|
22 | 22 | #include "xfs_inode.h"
|
23 | 23 | #include "xfs_dir2.h"
|
24 | 24 | #include "xfs_quota.h"
|
| 25 | +#include "xfs_alloc.h" |
| 26 | +#include "xfs_ag.h" |
| 27 | +#include "xfs_sb.h" |
25 | 28 |
|
26 | 29 | /*
|
27 | 30 | * This is the number of entries in the l_buf_cancel_table used during
|
@@ -684,6 +687,49 @@ xlog_recover_do_inode_buffer(
|
684 | 687 | return 0;
|
685 | 688 | }
|
686 | 689 |
|
| 690 | +/* |
| 691 | + * Update the in-memory superblock and perag structures from the primary SB |
| 692 | + * buffer. |
| 693 | + * |
| 694 | + * This is required because transactions running after growfs may require the |
| 695 | + * updated values to be set in a previous fully commit transaction. |
| 696 | + */ |
| 697 | +static int |
| 698 | +xlog_recover_do_primary_sb_buffer( |
| 699 | + struct xfs_mount *mp, |
| 700 | + struct xlog_recover_item *item, |
| 701 | + struct xfs_buf *bp, |
| 702 | + struct xfs_buf_log_format *buf_f, |
| 703 | + xfs_lsn_t current_lsn) |
| 704 | +{ |
| 705 | + struct xfs_dsb *dsb = bp->b_addr; |
| 706 | + xfs_agnumber_t orig_agcount = mp->m_sb.sb_agcount; |
| 707 | + int error; |
| 708 | + |
| 709 | + xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn); |
| 710 | + |
| 711 | + /* |
| 712 | + * Update the in-core super block from the freshly recovered on-disk one. |
| 713 | + */ |
| 714 | + xfs_sb_from_disk(&mp->m_sb, dsb); |
| 715 | + |
| 716 | + /* |
| 717 | + * Initialize the new perags, and also update various block and inode |
| 718 | + * allocator setting based off the number of AGs or total blocks. |
| 719 | + * Because of the latter this also needs to happen if the agcount did |
| 720 | + * not change. |
| 721 | + */ |
| 722 | + error = xfs_initialize_perag(mp, orig_agcount, |
| 723 | + mp->m_sb.sb_agcount, mp->m_sb.sb_dblocks, |
| 724 | + &mp->m_maxagi); |
| 725 | + if (error) { |
| 726 | + xfs_warn(mp, "Failed recovery per-ag init: %d", error); |
| 727 | + return error; |
| 728 | + } |
| 729 | + mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); |
| 730 | + return 0; |
| 731 | +} |
| 732 | + |
687 | 733 | /*
|
688 | 734 | * V5 filesystems know the age of the buffer on disk being recovered. We can
|
689 | 735 | * have newer objects on disk than we are replaying, and so for these cases we
|
@@ -967,6 +1013,12 @@ xlog_recover_buf_commit_pass2(
|
967 | 1013 | dirty = xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
|
968 | 1014 | if (!dirty)
|
969 | 1015 | goto out_release;
|
| 1016 | + } else if ((xfs_blft_from_flags(buf_f) & XFS_BLFT_SB_BUF) && |
| 1017 | + xfs_buf_daddr(bp) == 0) { |
| 1018 | + error = xlog_recover_do_primary_sb_buffer(mp, item, bp, buf_f, |
| 1019 | + current_lsn); |
| 1020 | + if (error) |
| 1021 | + goto out_release; |
970 | 1022 | } else {
|
971 | 1023 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn);
|
972 | 1024 | }
|
|
0 commit comments