linux/fs
Lukas Czerner 91dd8c1144 ext4: prevent race while walking extent tree for fiemap
Currently ext4_ext_walk_space() only takes i_data_sem for read when
searching for the extent at given block with ext4_ext_find_extent().
Then it drops the lock and the extent tree can be changed at will.
However later on we're searching for the 'next' extent, but the extent
tree might already have changed, so the information might not be
accurate.

In fact we can hit BUG_ON(end <= start) if the extent got inserted into
the tree after the one we found and before the block we were searching
for. This has been reproduced by running xfstests 225 in loop on s390x
architecture, but theoretically we could hit this on any other
architecture as well, but probably not as often.

Moreover the extent currently in delayed allocation might be allocated
after we search the extent tree and before we search extent status tree
delayed buffers resulting in those delayed buffers being completely
missed, even though completely written and allocated.

We fix all those problems in several steps:

 1. remove unnecessary callback indirection
 2. rename functions
        ext4_ext_walk_space -> ext4_fill_fiemap_extents
        ext4_ext_fiemap_cb -> ext4_find_delayed_extent
 3. move fiemap_fill_next_extent() into ext4_fill_fiemap_extents()
 4. hold the i_data_sem for:
        ext4_ext_find_extent()
        ext4_ext_next_allocated_block()
        ext4_find_delayed_extent()
 5. call fiemap_fill_next_extent after releasing the i_data_sem
 6. move path reinitialization into the critical section.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
2012-11-28 12:32:26 -05:00
..
9p The following changes since commit 4cbe5a555f: 2012-10-12 09:59:23 +09:00
adfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
affs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
afs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
autofs4 autofs4 - fix reset pending flag on mount fail 2012-10-11 10:21:16 +09:00
befs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
bfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
btrfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2012-10-26 09:34:04 -07:00
cachefiles fs: cachefiles: add support for large files in filesystem caching 2012-07-30 17:25:21 -07:00
ceph tmpfs,ceph,gfs2,isofs,reiserfs,xfs: fix fh_len checking 2012-10-09 23:33:55 -04:00
cifs Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux 2012-10-14 13:39:34 -07:00
coda fs: push rcu_barrier() from deactivate_locked_super() to filesystems 2012-10-02 21:35:55 -04:00
configfs userns: Convert configfs to use kuid and kgid where appropriate 2012-09-18 01:01:37 -07:00
cramfs userns: Convert cramfs to use kuid/kgid where appropriate 2012-09-21 03:13:08 -07:00
debugfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2012-10-02 11:11:09 -07:00
devpts
dlm Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-10-02 13:38:27 -07:00
ecryptfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
efs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
exofs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-12 10:52:03 +09:00
exportfs
ext2 ext2: fix return values on parse_options() failure 2012-10-09 23:23:53 +02:00
ext3 Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs 2012-10-16 18:12:38 -07:00
ext4 ext4: prevent race while walking extent tree for fiemap 2012-11-28 12:32:26 -05:00
fat fat: drop lock/unlock super 2012-10-09 23:33:38 -04:00
freevxfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
fscache
fuse mm: kill vma flag VM_CAN_NONLINEAR 2012-10-09 16:22:17 +09:00
gfs2 tmpfs,ceph,gfs2,isofs,reiserfs,xfs: fix fh_len checking 2012-10-09 23:33:55 -04:00
hfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
hfsplus Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
hostfs Merge branch 'for-linus-37rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml 2012-10-10 11:15:20 +09:00
hpfs hpfs: drop lock/unlock super 2012-10-09 23:33:38 -04:00
hppfs hppfs: fix the return value of get_inode() 2012-10-09 22:34:52 +02:00
hugetlbfs mm: replace vma prio_tree with an interval tree 2012-10-09 16:22:39 +09:00
isofs tmpfs,ceph,gfs2,isofs,reiserfs,xfs: fix fh_len checking 2012-10-09 23:33:55 -04:00
jbd jbd: Fix assertion failure in commit code due to lacking transaction credits 2012-09-12 15:52:03 +02:00
jbd2 ext4: remove ext4_handle_release_buffer() 2012-11-08 11:22:46 -05:00
jffs2 UAPI Disintegration 2012-10-09 2012-10-09 15:04:25 +01:00
jfs jfs: Fix FITRIM argument handling 2012-10-17 09:18:38 -05:00
lockd LOCKD: Clear ln->nsm_clnt only when ln->nsm_users is zero 2012-10-24 10:46:22 -04:00
logfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
minix Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
ncpfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
nfs NFSv4: Fix the return value for nfs_callback_start_svc 2012-10-16 13:14:42 -04:00
nfs_common
nfsd UAPI Disintegration 2012-10-09 2012-10-09 18:35:22 -04:00
nilfs2 mm: kill vma flag VM_CAN_NONLINEAR 2012-10-09 16:22:17 +09:00
nls
notify switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
ntfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
ocfs2 mm: kill vma flag VM_CAN_NONLINEAR 2012-10-09 16:22:17 +09:00
omfs omfs: convert to use beXX_add_cpu() 2012-10-06 03:05:31 +09:00
openpromfs fs: push rcu_barrier() from deactivate_locked_super() to filesystems 2012-10-02 21:35:55 -04:00
proc Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2012-10-24 04:07:02 +03:00
pstore pstore: Avoid recursive spinlocks in the oops_in_progress case 2012-09-20 17:04:50 -07:00
qnx4 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
qnx6 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
quota Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs 2012-10-16 18:12:38 -07:00
ramfs
reiserfs tmpfs,ceph,gfs2,isofs,reiserfs,xfs: fix fh_len checking 2012-10-09 23:33:55 -04:00
romfs fs: push rcu_barrier() from deactivate_locked_super() to filesystems 2012-10-02 21:35:55 -04:00
squashfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
sysfs sysfs: sysfs_pathname/sysfs_add_one: Use strlcat() instead of strcat() 2012-10-24 15:57:14 -07:00
sysv sysv: drop lock/unlock super 2012-10-09 23:33:39 -04:00
ubifs mm: kill vma flag VM_CAN_NONLINEAR 2012-10-09 16:22:17 +09:00
udf Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs 2012-10-04 09:14:01 -07:00
ufs ufs: drop lock/unlock super 2012-10-09 23:33:39 -04:00
xfs tmpfs,ceph,gfs2,isofs,reiserfs,xfs: fix fh_len checking 2012-10-09 23:33:55 -04:00
aio.c
anon_inodes.c
attr.c ima: add inode_post_setattr call 2012-09-07 14:57:46 -04:00
bad_inode.c
binfmt_aout.c coredump: pass siginfo_t* to do_coredump() and below, not merely signr 2012-10-06 03:05:16 +09:00
binfmt_elf_fdpic.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal 2012-10-10 12:02:25 +09:00
binfmt_elf.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal 2012-10-10 12:02:25 +09:00
binfmt_em86.c
binfmt_flat.c coredump: pass siginfo_t* to do_coredump() and below, not merely signr 2012-10-06 03:05:16 +09:00
binfmt_misc.c
binfmt_script.c
binfmt_som.c
bio-integrity.c block: Ues bi_pool for bio_integrity_alloc() 2012-09-09 10:35:38 +02:00
bio.c block: makes bio_split support bio without data 2012-09-28 10:38:48 +02:00
block_dev.c Lock splice_read and splice_write functions 2012-10-28 10:59:37 -07:00
buffer.c The big new feature added this time is supporting online resizing 2012-10-08 06:36:39 +09:00
char_dev.c char_dev: pin parent kobject 2012-10-22 08:50:37 +03:00
compat_binfmt_elf.c coredump: extend core dump note section to contain file names of mapped files 2012-10-06 03:05:17 +09:00
compat_ioctl.c fs/compat_ioctl.c: VIDEO_SET_SPU_PALETTE missing error check 2012-10-25 14:37:53 -07:00
compat.c vfs: define struct filename and have getname() return it 2012-10-12 20:14:55 -04:00
coredump.c fix a leak in replace_fd() users 2012-10-16 13:36:50 -04:00
coredump.h coredump: update coredump-related headers 2012-10-06 03:05:15 +09:00
dcache.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
dcookies.c
direct-io.c block: move down direct IO plugging 2012-08-09 15:23:09 +02:00
drop_caches.c
eventfd.c
eventpoll.c epoll: support for disabling items, and a self-test app 2012-10-06 03:05:00 +09:00
exec.c freezer: exec should clear PF_NOFREEZE along with PF_KTHREAD 2012-10-25 22:28:12 +02:00
fcntl.c Fix F_DUPFD_CLOEXEC breakage 2012-10-09 15:52:31 +09:00
fhandle.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
fifo.c
file_table.c lglock: add DEFINE_STATIC_LGLOCK() 2012-10-10 01:15:44 -04:00
file.c dup3: Return an error when oldfd == newfd. 2012-10-09 23:33:38 -04:00
filesystems.c vfs: define struct filename and have getname() return it 2012-10-12 20:14:55 -04:00
fs_struct.c
fs-writeback.c Merge branch 'writeback-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/linux 2012-10-12 10:46:03 +09:00
generic_acl.c userns: Pass a userns parameter into posix_acl_to_xattr and posix_acl_from_xattr 2012-09-18 01:01:35 -07:00
inode.c mm: replace vma prio_tree with an interval tree 2012-10-09 16:22:39 +09:00
internal.h vfs: make path_openat take a struct filename pointer 2012-10-12 20:15:09 -04:00
ioctl.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
ioprio.c
Kconfig
Kconfig.binfmt coredump: make core dump functionality optional 2012-10-06 03:05:15 +09:00
libfs.c vfs: fix kerneldoc for generic_fh_to_parent() 2012-09-05 10:59:30 +02:00
locks.c UAPI Disintegration 2012-10-09 2012-10-09 18:35:22 -04:00
Makefile coredump: make core dump functionality optional 2012-10-06 03:05:15 +09:00
mbcache.c
mount.h
mpage.c
namei.c VFS: don't do protected {sym,hard}links by default 2012-10-26 10:05:07 -07:00
namespace.c vfs: define struct filename and have getname() return it 2012-10-12 20:14:55 -04:00
no-block.c
open.c vfs: make path_openat take a struct filename pointer 2012-10-12 20:15:09 -04:00
pipe.c pipe(2) - race-free error recovery 2012-09-26 21:08:52 -04:00
pnode.c
pnode.h
posix_acl.c userns: Convert vfs posix_acl support to use kuids and kgids 2012-09-18 01:01:35 -07:00
proc_namespace.c
read_write.c compat: fs: Generic compat_sys_sendfile implementation 2012-10-02 21:35:55 -04:00
read_write.h compat: fs: Generic compat_sys_sendfile implementation 2012-10-02 21:35:55 -04:00
readdir.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
select.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
seq_file.c userns: Make seq_file's user namespace accessible 2012-08-14 21:47:55 -07:00
signalfd.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
splice.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
stack.c
stat.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-10-02 20:25:04 -07:00
statfs.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
super.c vfs: drop lock/unlock super 2012-10-09 23:33:39 -04:00
sync.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
timerfd.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
utimes.c switch simple cases of fget_light to fdget 2012-09-26 22:20:08 -04:00
xattr_acl.c userns: Fix posix_acl_file_xattr_userns gid conversion 2012-10-12 13:16:48 -07:00
xattr.c fs, xattr: fix bug when removing a name not in xattr list 2012-10-18 12:35:58 -07:00