aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-05-27 02:38:24 -0400
committerBen Myers <bpm@sgi.com>2013-05-30 18:20:08 -0400
commit7c9950fd2ac97431230544142d5e652e1b948372 (patch)
treed7862206d6bc85506490ffa80d3e6ac5836a6e09 /fs/xfs
parente7927e879d12d27aa06b9bbed57cc32dcd7d17fd (diff)
xfs: disable swap extents ioctl on CRC enabled filesystems
Currently, swapping extents from one inode to another is a simple act of switching data and attribute forks from one inode to another. This, unfortunately in no longer so simple with CRC enabled filesystems as there is owner information embedded into the BMBT blocks that are swapped between inodes. Hence swapping the forks between inodes results in the inodes having mapping blocks that point to the wrong owner and hence are considered corrupt. To fix this we need an extent tree block or record based swap algorithm so that the BMBT block owner information can be updated atomically in the swap transaction. This is a significant piece of new work, so for the moment simply don't allow swap extent operations to succeed on CRC enabled filesystems. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Ben Myers <bpm@sgi.com> (cherry picked from commit 02f75405a75eadfb072609f6bf839e027de6a29a)
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_dfrag.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index f852b082a084..c407e1ccff43 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -219,6 +219,14 @@ xfs_swap_extents(
219 int taforkblks = 0; 219 int taforkblks = 0;
220 __uint64_t tmp; 220 __uint64_t tmp;
221 221
222 /*
223 * We have no way of updating owner information in the BMBT blocks for
224 * each inode on CRC enabled filesystems, so to avoid corrupting the
225 * this metadata we simply don't allow extent swaps to occur.
226 */
227 if (xfs_sb_version_hascrc(&mp->m_sb))
228 return XFS_ERROR(EINVAL);
229
222 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); 230 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
223 if (!tempifp) { 231 if (!tempifp) {
224 error = XFS_ERROR(ENOMEM); 232 error = XFS_ERROR(ENOMEM);