diff options
author | Dave Chinner <dchinner@redhat.com> | 2017-12-06 17:14:27 -0600 |
---|---|---|
committer | Eric Sandeen <sandeen@redhat.com> | 2017-12-06 17:14:27 -0600 |
commit | e2847e5c0a0037f5bad1fb4edcb3f639fff44cae (patch) | |
tree | c9d229ee53e06284856623dbfd1e4a4474c9bf29 | |
parent | 0ff1b0ed515a0c70d2a445ca9f79edecfdd7829e (diff) | |
download | xfsprogs-dev-e2847e5c0a0037f5bad1fb4edcb3f639fff44cae.tar.gz |
mkfs: factor secondary superblock updates
Signed-Off-By: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r-- | mkfs/xfs_mkfs.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 4ba11b6c20..1b23ada2b5 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2489,6 +2489,39 @@ initialise_ag_freespace( libxfs_trans_commit(tp); } +/* + * rewrite several secondary superblocks with the root inode number filled out. + * This can help repair recovery from a trashed primary superblock without + * losing the root inode. + */ +static void +rewrite_secondary_superblocks( + struct xfs_mount *mp) +{ + struct xfs_buf *buf; + + /* rewrite the last superblock */ + buf = libxfs_readbuf(mp->m_dev, + XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount - 1, + XFS_SB_DADDR), + XFS_FSS_TO_BB(mp, 1), + LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops); + XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino); + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); + + /* and one in the middle for luck if there's enough AGs for that */ + if (mp->m_sb.sb_agcount <= 2) + return; + + buf = libxfs_readbuf(mp->m_dev, + XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount - 1) / 2, + XFS_SB_DADDR), + XFS_FSS_TO_BB(mp, 1), + LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops); + XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino); + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); +} + int main( int argc, @@ -3716,34 +3749,10 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), } /* - * Write out multiple secondary superblocks with rootinode field set + * Re-write multiple secondary superblocks with rootinode field set */ - if (mp->m_sb.sb_agcount > 1) { - /* - * the last superblock - */ - buf = libxfs_readbuf(mp->m_dev, - XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount-1, - XFS_SB_DADDR), - XFS_FSS_TO_BB(mp, 1), - LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops); - XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64( - mp->m_sb.sb_rootino); - libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); - /* - * and one in the middle for luck - */ - if (mp->m_sb.sb_agcount > 2) { - buf = libxfs_readbuf(mp->m_dev, - XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount-1)/2, - XFS_SB_DADDR), - XFS_FSS_TO_BB(mp, 1), - LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops); - XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64( - mp->m_sb.sb_rootino); - libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); - } - } + if (mp->m_sb.sb_agcount > 1) + rewrite_secondary_superblocks(mp); /* * Dump all inodes and buffers before marking us all done. |