diff options
author | Dave Chinner <dchinner@redhat.com> | 2015-08-18 20:31:54 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2015-08-18 20:31:54 -0400 |
commit | fcfbe2c4ef4243cc11a1cd64ee1b4907b6afea06 (patch) | |
tree | 8f96db333c8177d7c933725e83dcd71f9e7f3012 /fs/xfs/xfs_log_recover.c | |
parent | ac383de20d468a75e7023caf06dcf6606cd85220 (diff) |
xfs: log recovery needs to validate against sb_meta_uuid
Now that sb_uuid can be changed by the user, we cannot use this to
validate the metadata blocks being recovered belong to this
filesystem. We must check against the sb_meta_uuid as that will
remain unchanged.
There is a complication in this code - the superblock itself. We can
not check the sb_meta_uuid unconditionally, as that may not be set
on disk. Hence we must verify the superblock sb_uuid matches between
the log record and the in-core superblock.
Found by inspection after the previous two problems were found.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 01dd228ca05e..86c3de477a9d 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1890,15 +1890,25 @@ xlog_recover_get_buf_lsn( | |||
1890 | uuid = &((struct xfs_attr3_rmt_hdr *)blk)->rm_uuid; | 1890 | uuid = &((struct xfs_attr3_rmt_hdr *)blk)->rm_uuid; |
1891 | break; | 1891 | break; |
1892 | case XFS_SB_MAGIC: | 1892 | case XFS_SB_MAGIC: |
1893 | /* | ||
1894 | * superblock uuids are magic. We may or may not have a | ||
1895 | * sb_meta_uuid on disk, but it will be set in the in-core | ||
1896 | * superblock. We set the uuid pointer for verification | ||
1897 | * according to the superblock feature mask to ensure we check | ||
1898 | * the relevant UUID in the superblock. | ||
1899 | */ | ||
1893 | lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn); | 1900 | lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn); |
1894 | uuid = &((struct xfs_dsb *)blk)->sb_uuid; | 1901 | if (xfs_sb_version_hasmetauuid(&mp->m_sb)) |
1902 | uuid = &((struct xfs_dsb *)blk)->sb_meta_uuid; | ||
1903 | else | ||
1904 | uuid = &((struct xfs_dsb *)blk)->sb_uuid; | ||
1895 | break; | 1905 | break; |
1896 | default: | 1906 | default: |
1897 | break; | 1907 | break; |
1898 | } | 1908 | } |
1899 | 1909 | ||
1900 | if (lsn != (xfs_lsn_t)-1) { | 1910 | if (lsn != (xfs_lsn_t)-1) { |
1901 | if (!uuid_equal(&mp->m_sb.sb_uuid, uuid)) | 1911 | if (!uuid_equal(&mp->m_sb.sb_meta_uuid, uuid)) |
1902 | goto recover_immediately; | 1912 | goto recover_immediately; |
1903 | return lsn; | 1913 | return lsn; |
1904 | } | 1914 | } |