diff options
author | Eric Sandeen <sandeen@redhat.com> | 2012-03-27 16:40:26 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2013-06-20 14:26:09 -0400 |
commit | 427d9fe233ccec3a293be4bcf07f9bac12463a99 (patch) | |
tree | fa4fe5c810a10785d8a11f8f80c6e27c7e20d375 /fs/xfs/xfs_dfrag.c | |
parent | 39a45d8463d98ea57347b871641136be64b216a9 (diff) |
xfs: check on-disk (not incore) btree root size in dfrag.c
xfs_swap_extents_check_format() contains checks to make sure that
original and the temporary files during defrag are compatible;
Gabriel VLASIU ran into a case where xfs_fsr returned EINVAL
because the tests found the btree root to be of size 120,
while the fork offset was only 104; IOW, they overlapped.
However, this is just due to an error in the
xfs_swap_extents_check_format() tests, because it is checking
the in-memory btree root size against the on-disk fork offset.
We should be checking the on-disk sizes in both cases.
This patch adds a new macro to calculate this size, and uses
it in the tests.
With this change, the filesystem image provided by Gabriel
allows for proper file degragmentation.
Reported-by: Gabriel VLASIU <gabriel@vlasiu.net>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_dfrag.c')
-rw-r--r-- | fs/xfs/xfs_dfrag.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index c407e1ccff43..e36445ceaf80 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -24,6 +24,9 @@ | |||
24 | #include "xfs_ag.h" | 24 | #include "xfs_ag.h" |
25 | #include "xfs_mount.h" | 25 | #include "xfs_mount.h" |
26 | #include "xfs_bmap_btree.h" | 26 | #include "xfs_bmap_btree.h" |
27 | #include "xfs_alloc_btree.h" | ||
28 | #include "xfs_ialloc_btree.h" | ||
29 | #include "xfs_btree.h" | ||
27 | #include "xfs_dinode.h" | 30 | #include "xfs_dinode.h" |
28 | #include "xfs_inode.h" | 31 | #include "xfs_inode.h" |
29 | #include "xfs_inode_item.h" | 32 | #include "xfs_inode_item.h" |
@@ -182,7 +185,7 @@ xfs_swap_extents_check_format( | |||
182 | */ | 185 | */ |
183 | if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) { | 186 | if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) { |
184 | if (XFS_IFORK_BOFF(ip) && | 187 | if (XFS_IFORK_BOFF(ip) && |
185 | tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip)) | 188 | XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) |
186 | return EINVAL; | 189 | return EINVAL; |
187 | if (XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= | 190 | if (XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= |
188 | XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) | 191 | XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) |
@@ -192,9 +195,8 @@ xfs_swap_extents_check_format( | |||
192 | /* Reciprocal target->temp btree format checks */ | 195 | /* Reciprocal target->temp btree format checks */ |
193 | if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) { | 196 | if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) { |
194 | if (XFS_IFORK_BOFF(tip) && | 197 | if (XFS_IFORK_BOFF(tip) && |
195 | ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip)) | 198 | XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) |
196 | return EINVAL; | 199 | return EINVAL; |
197 | |||
198 | if (XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= | 200 | if (XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= |
199 | XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) | 201 | XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) |
200 | return EINVAL; | 202 | return EINVAL; |