linux/fs/ext4
Yongqiang Yang 6d9c85eb70 ext4: make FIEMAP and delayed allocation play well together
Fix the FIEMAP ioctl so that it returns all of the page ranges which
are still subject to delayed allocation.  We were missing some cases
if the file was sparse.

Reported by Chris Mason <chris.mason@oracle.com>:
>We've had reports on btrfs that cp is giving us files full of zeros
>instead of actually copying them.  It was tracked down to a bug with
>the btrfs fiemap implementation where it was returning holes for
>delalloc ranges.
>
>Newer versions of cp are trusting fiemap to tell it where the holes
>are, which does seem like a pretty neat trick.
>
>I decided to give xfs and ext4 a shot with a few tests cases too, xfs
>passed with all the ones btrfs was getting wrong, and ext4 got the basic
>delalloc case right.
>$ mkfs.ext4 /dev/xxx
>$ mount /dev/xxx /mnt
>$ dd if=/dev/zero of=/mnt/foo bs=1M count=1
>$ fiemap-test foo
>ext:   0 logical: [       0..     255] phys:        0..     255
>flags: 0x007 tot: 256
>
>Horray!  But once we throw a hole in, things go bad:
>$ mkfs.ext4 /dev/xxx
>$ mount /dev/xxx /mnt
>$ dd if=/dev/zero of=/mnt/foo bs=1M count=1 seek=1
>$ fiemap-test foo
>< no output >
>
>We've got a delalloc extent after the hole and ext4 fiemap didn't find
>it.  If I run sync to kick the delalloc out:
>$sync
>$ fiemap-test foo
>ext:   0 logical: [     256..     511] phys:    34048..   34303
>flags: 0x001 tot: 256
>
>fiemap-test is sitting in my /usr/local/bin, and I have no idea how it
>got there.  It's full of pretty comments so I know it isn't mine, but
>you can grab it here:
>
>http://oss.oracle.com/~mason/fiemap-test.c
>
>xfsqa has a fiemap program too.

After Fix, test results are as follows:
ext:   0 logical: [     256..     511] phys:        0..     255
flags: 0x007 tot: 256
ext:   0 logical: [     256..     511] phys:    33280..   33535
flags: 0x001 tot: 256

$ mkfs.ext4 /dev/xxx
$ mount /dev/xxx /mnt
$ dd if=/dev/zero of=/mnt/foo bs=1M count=1 seek=1
$ sync
$ dd if=/dev/zero of=/mnt/foo bs=1M count=1 seek=3
$ dd if=/dev/zero of=/mnt/foo bs=1M count=1 seek=5
$ fiemap-test foo
ext:   0 logical: [     256..     511] phys:    33280..   33535
flags: 0x000 tot: 256
ext:   1 logical: [     768..    1023] phys:        0..     255
flags: 0x006 tot: 256
ext:   2 logical: [    1280..    1535] phys:        0..     255
flags: 0x007 tot: 256

Tested-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
2011-02-27 17:25:47 -05:00
..
acl.c ext2,3,4: provide simple rcu-walk ACL implementation 2011-01-07 17:50:30 +11:00
acl.h fs: provide rcu-walk aware permission i_ops 2011-01-07 17:50:29 +11:00
balloc.c ext4: replace i_delalloc_reserved_flag with EXT4_STATE_DELALLOC_RESERVED 2011-01-10 12:12:36 -05:00
bitmap.c ext4: Change unsigned long to unsigned int 2008-11-05 00:14:04 -05:00
block_validity.c ext4: rename {exit,init}_ext4_*() to ext4_{exit,init}_*() 2010-10-27 21:30:14 -04:00
dir.c ext4: Use ext4_error_file() to print the pathname to the corrupted inode 2011-01-10 12:10:55 -05:00
ext4_extents.h ext4: drop ec_type from the ext4_ext_cache structure 2011-01-10 12:13:26 -05:00
ext4_jbd2.c ext4: Pass line numbers to ext4_error() and friends 2010-07-27 11:56:40 -04:00
ext4_jbd2.h ext4: dynamically allocate the jbd2_inode in ext4_inode_info as necessary 2011-01-10 12:29:43 -05:00
ext4.h ext4: serialize unaligned asynchronous DIO 2011-02-12 08:17:34 -05:00
extents.c ext4: make FIEMAP and delayed allocation play well together 2011-02-27 17:25:47 -05:00
file.c ext4: serialize unaligned asynchronous DIO 2011-02-12 08:17:34 -05:00
fsync.c ext4: flush the i_completed_io_list during ext4_truncate 2011-01-10 12:47:05 -05:00
hash.c ext4: Add support for non-native signed/unsigned htree hash algorithms 2008-10-28 13:21:44 -04:00
ialloc.c ext4: Fix sparse warning: Using plain integer as NULL pointer 2011-02-21 21:01:42 -05:00
inode.c ext4: move setup of the mpd structure to write_cache_pages_da() 2011-02-26 14:09:20 -05:00
ioctl.c ext4: Adjust minlen with discard_granularity in the FITRIM ioctl 2011-02-23 17:49:51 -05:00
Kconfig ext4: Don't ask about supporting ext2/3 in ext4 if ext4 is not configured 2009-12-21 10:54:09 -05:00
Makefile ext4: use bio layer instead of buffer layer in mpage_da_submit_io 2010-10-27 21:30:10 -04:00
mballoc.c ext4: suppress verbose debugging information if malloc-debug is off 2011-02-27 17:23:47 -05:00
mballoc.h ext4: clarify description of ac_g_ex in struct ext4_allocation_context 2011-02-24 14:10:00 -05:00
migrate.c ext4: Fix sparse warning: Using plain integer as NULL pointer 2011-02-21 21:01:42 -05:00
move_extent.c ext4: rename {ext,idx}_pblock and inline small extent functions 2010-10-27 21:30:14 -04:00
namei.c ext4: add error checking to calls to ext4_handle_dirty_metadata() 2011-01-10 12:46:59 -05:00
page-io.c ext4: don't leave PageWriteback set after memory failure 2011-02-27 16:43:24 -05:00
resize.c ext4: fix compile warnings with EXT4FS_DEBUG enabled 2011-02-21 20:39:58 -05:00
super.c ext4: enable mblk_io_submit by default 2011-02-26 13:53:09 -05:00
symlink.c ext4: symlink must be handled via filesystem specific operation 2010-05-16 02:00:00 -04:00
xattr_security.c ext4: constify xattr_handler 2010-05-21 18:31:19 -04:00
xattr_trusted.c ext4: constify xattr_handler 2010-05-21 18:31:19 -04:00
xattr_user.c ext4: constify xattr_handler 2010-05-21 18:31:19 -04:00
xattr.c ext4: Fix sparse warning: Using plain integer as NULL pointer 2011-02-21 21:01:42 -05:00
xattr.h ext4: fix compile with CONFIG_EXT4_FS_XATTR disabled 2010-10-28 09:29:17 -07:00