]> git.baikalelectronics.ru Git - kernel.git/commit
Btrfs: fix race between fsync and lockless direct IO writes
authorFilipe Manana <fdmanana@suse.com>
Thu, 21 Jan 2016 10:17:54 +0000 (10:17 +0000)
committerChris Mason <clm@fb.com>
Tue, 26 Jan 2016 00:50:26 +0000 (16:50 -0800)
commit8c9ac58637813b3aee1c27e95e8d8351527cb47c
tree52b0a9db694a7810bed41f04fa5be2b843352484
parent4936db3b64bedda841c9cbbd37f6d27d26529b5c
Btrfs: fix race between fsync and lockless direct IO writes

An fsync, using the fast path, can race with a concurrent lockless direct
IO write and end up logging a file extent item that points to an extent
that wasn't written to yet. This is because the fast fsync path collects
ordered extents into a local list and then collects all the new extent
maps to log file extent items based on them, while the direct IO write
path creates the new extent map before it creates the corresponding
ordered extent (and submitting the respective bio(s)).

So fix this by making the direct IO write path create ordered extents
before the extent maps and make the fast fsync path collect any new
ordered extents after it collects the extent maps.
Note that making the fsync handler call inode_dio_wait() (after acquiring
the inode's i_mutex) would not work and lead to a deadlock when doing
AIO, as through AIO we end up in a path where the fsync handler is called
(through dio_aio_complete_work() -> dio_complete() -> vfs_fsync_range())
before the inode's dio counter is decremented (inode_dio_wait() waits
for this counter to have a value of zero).

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/inode.c
fs/btrfs/tree-log.c