diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-10 10:27:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-10 10:27:48 -0700 |
commit | 6618a24ab2313309e9df1cc06cc1f6786a6b6a9c (patch) | |
tree | 2a335d8110a87e047676e5fd41f24f547a3f7d05 /fs | |
parent | 1d07b6cb96bc17f844a0218ec783f017cc2d29ee (diff) | |
parent | ff0fa73247e442518936baa43c3f037b17f10fa7 (diff) |
Merge branch 'nowait-aio-btrfs-fixup' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fix from David Sterba:
"This fixes a user-visible bug introduced by the nowait-aio patches
merged in this cycle"
* 'nowait-aio-btrfs-fixup' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: nowait aio: Correct assignment of pos
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/file.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a85d7903fbdd..9e75d8a39aac 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1881,16 +1881,25 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, ssize_t num_written = 0; bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); ssize_t err; - loff_t pos = iocb->ki_pos; + loff_t pos; size_t count = iov_iter_count(from); loff_t oldsize; int clean_page = 0; - if ((iocb->ki_flags & IOCB_NOWAIT) && - (iocb->ki_flags & IOCB_DIRECT)) { - /* Don't sleep on inode rwsem */ - if (!inode_trylock(inode)) + if (!inode_trylock(inode)) { + if (iocb->ki_flags & IOCB_NOWAIT) return -EAGAIN; + inode_lock(inode); + } + + err = generic_write_checks(iocb, from); + if (err <= 0) { + inode_unlock(inode); + return err; + } + + pos = iocb->ki_pos; + if (iocb->ki_flags & IOCB_NOWAIT) { /* * We will allocate space in case nodatacow is not set, * so bail @@ -1901,13 +1910,6 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, inode_unlock(inode); return -EAGAIN; } - } else - inode_lock(inode); - - err = generic_write_checks(iocb, from); - if (err <= 0) { - inode_unlock(inode); - return err; } current->backing_dev_info = inode_to_bdi(inode); |