diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fuse/file.c | 11 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 8 | ||||
-rw-r--r-- | fs/fuse/inode.c | 8 |
3 files changed, 24 insertions, 3 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 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index b788becada76..eb8c6135fbbf 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -135,6 +135,9 @@ struct fuse_file { | |||
135 | 135 | ||
136 | /** Wait queue head for poll */ | 136 | /** Wait queue head for poll */ |
137 | wait_queue_head_t poll_wait; | 137 | wait_queue_head_t poll_wait; |
138 | |||
139 | /** Has flock been performed on this file? */ | ||
140 | bool flock:1; | ||
138 | }; | 141 | }; |
139 | 142 | ||
140 | /** One input argument of a request */ | 143 | /** One input argument of a request */ |
@@ -448,7 +451,7 @@ struct fuse_conn { | |||
448 | /** Is removexattr not implemented by fs? */ | 451 | /** Is removexattr not implemented by fs? */ |
449 | unsigned no_removexattr:1; | 452 | unsigned no_removexattr:1; |
450 | 453 | ||
451 | /** Are file locking primitives not implemented by fs? */ | 454 | /** Are posix file locking primitives not implemented by fs? */ |
452 | unsigned no_lock:1; | 455 | unsigned no_lock:1; |
453 | 456 | ||
454 | /** Is access not implemented by fs? */ | 457 | /** Is access not implemented by fs? */ |
@@ -472,6 +475,9 @@ struct fuse_conn { | |||
472 | /** Don't apply umask to creation modes */ | 475 | /** Don't apply umask to creation modes */ |
473 | unsigned dont_mask:1; | 476 | unsigned dont_mask:1; |
474 | 477 | ||
478 | /** Are BSD file locking primitives not implemented by fs? */ | ||
479 | unsigned no_flock:1; | ||
480 | |||
475 | /** The number of requests waiting for completion */ | 481 | /** The number of requests waiting for completion */ |
476 | atomic_t num_waiting; | 482 | atomic_t num_waiting; |
477 | 483 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 5354906e797c..f541d639844b 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -809,6 +809,10 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
809 | fc->async_read = 1; | 809 | fc->async_read = 1; |
810 | if (!(arg->flags & FUSE_POSIX_LOCKS)) | 810 | if (!(arg->flags & FUSE_POSIX_LOCKS)) |
811 | fc->no_lock = 1; | 811 | fc->no_lock = 1; |
812 | if (arg->minor >= 17) { | ||
813 | if (!(arg->flags & FUSE_FLOCK_LOCKS)) | ||
814 | fc->no_flock = 1; | ||
815 | } | ||
812 | if (arg->flags & FUSE_ATOMIC_O_TRUNC) | 816 | if (arg->flags & FUSE_ATOMIC_O_TRUNC) |
813 | fc->atomic_o_trunc = 1; | 817 | fc->atomic_o_trunc = 1; |
814 | if (arg->minor >= 9) { | 818 | if (arg->minor >= 9) { |
@@ -823,6 +827,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
823 | } else { | 827 | } else { |
824 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; | 828 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; |
825 | fc->no_lock = 1; | 829 | fc->no_lock = 1; |
830 | fc->no_flock = 1; | ||
826 | } | 831 | } |
827 | 832 | ||
828 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); | 833 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); |
@@ -843,7 +848,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) | |||
843 | arg->minor = FUSE_KERNEL_MINOR_VERSION; | 848 | arg->minor = FUSE_KERNEL_MINOR_VERSION; |
844 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; | 849 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; |
845 | arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | | 850 | arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | |
846 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK; | 851 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | |
852 | FUSE_FLOCK_LOCKS; | ||
847 | req->in.h.opcode = FUSE_INIT; | 853 | req->in.h.opcode = FUSE_INIT; |
848 | req->in.numargs = 1; | 854 | req->in.numargs = 1; |
849 | req->in.args[0].size = sizeof(*arg); | 855 | req->in.args[0].size = sizeof(*arg); |