diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-25 09:06:04 -1000 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-06-25 09:06:04 -1000 |
commit | 5dbc746960b5cd62c558cd6663697afd41f59d39 (patch) | |
tree | 41486216b93c026c92743d64e16295528ac68c88 | |
parent | f97f7d2d27bf092b40babda9ded29cc85cf77eec (diff) | |
parent | 14c14414d157ea851119c96c61a17306a2b4a035 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse bugfix from Miklos Szeredi:
"This fixes a race between fallocate() and truncate()"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: hold i_mutex in fuse_file_fallocate()
-rw-r--r-- | fs/fuse/file.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e570081f9f76..35f281033142 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2470,13 +2470,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, .mode = mode }; int err; + bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || + (mode & FALLOC_FL_PUNCH_HOLE); if (fc->no_fallocate) return -EOPNOTSUPP; - if (mode & FALLOC_FL_PUNCH_HOLE) { + if (lock_inode) { mutex_lock(&inode->i_mutex); - fuse_set_nowrite(inode); + if (mode & FALLOC_FL_PUNCH_HOLE) + fuse_set_nowrite(inode); } req = fuse_get_req_nopages(fc); @@ -2511,8 +2514,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, fuse_invalidate_attr(inode); out: - if (mode & FALLOC_FL_PUNCH_HOLE) { - fuse_release_nowrite(inode); + if (lock_inode) { + if (mode & FALLOC_FL_PUNCH_HOLE) + fuse_release_nowrite(inode); mutex_unlock(&inode->i_mutex); } |