aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/file.c
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2011-08-08 10:08:08 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2011-08-08 10:08:08 -0400
commit37fb3a30b46237f23cfdf7ee09d49f9888dd13bf (patch)
treec36910e300ade812159d12218fdf122b3d2ef3de /fs/fuse/file.c
parenta2daff6803a384ce065e3681a2affea1da59c5f5 (diff)
fuse: fix flock
Commit a9ff4f87 "fuse: support BSD locking semantics" overlooked a number of issues with supporing flock locks over existing POSIX locking infrastructure: - it's not backward compatible, passing flock(2) calls to userspace unconditionally (if userspace sets FUSE_POSIX_LOCKS) - it doesn't cater for the fact that flock locks are automatically unlocked on file release - it doesn't take into account the fact that flock exclusive locks (write locks) don't need an fd opened for write. The last one invalidates the original premise of the patch that flock locks can be emulated with POSIX locks. This patch fixes the first two issues. The last one needs to be fixed in userspace if the filesystem assumed that a write lock will happen only on a file operned for write (as in the case of the current fuse library). Reported-by: Sebastian Pipping <webmaster@hartwork.org> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r--fs/fuse/file.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 82a66466a24c..e32784924355 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -245,6 +245,12 @@ void fuse_release_common(struct file *file, int opcode)
245 req = ff->reserved_req; 245 req = ff->reserved_req;
246 fuse_prepare_release(ff, file->f_flags, opcode); 246 fuse_prepare_release(ff, file->f_flags, opcode);
247 247
248 if (ff->flock) {
249 struct fuse_release_in *inarg = &req->misc.release.in;
250 inarg->release_flags |= FUSE_RELEASE_FLOCK_UNLOCK;
251 inarg->lock_owner = fuse_lock_owner_id(ff->fc,
252 (fl_owner_t) file);
253 }
248 /* Hold vfsmount and dentry until release is finished */ 254 /* Hold vfsmount and dentry until release is finished */
249 path_get(&file->f_path); 255 path_get(&file->f_path);
250 req->misc.release.path = file->f_path; 256 req->misc.release.path = file->f_path;
@@ -1547,11 +1553,14 @@ static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
1547 struct fuse_conn *fc = get_fuse_conn(inode); 1553 struct fuse_conn *fc = get_fuse_conn(inode);
1548 int err; 1554 int err;
1549 1555
1550 if (fc->no_lock) { 1556 if (fc->no_flock) {
1551 err = flock_lock_file_wait(file, fl); 1557 err = flock_lock_file_wait(file, fl);
1552 } else { 1558 } else {
1559 struct fuse_file *ff = file->private_data;
1560
1553 /* emulate flock with POSIX locks */ 1561 /* emulate flock with POSIX locks */
1554 fl->fl_owner = (fl_owner_t) file; 1562 fl->fl_owner = (fl_owner_t) file;
1563 ff->flock = true;
1555 err = fuse_setlk(file, fl, 1); 1564 err = fuse_setlk(file, fl, 1);
1556 } 1565 }
1557 1566