xfs: xfs_swap_extents needs to handle dynamic fork offsets
authorDave Chinner <david@fromorbit.com>
Thu, 11 Mar 2010 22:42:12 +0000 (09:42 +1100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 26 Apr 2010 14:41:16 +0000 (07:41 -0700)
commit059f754c44af50340f8921df60091254b0bfb1e6
tree14a508179775c5ebec891b7b91a70835bab639d1
parentbcb56a66459dafdc87b48d2e84cbd73eb4fbc385
xfs: xfs_swap_extents needs to handle dynamic fork offsets

commit e09f98606dcc156de1146c209d45a0d6d5f51c3f upstream

When swapping extents, we can corrupt inodes by swapping data forks
that are in incompatible formats.  This is caused by the two indoes
having different fork offsets due to the presence of an attribute
fork on an attr2 filesystem.  xfs_fsr tries to be smart about
setting the fork offset, but the trick it plays only works on attr1
(old fixed format attribute fork) filesystems.

Changing the way xfs_fsr sets up the attribute fork will prevent
this situation from ever occurring, so in the kernel code we can get
by with a preventative fix - check that the data fork in the
defragmented inode is in a format valid for the inode it is being
swapped into.  This will lead to files that will silently and
potentially repeatedly fail defragmentation, so issue a warning to
the log when this particular failure occurs to let us know that
xfs_fsr needs updating/fixing.

To help identify how to improve xfs_fsr to avoid this issue, add
trace points for the inodes being swapped so that we can determine
why the swap was rejected and to confirm that the code is making the
right decisions and modifications when swapping forks.

A further complication is even when the swap is allowed to proceed
when the fork offset is different between the two inodes then value
for the maximum number of extents the data fork can hold can be
wrong. Make sure these are also set correctly after the swap occurs.

Signed-off-by: Dave Chinner <david@fromorbit.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/xfs/xfs_dfrag.c