diff options
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/control.c | 15 | ||||
-rw-r--r-- | fs/fuse/cuse.c | 15 | ||||
-rw-r--r-- | fs/fuse/dev.c | 202 | ||||
-rw-r--r-- | fs/fuse/dir.c | 102 | ||||
-rw-r--r-- | fs/fuse/file.c | 196 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 34 | ||||
-rw-r--r-- | fs/fuse/inode.c | 73 |
7 files changed, 490 insertions, 147 deletions
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 3773fd63d2f9..85542a7daf40 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c | |||
@@ -179,23 +179,27 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file, | |||
179 | static const struct file_operations fuse_ctl_abort_ops = { | 179 | static const struct file_operations fuse_ctl_abort_ops = { |
180 | .open = nonseekable_open, | 180 | .open = nonseekable_open, |
181 | .write = fuse_conn_abort_write, | 181 | .write = fuse_conn_abort_write, |
182 | .llseek = no_llseek, | ||
182 | }; | 183 | }; |
183 | 184 | ||
184 | static const struct file_operations fuse_ctl_waiting_ops = { | 185 | static const struct file_operations fuse_ctl_waiting_ops = { |
185 | .open = nonseekable_open, | 186 | .open = nonseekable_open, |
186 | .read = fuse_conn_waiting_read, | 187 | .read = fuse_conn_waiting_read, |
188 | .llseek = no_llseek, | ||
187 | }; | 189 | }; |
188 | 190 | ||
189 | static const struct file_operations fuse_conn_max_background_ops = { | 191 | static const struct file_operations fuse_conn_max_background_ops = { |
190 | .open = nonseekable_open, | 192 | .open = nonseekable_open, |
191 | .read = fuse_conn_max_background_read, | 193 | .read = fuse_conn_max_background_read, |
192 | .write = fuse_conn_max_background_write, | 194 | .write = fuse_conn_max_background_write, |
195 | .llseek = no_llseek, | ||
193 | }; | 196 | }; |
194 | 197 | ||
195 | static const struct file_operations fuse_conn_congestion_threshold_ops = { | 198 | static const struct file_operations fuse_conn_congestion_threshold_ops = { |
196 | .open = nonseekable_open, | 199 | .open = nonseekable_open, |
197 | .read = fuse_conn_congestion_threshold_read, | 200 | .read = fuse_conn_congestion_threshold_read, |
198 | .write = fuse_conn_congestion_threshold_write, | 201 | .write = fuse_conn_congestion_threshold_write, |
202 | .llseek = no_llseek, | ||
199 | }; | 203 | }; |
200 | 204 | ||
201 | static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, | 205 | static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, |
@@ -218,6 +222,7 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, | |||
218 | if (!inode) | 222 | if (!inode) |
219 | return NULL; | 223 | return NULL; |
220 | 224 | ||
225 | inode->i_ino = get_next_ino(); | ||
221 | inode->i_mode = mode; | 226 | inode->i_mode = mode; |
222 | inode->i_uid = fc->user_id; | 227 | inode->i_uid = fc->user_id; |
223 | inode->i_gid = fc->group_id; | 228 | inode->i_gid = fc->group_id; |
@@ -317,12 +322,10 @@ static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) | |||
317 | return 0; | 322 | return 0; |
318 | } | 323 | } |
319 | 324 | ||
320 | static int fuse_ctl_get_sb(struct file_system_type *fs_type, int flags, | 325 | static struct dentry *fuse_ctl_mount(struct file_system_type *fs_type, |
321 | const char *dev_name, void *raw_data, | 326 | int flags, const char *dev_name, void *raw_data) |
322 | struct vfsmount *mnt) | ||
323 | { | 327 | { |
324 | return get_sb_single(fs_type, flags, raw_data, | 328 | return mount_single(fs_type, flags, raw_data, fuse_ctl_fill_super); |
325 | fuse_ctl_fill_super, mnt); | ||
326 | } | 329 | } |
327 | 330 | ||
328 | static void fuse_ctl_kill_sb(struct super_block *sb) | 331 | static void fuse_ctl_kill_sb(struct super_block *sb) |
@@ -341,7 +344,7 @@ static void fuse_ctl_kill_sb(struct super_block *sb) | |||
341 | static struct file_system_type fuse_ctl_fs_type = { | 344 | static struct file_system_type fuse_ctl_fs_type = { |
342 | .owner = THIS_MODULE, | 345 | .owner = THIS_MODULE, |
343 | .name = "fusectl", | 346 | .name = "fusectl", |
344 | .get_sb = fuse_ctl_get_sb, | 347 | .mount = fuse_ctl_mount, |
345 | .kill_sb = fuse_ctl_kill_sb, | 348 | .kill_sb = fuse_ctl_kill_sb, |
346 | }; | 349 | }; |
347 | 350 | ||
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index e1f8171278bd..b6cca47f7b07 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c | |||
@@ -182,6 +182,7 @@ static const struct file_operations cuse_frontend_fops = { | |||
182 | .unlocked_ioctl = cuse_file_ioctl, | 182 | .unlocked_ioctl = cuse_file_ioctl, |
183 | .compat_ioctl = cuse_file_compat_ioctl, | 183 | .compat_ioctl = cuse_file_compat_ioctl, |
184 | .poll = fuse_file_poll, | 184 | .poll = fuse_file_poll, |
185 | .llseek = noop_llseek, | ||
185 | }; | 186 | }; |
186 | 187 | ||
187 | 188 | ||
@@ -304,7 +305,7 @@ static void cuse_gendev_release(struct device *dev) | |||
304 | static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | 305 | static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) |
305 | { | 306 | { |
306 | struct cuse_conn *cc = fc_to_cc(fc); | 307 | struct cuse_conn *cc = fc_to_cc(fc); |
307 | struct cuse_init_out *arg = &req->misc.cuse_init_out; | 308 | struct cuse_init_out *arg = req->out.args[0].value; |
308 | struct page *page = req->pages[0]; | 309 | struct page *page = req->pages[0]; |
309 | struct cuse_devinfo devinfo = { }; | 310 | struct cuse_devinfo devinfo = { }; |
310 | struct device *dev; | 311 | struct device *dev; |
@@ -383,6 +384,7 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
383 | dev_set_uevent_suppress(dev, 0); | 384 | dev_set_uevent_suppress(dev, 0); |
384 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 385 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
385 | out: | 386 | out: |
387 | kfree(arg); | ||
386 | __free_page(page); | 388 | __free_page(page); |
387 | return; | 389 | return; |
388 | 390 | ||
@@ -404,6 +406,7 @@ static int cuse_send_init(struct cuse_conn *cc) | |||
404 | struct page *page; | 406 | struct page *page; |
405 | struct fuse_conn *fc = &cc->fc; | 407 | struct fuse_conn *fc = &cc->fc; |
406 | struct cuse_init_in *arg; | 408 | struct cuse_init_in *arg; |
409 | void *outarg; | ||
407 | 410 | ||
408 | BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE); | 411 | BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE); |
409 | 412 | ||
@@ -418,6 +421,10 @@ static int cuse_send_init(struct cuse_conn *cc) | |||
418 | if (!page) | 421 | if (!page) |
419 | goto err_put_req; | 422 | goto err_put_req; |
420 | 423 | ||
424 | outarg = kzalloc(sizeof(struct cuse_init_out), GFP_KERNEL); | ||
425 | if (!outarg) | ||
426 | goto err_free_page; | ||
427 | |||
421 | arg = &req->misc.cuse_init_in; | 428 | arg = &req->misc.cuse_init_in; |
422 | arg->major = FUSE_KERNEL_VERSION; | 429 | arg->major = FUSE_KERNEL_VERSION; |
423 | arg->minor = FUSE_KERNEL_MINOR_VERSION; | 430 | arg->minor = FUSE_KERNEL_MINOR_VERSION; |
@@ -428,7 +435,7 @@ static int cuse_send_init(struct cuse_conn *cc) | |||
428 | req->in.args[0].value = arg; | 435 | req->in.args[0].value = arg; |
429 | req->out.numargs = 2; | 436 | req->out.numargs = 2; |
430 | req->out.args[0].size = sizeof(struct cuse_init_out); | 437 | req->out.args[0].size = sizeof(struct cuse_init_out); |
431 | req->out.args[0].value = &req->misc.cuse_init_out; | 438 | req->out.args[0].value = outarg; |
432 | req->out.args[1].size = CUSE_INIT_INFO_MAX; | 439 | req->out.args[1].size = CUSE_INIT_INFO_MAX; |
433 | req->out.argvar = 1; | 440 | req->out.argvar = 1; |
434 | req->out.argpages = 1; | 441 | req->out.argpages = 1; |
@@ -439,6 +446,8 @@ static int cuse_send_init(struct cuse_conn *cc) | |||
439 | 446 | ||
440 | return 0; | 447 | return 0; |
441 | 448 | ||
449 | err_free_page: | ||
450 | __free_page(page); | ||
442 | err_put_req: | 451 | err_put_req: |
443 | fuse_put_request(fc, req); | 452 | fuse_put_request(fc, req); |
444 | err: | 453 | err: |
@@ -457,7 +466,7 @@ static void cuse_fc_release(struct fuse_conn *fc) | |||
457 | * @file: file struct being opened | 466 | * @file: file struct being opened |
458 | * | 467 | * |
459 | * Userland CUSE server can create a CUSE device by opening /dev/cuse | 468 | * Userland CUSE server can create a CUSE device by opening /dev/cuse |
460 | * and replying to the initilaization request kernel sends. This | 469 | * and replying to the initialization request kernel sends. This |
461 | * function is responsible for handling CUSE device initialization. | 470 | * function is responsible for handling CUSE device initialization. |
462 | * Because the fd opened by this function is used during | 471 | * Because the fd opened by this function is used during |
463 | * initialization, this function only creates cuse_conn and sends | 472 | * initialization, this function only creates cuse_conn and sends |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index cde755cca564..640fc229df10 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -251,6 +251,20 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) | |||
251 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | 251 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); |
252 | } | 252 | } |
253 | 253 | ||
254 | void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, | ||
255 | u64 nodeid, u64 nlookup) | ||
256 | { | ||
257 | forget->forget_one.nodeid = nodeid; | ||
258 | forget->forget_one.nlookup = nlookup; | ||
259 | |||
260 | spin_lock(&fc->lock); | ||
261 | fc->forget_list_tail->next = forget; | ||
262 | fc->forget_list_tail = forget; | ||
263 | wake_up(&fc->waitq); | ||
264 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | ||
265 | spin_unlock(&fc->lock); | ||
266 | } | ||
267 | |||
254 | static void flush_bg_queue(struct fuse_conn *fc) | 268 | static void flush_bg_queue(struct fuse_conn *fc) |
255 | { | 269 | { |
256 | while (fc->active_background < fc->max_background && | 270 | while (fc->active_background < fc->max_background && |
@@ -438,12 +452,6 @@ static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) | |||
438 | } | 452 | } |
439 | } | 453 | } |
440 | 454 | ||
441 | void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) | ||
442 | { | ||
443 | req->isreply = 0; | ||
444 | fuse_request_send_nowait(fc, req); | ||
445 | } | ||
446 | |||
447 | void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) | 455 | void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) |
448 | { | 456 | { |
449 | req->isreply = 1; | 457 | req->isreply = 1; |
@@ -729,14 +737,12 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) | |||
729 | if (WARN_ON(PageMlocked(oldpage))) | 737 | if (WARN_ON(PageMlocked(oldpage))) |
730 | goto out_fallback_unlock; | 738 | goto out_fallback_unlock; |
731 | 739 | ||
732 | remove_from_page_cache(oldpage); | 740 | err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); |
733 | page_cache_release(oldpage); | ||
734 | |||
735 | err = add_to_page_cache_locked(newpage, mapping, index, GFP_KERNEL); | ||
736 | if (err) { | 741 | if (err) { |
737 | printk(KERN_WARNING "fuse_try_move_page: failed to add page"); | 742 | unlock_page(newpage); |
738 | goto out_fallback_unlock; | 743 | return err; |
739 | } | 744 | } |
745 | |||
740 | page_cache_get(newpage); | 746 | page_cache_get(newpage); |
741 | 747 | ||
742 | if (!(buf->flags & PIPE_BUF_FLAG_LRU)) | 748 | if (!(buf->flags & PIPE_BUF_FLAG_LRU)) |
@@ -809,11 +815,9 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, | |||
809 | int err; | 815 | int err; |
810 | struct page *page = *pagep; | 816 | struct page *page = *pagep; |
811 | 817 | ||
812 | if (page && zeroing && count < PAGE_SIZE) { | 818 | if (page && zeroing && count < PAGE_SIZE) |
813 | void *mapaddr = kmap_atomic(page, KM_USER1); | 819 | clear_highpage(page); |
814 | memset(mapaddr, 0, PAGE_SIZE); | 820 | |
815 | kunmap_atomic(mapaddr, KM_USER1); | ||
816 | } | ||
817 | while (count) { | 821 | while (count) { |
818 | if (cs->write && cs->pipebufs && page) { | 822 | if (cs->write && cs->pipebufs && page) { |
819 | return fuse_ref_page(cs, page, offset, count); | 823 | return fuse_ref_page(cs, page, offset, count); |
@@ -830,10 +834,10 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, | |||
830 | } | 834 | } |
831 | } | 835 | } |
832 | if (page) { | 836 | if (page) { |
833 | void *mapaddr = kmap_atomic(page, KM_USER1); | 837 | void *mapaddr = kmap_atomic(page, KM_USER0); |
834 | void *buf = mapaddr + offset; | 838 | void *buf = mapaddr + offset; |
835 | offset += fuse_copy_do(cs, &buf, &count); | 839 | offset += fuse_copy_do(cs, &buf, &count); |
836 | kunmap_atomic(mapaddr, KM_USER1); | 840 | kunmap_atomic(mapaddr, KM_USER0); |
837 | } else | 841 | } else |
838 | offset += fuse_copy_do(cs, NULL, &count); | 842 | offset += fuse_copy_do(cs, NULL, &count); |
839 | } | 843 | } |
@@ -898,9 +902,15 @@ static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, | |||
898 | return err; | 902 | return err; |
899 | } | 903 | } |
900 | 904 | ||
905 | static int forget_pending(struct fuse_conn *fc) | ||
906 | { | ||
907 | return fc->forget_list_head.next != NULL; | ||
908 | } | ||
909 | |||
901 | static int request_pending(struct fuse_conn *fc) | 910 | static int request_pending(struct fuse_conn *fc) |
902 | { | 911 | { |
903 | return !list_empty(&fc->pending) || !list_empty(&fc->interrupts); | 912 | return !list_empty(&fc->pending) || !list_empty(&fc->interrupts) || |
913 | forget_pending(fc); | ||
904 | } | 914 | } |
905 | 915 | ||
906 | /* Wait until a request is available on the pending list */ | 916 | /* Wait until a request is available on the pending list */ |
@@ -962,6 +972,120 @@ __releases(fc->lock) | |||
962 | return err ? err : reqsize; | 972 | return err ? err : reqsize; |
963 | } | 973 | } |
964 | 974 | ||
975 | static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc, | ||
976 | unsigned max, | ||
977 | unsigned *countp) | ||
978 | { | ||
979 | struct fuse_forget_link *head = fc->forget_list_head.next; | ||
980 | struct fuse_forget_link **newhead = &head; | ||
981 | unsigned count; | ||
982 | |||
983 | for (count = 0; *newhead != NULL && count < max; count++) | ||
984 | newhead = &(*newhead)->next; | ||
985 | |||
986 | fc->forget_list_head.next = *newhead; | ||
987 | *newhead = NULL; | ||
988 | if (fc->forget_list_head.next == NULL) | ||
989 | fc->forget_list_tail = &fc->forget_list_head; | ||
990 | |||
991 | if (countp != NULL) | ||
992 | *countp = count; | ||
993 | |||
994 | return head; | ||
995 | } | ||
996 | |||
997 | static int fuse_read_single_forget(struct fuse_conn *fc, | ||
998 | struct fuse_copy_state *cs, | ||
999 | size_t nbytes) | ||
1000 | __releases(fc->lock) | ||
1001 | { | ||
1002 | int err; | ||
1003 | struct fuse_forget_link *forget = dequeue_forget(fc, 1, NULL); | ||
1004 | struct fuse_forget_in arg = { | ||
1005 | .nlookup = forget->forget_one.nlookup, | ||
1006 | }; | ||
1007 | struct fuse_in_header ih = { | ||
1008 | .opcode = FUSE_FORGET, | ||
1009 | .nodeid = forget->forget_one.nodeid, | ||
1010 | .unique = fuse_get_unique(fc), | ||
1011 | .len = sizeof(ih) + sizeof(arg), | ||
1012 | }; | ||
1013 | |||
1014 | spin_unlock(&fc->lock); | ||
1015 | kfree(forget); | ||
1016 | if (nbytes < ih.len) | ||
1017 | return -EINVAL; | ||
1018 | |||
1019 | err = fuse_copy_one(cs, &ih, sizeof(ih)); | ||
1020 | if (!err) | ||
1021 | err = fuse_copy_one(cs, &arg, sizeof(arg)); | ||
1022 | fuse_copy_finish(cs); | ||
1023 | |||
1024 | if (err) | ||
1025 | return err; | ||
1026 | |||
1027 | return ih.len; | ||
1028 | } | ||
1029 | |||
1030 | static int fuse_read_batch_forget(struct fuse_conn *fc, | ||
1031 | struct fuse_copy_state *cs, size_t nbytes) | ||
1032 | __releases(fc->lock) | ||
1033 | { | ||
1034 | int err; | ||
1035 | unsigned max_forgets; | ||
1036 | unsigned count; | ||
1037 | struct fuse_forget_link *head; | ||
1038 | struct fuse_batch_forget_in arg = { .count = 0 }; | ||
1039 | struct fuse_in_header ih = { | ||
1040 | .opcode = FUSE_BATCH_FORGET, | ||
1041 | .unique = fuse_get_unique(fc), | ||
1042 | .len = sizeof(ih) + sizeof(arg), | ||
1043 | }; | ||
1044 | |||
1045 | if (nbytes < ih.len) { | ||
1046 | spin_unlock(&fc->lock); | ||
1047 | return -EINVAL; | ||
1048 | } | ||
1049 | |||
1050 | max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); | ||
1051 | head = dequeue_forget(fc, max_forgets, &count); | ||
1052 | spin_unlock(&fc->lock); | ||
1053 | |||
1054 | arg.count = count; | ||
1055 | ih.len += count * sizeof(struct fuse_forget_one); | ||
1056 | err = fuse_copy_one(cs, &ih, sizeof(ih)); | ||
1057 | if (!err) | ||
1058 | err = fuse_copy_one(cs, &arg, sizeof(arg)); | ||
1059 | |||
1060 | while (head) { | ||
1061 | struct fuse_forget_link *forget = head; | ||
1062 | |||
1063 | if (!err) { | ||
1064 | err = fuse_copy_one(cs, &forget->forget_one, | ||
1065 | sizeof(forget->forget_one)); | ||
1066 | } | ||
1067 | head = forget->next; | ||
1068 | kfree(forget); | ||
1069 | } | ||
1070 | |||
1071 | fuse_copy_finish(cs); | ||
1072 | |||
1073 | if (err) | ||
1074 | return err; | ||
1075 | |||
1076 | return ih.len; | ||
1077 | } | ||
1078 | |||
1079 | static int fuse_read_forget(struct fuse_conn *fc, struct fuse_copy_state *cs, | ||
1080 | size_t nbytes) | ||
1081 | __releases(fc->lock) | ||
1082 | { | ||
1083 | if (fc->minor < 16 || fc->forget_list_head.next->next == NULL) | ||
1084 | return fuse_read_single_forget(fc, cs, nbytes); | ||
1085 | else | ||
1086 | return fuse_read_batch_forget(fc, cs, nbytes); | ||
1087 | } | ||
1088 | |||
965 | /* | 1089 | /* |
966 | * Read a single request into the userspace filesystem's buffer. This | 1090 | * Read a single request into the userspace filesystem's buffer. This |
967 | * function waits until a request is available, then removes it from | 1091 | * function waits until a request is available, then removes it from |
@@ -1000,6 +1124,14 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, | |||
1000 | return fuse_read_interrupt(fc, cs, nbytes, req); | 1124 | return fuse_read_interrupt(fc, cs, nbytes, req); |
1001 | } | 1125 | } |
1002 | 1126 | ||
1127 | if (forget_pending(fc)) { | ||
1128 | if (list_empty(&fc->pending) || fc->forget_batch-- > 0) | ||
1129 | return fuse_read_forget(fc, cs, nbytes); | ||
1130 | |||
1131 | if (fc->forget_batch <= -8) | ||
1132 | fc->forget_batch = 16; | ||
1133 | } | ||
1134 | |||
1003 | req = list_entry(fc->pending.next, struct fuse_req, list); | 1135 | req = list_entry(fc->pending.next, struct fuse_req, list); |
1004 | req->state = FUSE_REQ_READING; | 1136 | req->state = FUSE_REQ_READING; |
1005 | list_move(&req->list, &fc->io); | 1137 | list_move(&req->list, &fc->io); |
@@ -1092,7 +1224,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, | |||
1092 | if (!fc) | 1224 | if (!fc) |
1093 | return -EPERM; | 1225 | return -EPERM; |
1094 | 1226 | ||
1095 | bufs = kmalloc(pipe->buffers * sizeof (struct pipe_buffer), GFP_KERNEL); | 1227 | bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); |
1096 | if (!bufs) | 1228 | if (!bufs) |
1097 | return -ENOMEM; | 1229 | return -ENOMEM; |
1098 | 1230 | ||
@@ -1336,12 +1468,7 @@ out_finish: | |||
1336 | 1468 | ||
1337 | static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) | 1469 | static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) |
1338 | { | 1470 | { |
1339 | int i; | 1471 | release_pages(req->pages, req->num_pages, 0); |
1340 | |||
1341 | for (i = 0; i < req->num_pages; i++) { | ||
1342 | struct page *page = req->pages[i]; | ||
1343 | page_cache_release(page); | ||
1344 | } | ||
1345 | } | 1472 | } |
1346 | 1473 | ||
1347 | static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, | 1474 | static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, |
@@ -1633,7 +1760,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, | |||
1633 | if (!fc) | 1760 | if (!fc) |
1634 | return -EPERM; | 1761 | return -EPERM; |
1635 | 1762 | ||
1636 | bufs = kmalloc(pipe->buffers * sizeof (struct pipe_buffer), GFP_KERNEL); | 1763 | bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); |
1637 | if (!bufs) | 1764 | if (!bufs) |
1638 | return -ENOMEM; | 1765 | return -ENOMEM; |
1639 | 1766 | ||
@@ -1777,6 +1904,23 @@ __acquires(fc->lock) | |||
1777 | flush_bg_queue(fc); | 1904 | flush_bg_queue(fc); |
1778 | end_requests(fc, &fc->pending); | 1905 | end_requests(fc, &fc->pending); |
1779 | end_requests(fc, &fc->processing); | 1906 | end_requests(fc, &fc->processing); |
1907 | while (forget_pending(fc)) | ||
1908 | kfree(dequeue_forget(fc, 1, NULL)); | ||
1909 | } | ||
1910 | |||
1911 | static void end_polls(struct fuse_conn *fc) | ||
1912 | { | ||
1913 | struct rb_node *p; | ||
1914 | |||
1915 | p = rb_first(&fc->polled_files); | ||
1916 | |||
1917 | while (p) { | ||
1918 | struct fuse_file *ff; | ||
1919 | ff = rb_entry(p, struct fuse_file, polled_node); | ||
1920 | wake_up_interruptible_all(&ff->poll_wait); | ||
1921 | |||
1922 | p = rb_next(p); | ||
1923 | } | ||
1780 | } | 1924 | } |
1781 | 1925 | ||
1782 | /* | 1926 | /* |
@@ -1806,6 +1950,7 @@ void fuse_abort_conn(struct fuse_conn *fc) | |||
1806 | fc->blocked = 0; | 1950 | fc->blocked = 0; |
1807 | end_io_requests(fc); | 1951 | end_io_requests(fc); |
1808 | end_queued_requests(fc); | 1952 | end_queued_requests(fc); |
1953 | end_polls(fc); | ||
1809 | wake_up_all(&fc->waitq); | 1954 | wake_up_all(&fc->waitq); |
1810 | wake_up_all(&fc->blocked_waitq); | 1955 | wake_up_all(&fc->blocked_waitq); |
1811 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | 1956 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); |
@@ -1822,6 +1967,7 @@ int fuse_dev_release(struct inode *inode, struct file *file) | |||
1822 | fc->connected = 0; | 1967 | fc->connected = 0; |
1823 | fc->blocked = 0; | 1968 | fc->blocked = 0; |
1824 | end_queued_requests(fc); | 1969 | end_queued_requests(fc); |
1970 | end_polls(fc); | ||
1825 | wake_up_all(&fc->blocked_waitq); | 1971 | wake_up_all(&fc->blocked_waitq); |
1826 | spin_unlock(&fc->lock); | 1972 | spin_unlock(&fc->lock); |
1827 | fuse_conn_put(fc); | 1973 | fuse_conn_put(fc); |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index c9627c95482d..d50160714595 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -10,9 +10,9 @@ | |||
10 | 10 | ||
11 | #include <linux/pagemap.h> | 11 | #include <linux/pagemap.h> |
12 | #include <linux/file.h> | 12 | #include <linux/file.h> |
13 | #include <linux/gfp.h> | ||
14 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
15 | #include <linux/namei.h> | 14 | #include <linux/namei.h> |
15 | #include <linux/slab.h> | ||
16 | 16 | ||
17 | #if BITS_PER_LONG >= 64 | 17 | #if BITS_PER_LONG >= 64 |
18 | static inline void fuse_dentry_settime(struct dentry *entry, u64 time) | 18 | static inline void fuse_dentry_settime(struct dentry *entry, u64 time) |
@@ -156,8 +156,9 @@ u64 fuse_get_attr_version(struct fuse_conn *fc) | |||
156 | */ | 156 | */ |
157 | static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | 157 | static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) |
158 | { | 158 | { |
159 | struct inode *inode = entry->d_inode; | 159 | struct inode *inode; |
160 | 160 | ||
161 | inode = ACCESS_ONCE(entry->d_inode); | ||
161 | if (inode && is_bad_inode(inode)) | 162 | if (inode && is_bad_inode(inode)) |
162 | return 0; | 163 | return 0; |
163 | else if (fuse_dentry_time(entry) < get_jiffies_64()) { | 164 | else if (fuse_dentry_time(entry) < get_jiffies_64()) { |
@@ -165,7 +166,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
165 | struct fuse_entry_out outarg; | 166 | struct fuse_entry_out outarg; |
166 | struct fuse_conn *fc; | 167 | struct fuse_conn *fc; |
167 | struct fuse_req *req; | 168 | struct fuse_req *req; |
168 | struct fuse_req *forget_req; | 169 | struct fuse_forget_link *forget; |
169 | struct dentry *parent; | 170 | struct dentry *parent; |
170 | u64 attr_version; | 171 | u64 attr_version; |
171 | 172 | ||
@@ -173,13 +174,16 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
173 | if (!inode) | 174 | if (!inode) |
174 | return 0; | 175 | return 0; |
175 | 176 | ||
177 | if (nd && (nd->flags & LOOKUP_RCU)) | ||
178 | return -ECHILD; | ||
179 | |||
176 | fc = get_fuse_conn(inode); | 180 | fc = get_fuse_conn(inode); |
177 | req = fuse_get_req(fc); | 181 | req = fuse_get_req(fc); |
178 | if (IS_ERR(req)) | 182 | if (IS_ERR(req)) |
179 | return 0; | 183 | return 0; |
180 | 184 | ||
181 | forget_req = fuse_get_req(fc); | 185 | forget = fuse_alloc_forget(); |
182 | if (IS_ERR(forget_req)) { | 186 | if (!forget) { |
183 | fuse_put_request(fc, req); | 187 | fuse_put_request(fc, req); |
184 | return 0; | 188 | return 0; |
185 | } | 189 | } |
@@ -199,15 +203,14 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
199 | if (!err) { | 203 | if (!err) { |
200 | struct fuse_inode *fi = get_fuse_inode(inode); | 204 | struct fuse_inode *fi = get_fuse_inode(inode); |
201 | if (outarg.nodeid != get_node_id(inode)) { | 205 | if (outarg.nodeid != get_node_id(inode)) { |
202 | fuse_send_forget(fc, forget_req, | 206 | fuse_queue_forget(fc, forget, outarg.nodeid, 1); |
203 | outarg.nodeid, 1); | ||
204 | return 0; | 207 | return 0; |
205 | } | 208 | } |
206 | spin_lock(&fc->lock); | 209 | spin_lock(&fc->lock); |
207 | fi->nlookup++; | 210 | fi->nlookup++; |
208 | spin_unlock(&fc->lock); | 211 | spin_unlock(&fc->lock); |
209 | } | 212 | } |
210 | fuse_put_request(fc, forget_req); | 213 | kfree(forget); |
211 | if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) | 214 | if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) |
212 | return 0; | 215 | return 0; |
213 | 216 | ||
@@ -259,7 +262,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, | |||
259 | { | 262 | { |
260 | struct fuse_conn *fc = get_fuse_conn_super(sb); | 263 | struct fuse_conn *fc = get_fuse_conn_super(sb); |
261 | struct fuse_req *req; | 264 | struct fuse_req *req; |
262 | struct fuse_req *forget_req; | 265 | struct fuse_forget_link *forget; |
263 | u64 attr_version; | 266 | u64 attr_version; |
264 | int err; | 267 | int err; |
265 | 268 | ||
@@ -273,9 +276,9 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, | |||
273 | if (IS_ERR(req)) | 276 | if (IS_ERR(req)) |
274 | goto out; | 277 | goto out; |
275 | 278 | ||
276 | forget_req = fuse_get_req(fc); | 279 | forget = fuse_alloc_forget(); |
277 | err = PTR_ERR(forget_req); | 280 | err = -ENOMEM; |
278 | if (IS_ERR(forget_req)) { | 281 | if (!forget) { |
279 | fuse_put_request(fc, req); | 282 | fuse_put_request(fc, req); |
280 | goto out; | 283 | goto out; |
281 | } | 284 | } |
@@ -301,13 +304,13 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, | |||
301 | attr_version); | 304 | attr_version); |
302 | err = -ENOMEM; | 305 | err = -ENOMEM; |
303 | if (!*inode) { | 306 | if (!*inode) { |
304 | fuse_send_forget(fc, forget_req, outarg->nodeid, 1); | 307 | fuse_queue_forget(fc, forget, outarg->nodeid, 1); |
305 | goto out; | 308 | goto out; |
306 | } | 309 | } |
307 | err = 0; | 310 | err = 0; |
308 | 311 | ||
309 | out_put_forget: | 312 | out_put_forget: |
310 | fuse_put_request(fc, forget_req); | 313 | kfree(forget); |
311 | out: | 314 | out: |
312 | return err; | 315 | return err; |
313 | } | 316 | } |
@@ -347,7 +350,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
347 | } | 350 | } |
348 | 351 | ||
349 | entry = newent ? newent : entry; | 352 | entry = newent ? newent : entry; |
350 | entry->d_op = &fuse_dentry_operations; | ||
351 | if (outarg_valid) | 353 | if (outarg_valid) |
352 | fuse_change_entry_timeout(entry, &outarg); | 354 | fuse_change_entry_timeout(entry, &outarg); |
353 | else | 355 | else |
@@ -374,7 +376,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
374 | struct inode *inode; | 376 | struct inode *inode; |
375 | struct fuse_conn *fc = get_fuse_conn(dir); | 377 | struct fuse_conn *fc = get_fuse_conn(dir); |
376 | struct fuse_req *req; | 378 | struct fuse_req *req; |
377 | struct fuse_req *forget_req; | 379 | struct fuse_forget_link *forget; |
378 | struct fuse_create_in inarg; | 380 | struct fuse_create_in inarg; |
379 | struct fuse_open_out outopen; | 381 | struct fuse_open_out outopen; |
380 | struct fuse_entry_out outentry; | 382 | struct fuse_entry_out outentry; |
@@ -388,9 +390,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
388 | if (flags & O_DIRECT) | 390 | if (flags & O_DIRECT) |
389 | return -EINVAL; | 391 | return -EINVAL; |
390 | 392 | ||
391 | forget_req = fuse_get_req(fc); | 393 | forget = fuse_alloc_forget(); |
392 | if (IS_ERR(forget_req)) | 394 | if (!forget) |
393 | return PTR_ERR(forget_req); | 395 | return -ENOMEM; |
394 | 396 | ||
395 | req = fuse_get_req(fc); | 397 | req = fuse_get_req(fc); |
396 | err = PTR_ERR(req); | 398 | err = PTR_ERR(req); |
@@ -448,10 +450,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
448 | if (!inode) { | 450 | if (!inode) { |
449 | flags &= ~(O_CREAT | O_EXCL | O_TRUNC); | 451 | flags &= ~(O_CREAT | O_EXCL | O_TRUNC); |
450 | fuse_sync_release(ff, flags); | 452 | fuse_sync_release(ff, flags); |
451 | fuse_send_forget(fc, forget_req, outentry.nodeid, 1); | 453 | fuse_queue_forget(fc, forget, outentry.nodeid, 1); |
452 | return -ENOMEM; | 454 | return -ENOMEM; |
453 | } | 455 | } |
454 | fuse_put_request(fc, forget_req); | 456 | kfree(forget); |
455 | d_instantiate(entry, inode); | 457 | d_instantiate(entry, inode); |
456 | fuse_change_entry_timeout(entry, &outentry); | 458 | fuse_change_entry_timeout(entry, &outentry); |
457 | fuse_invalidate_attr(dir); | 459 | fuse_invalidate_attr(dir); |
@@ -469,7 +471,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
469 | out_put_request: | 471 | out_put_request: |
470 | fuse_put_request(fc, req); | 472 | fuse_put_request(fc, req); |
471 | out_put_forget_req: | 473 | out_put_forget_req: |
472 | fuse_put_request(fc, forget_req); | 474 | kfree(forget); |
473 | return err; | 475 | return err; |
474 | } | 476 | } |
475 | 477 | ||
@@ -483,12 +485,12 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
483 | struct fuse_entry_out outarg; | 485 | struct fuse_entry_out outarg; |
484 | struct inode *inode; | 486 | struct inode *inode; |
485 | int err; | 487 | int err; |
486 | struct fuse_req *forget_req; | 488 | struct fuse_forget_link *forget; |
487 | 489 | ||
488 | forget_req = fuse_get_req(fc); | 490 | forget = fuse_alloc_forget(); |
489 | if (IS_ERR(forget_req)) { | 491 | if (!forget) { |
490 | fuse_put_request(fc, req); | 492 | fuse_put_request(fc, req); |
491 | return PTR_ERR(forget_req); | 493 | return -ENOMEM; |
492 | } | 494 | } |
493 | 495 | ||
494 | memset(&outarg, 0, sizeof(outarg)); | 496 | memset(&outarg, 0, sizeof(outarg)); |
@@ -515,10 +517,10 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
515 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, | 517 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, |
516 | &outarg.attr, entry_attr_timeout(&outarg), 0); | 518 | &outarg.attr, entry_attr_timeout(&outarg), 0); |
517 | if (!inode) { | 519 | if (!inode) { |
518 | fuse_send_forget(fc, forget_req, outarg.nodeid, 1); | 520 | fuse_queue_forget(fc, forget, outarg.nodeid, 1); |
519 | return -ENOMEM; | 521 | return -ENOMEM; |
520 | } | 522 | } |
521 | fuse_put_request(fc, forget_req); | 523 | kfree(forget); |
522 | 524 | ||
523 | if (S_ISDIR(inode->i_mode)) { | 525 | if (S_ISDIR(inode->i_mode)) { |
524 | struct dentry *alias; | 526 | struct dentry *alias; |
@@ -541,7 +543,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
541 | return 0; | 543 | return 0; |
542 | 544 | ||
543 | out_put_forget_req: | 545 | out_put_forget_req: |
544 | fuse_put_request(fc, forget_req); | 546 | kfree(forget); |
545 | return err; | 547 | return err; |
546 | } | 548 | } |
547 | 549 | ||
@@ -689,6 +691,7 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
689 | struct fuse_rename_in inarg; | 691 | struct fuse_rename_in inarg; |
690 | struct fuse_conn *fc = get_fuse_conn(olddir); | 692 | struct fuse_conn *fc = get_fuse_conn(olddir); |
691 | struct fuse_req *req = fuse_get_req(fc); | 693 | struct fuse_req *req = fuse_get_req(fc); |
694 | |||
692 | if (IS_ERR(req)) | 695 | if (IS_ERR(req)) |
693 | return PTR_ERR(req); | 696 | return PTR_ERR(req); |
694 | 697 | ||
@@ -968,6 +971,14 @@ static int fuse_access(struct inode *inode, int mask) | |||
968 | return err; | 971 | return err; |
969 | } | 972 | } |
970 | 973 | ||
974 | static int fuse_perm_getattr(struct inode *inode, int flags) | ||
975 | { | ||
976 | if (flags & IPERM_FLAG_RCU) | ||
977 | return -ECHILD; | ||
978 | |||
979 | return fuse_do_getattr(inode, NULL, NULL); | ||
980 | } | ||
981 | |||
971 | /* | 982 | /* |
972 | * Check permission. The two basic access models of FUSE are: | 983 | * Check permission. The two basic access models of FUSE are: |
973 | * | 984 | * |
@@ -981,7 +992,7 @@ static int fuse_access(struct inode *inode, int mask) | |||
981 | * access request is sent. Execute permission is still checked | 992 | * access request is sent. Execute permission is still checked |
982 | * locally based on file mode. | 993 | * locally based on file mode. |
983 | */ | 994 | */ |
984 | static int fuse_permission(struct inode *inode, int mask) | 995 | static int fuse_permission(struct inode *inode, int mask, unsigned int flags) |
985 | { | 996 | { |
986 | struct fuse_conn *fc = get_fuse_conn(inode); | 997 | struct fuse_conn *fc = get_fuse_conn(inode); |
987 | bool refreshed = false; | 998 | bool refreshed = false; |
@@ -995,21 +1006,28 @@ static int fuse_permission(struct inode *inode, int mask) | |||
995 | */ | 1006 | */ |
996 | if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || | 1007 | if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || |
997 | ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { | 1008 | ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { |
998 | err = fuse_update_attributes(inode, NULL, NULL, &refreshed); | 1009 | struct fuse_inode *fi = get_fuse_inode(inode); |
999 | if (err) | 1010 | |
1000 | return err; | 1011 | if (fi->i_time < get_jiffies_64()) { |
1012 | refreshed = true; | ||
1013 | |||
1014 | err = fuse_perm_getattr(inode, flags); | ||
1015 | if (err) | ||
1016 | return err; | ||
1017 | } | ||
1001 | } | 1018 | } |
1002 | 1019 | ||
1003 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { | 1020 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { |
1004 | err = generic_permission(inode, mask, NULL); | 1021 | err = generic_permission(inode, mask, flags, NULL); |
1005 | 1022 | ||
1006 | /* If permission is denied, try to refresh file | 1023 | /* If permission is denied, try to refresh file |
1007 | attributes. This is also needed, because the root | 1024 | attributes. This is also needed, because the root |
1008 | node will at first have no permissions */ | 1025 | node will at first have no permissions */ |
1009 | if (err == -EACCES && !refreshed) { | 1026 | if (err == -EACCES && !refreshed) { |
1010 | err = fuse_do_getattr(inode, NULL, NULL); | 1027 | err = fuse_perm_getattr(inode, flags); |
1011 | if (!err) | 1028 | if (!err) |
1012 | err = generic_permission(inode, mask, NULL); | 1029 | err = generic_permission(inode, mask, |
1030 | flags, NULL); | ||
1013 | } | 1031 | } |
1014 | 1032 | ||
1015 | /* Note: the opposite of the above test does not | 1033 | /* Note: the opposite of the above test does not |
@@ -1017,13 +1035,16 @@ static int fuse_permission(struct inode *inode, int mask) | |||
1017 | noticed immediately, only after the attribute | 1035 | noticed immediately, only after the attribute |
1018 | timeout has expired */ | 1036 | timeout has expired */ |
1019 | } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { | 1037 | } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { |
1038 | if (flags & IPERM_FLAG_RCU) | ||
1039 | return -ECHILD; | ||
1040 | |||
1020 | err = fuse_access(inode, mask); | 1041 | err = fuse_access(inode, mask); |
1021 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { | 1042 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { |
1022 | if (!(inode->i_mode & S_IXUGO)) { | 1043 | if (!(inode->i_mode & S_IXUGO)) { |
1023 | if (refreshed) | 1044 | if (refreshed) |
1024 | return -EACCES; | 1045 | return -EACCES; |
1025 | 1046 | ||
1026 | err = fuse_do_getattr(inode, NULL, NULL); | 1047 | err = fuse_perm_getattr(inode, flags); |
1027 | if (!err && !(inode->i_mode & S_IXUGO)) | 1048 | if (!err && !(inode->i_mode & S_IXUGO)) |
1028 | return -EACCES; | 1049 | return -EACCES; |
1029 | } | 1050 | } |
@@ -1277,8 +1298,11 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, | |||
1277 | if (err) | 1298 | if (err) |
1278 | return err; | 1299 | return err; |
1279 | 1300 | ||
1280 | if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc) | 1301 | if (attr->ia_valid & ATTR_OPEN) { |
1281 | return 0; | 1302 | if (fc->atomic_o_trunc) |
1303 | return 0; | ||
1304 | file = NULL; | ||
1305 | } | ||
1282 | 1306 | ||
1283 | if (attr->ia_valid & ATTR_SIZE) | 1307 | if (attr->ia_valid & ATTR_SIZE) |
1284 | is_truncate = true; | 1308 | is_truncate = true; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c8224587123f..82a66466a24c 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/compat.h> | ||
16 | 17 | ||
17 | static const struct file_operations fuse_direct_io_file_operations; | 18 | static const struct file_operations fuse_direct_io_file_operations; |
18 | 19 | ||
@@ -85,18 +86,52 @@ struct fuse_file *fuse_file_get(struct fuse_file *ff) | |||
85 | return ff; | 86 | return ff; |
86 | } | 87 | } |
87 | 88 | ||
89 | static void fuse_release_async(struct work_struct *work) | ||
90 | { | ||
91 | struct fuse_req *req; | ||
92 | struct fuse_conn *fc; | ||
93 | struct path path; | ||
94 | |||
95 | req = container_of(work, struct fuse_req, misc.release.work); | ||
96 | path = req->misc.release.path; | ||
97 | fc = get_fuse_conn(path.dentry->d_inode); | ||
98 | |||
99 | fuse_put_request(fc, req); | ||
100 | path_put(&path); | ||
101 | } | ||
102 | |||
88 | static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req) | 103 | static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req) |
89 | { | 104 | { |
90 | path_put(&req->misc.release.path); | 105 | if (fc->destroy_req) { |
106 | /* | ||
107 | * If this is a fuseblk mount, then it's possible that | ||
108 | * releasing the path will result in releasing the | ||
109 | * super block and sending the DESTROY request. If | ||
110 | * the server is single threaded, this would hang. | ||
111 | * For this reason do the path_put() in a separate | ||
112 | * thread. | ||
113 | */ | ||
114 | atomic_inc(&req->count); | ||
115 | INIT_WORK(&req->misc.release.work, fuse_release_async); | ||
116 | schedule_work(&req->misc.release.work); | ||
117 | } else { | ||
118 | path_put(&req->misc.release.path); | ||
119 | } | ||
91 | } | 120 | } |
92 | 121 | ||
93 | static void fuse_file_put(struct fuse_file *ff) | 122 | static void fuse_file_put(struct fuse_file *ff, bool sync) |
94 | { | 123 | { |
95 | if (atomic_dec_and_test(&ff->count)) { | 124 | if (atomic_dec_and_test(&ff->count)) { |
96 | struct fuse_req *req = ff->reserved_req; | 125 | struct fuse_req *req = ff->reserved_req; |
97 | 126 | ||
98 | req->end = fuse_release_end; | 127 | if (sync) { |
99 | fuse_request_send_background(ff->fc, req); | 128 | fuse_request_send(ff->fc, req); |
129 | path_put(&req->misc.release.path); | ||
130 | fuse_put_request(ff->fc, req); | ||
131 | } else { | ||
132 | req->end = fuse_release_end; | ||
133 | fuse_request_send_background(ff->fc, req); | ||
134 | } | ||
100 | kfree(ff); | 135 | kfree(ff); |
101 | } | 136 | } |
102 | } | 137 | } |
@@ -134,6 +169,7 @@ EXPORT_SYMBOL_GPL(fuse_do_open); | |||
134 | void fuse_finish_open(struct inode *inode, struct file *file) | 169 | void fuse_finish_open(struct inode *inode, struct file *file) |
135 | { | 170 | { |
136 | struct fuse_file *ff = file->private_data; | 171 | struct fuse_file *ff = file->private_data; |
172 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
137 | 173 | ||
138 | if (ff->open_flags & FOPEN_DIRECT_IO) | 174 | if (ff->open_flags & FOPEN_DIRECT_IO) |
139 | file->f_op = &fuse_direct_io_file_operations; | 175 | file->f_op = &fuse_direct_io_file_operations; |
@@ -141,6 +177,15 @@ void fuse_finish_open(struct inode *inode, struct file *file) | |||
141 | invalidate_inode_pages2(inode->i_mapping); | 177 | invalidate_inode_pages2(inode->i_mapping); |
142 | if (ff->open_flags & FOPEN_NONSEEKABLE) | 178 | if (ff->open_flags & FOPEN_NONSEEKABLE) |
143 | nonseekable_open(inode, file); | 179 | nonseekable_open(inode, file); |
180 | if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) { | ||
181 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
182 | |||
183 | spin_lock(&fc->lock); | ||
184 | fi->attr_version = ++fc->attr_version; | ||
185 | i_size_write(inode, 0); | ||
186 | spin_unlock(&fc->lock); | ||
187 | fuse_invalidate_attr(inode); | ||
188 | } | ||
144 | } | 189 | } |
145 | 190 | ||
146 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) | 191 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) |
@@ -177,7 +222,7 @@ static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode) | |||
177 | rb_erase(&ff->polled_node, &fc->polled_files); | 222 | rb_erase(&ff->polled_node, &fc->polled_files); |
178 | spin_unlock(&fc->lock); | 223 | spin_unlock(&fc->lock); |
179 | 224 | ||
180 | wake_up_interruptible_sync(&ff->poll_wait); | 225 | wake_up_interruptible_all(&ff->poll_wait); |
181 | 226 | ||
182 | inarg->fh = ff->fh; | 227 | inarg->fh = ff->fh; |
183 | inarg->flags = flags; | 228 | inarg->flags = flags; |
@@ -208,8 +253,12 @@ void fuse_release_common(struct file *file, int opcode) | |||
208 | * Normally this will send the RELEASE request, however if | 253 | * Normally this will send the RELEASE request, however if |
209 | * some asynchronous READ or WRITE requests are outstanding, | 254 | * some asynchronous READ or WRITE requests are outstanding, |
210 | * the sending will be delayed. | 255 | * the sending will be delayed. |
256 | * | ||
257 | * Make the release synchronous if this is a fuseblk mount, | ||
258 | * synchronous RELEASE is allowed (and desirable) in this case | ||
259 | * because the server can be trusted not to screw up. | ||
211 | */ | 260 | */ |
212 | fuse_file_put(ff); | 261 | fuse_file_put(ff, ff->fc->destroy_req != NULL); |
213 | } | 262 | } |
214 | 263 | ||
215 | static int fuse_open(struct inode *inode, struct file *file) | 264 | static int fuse_open(struct inode *inode, struct file *file) |
@@ -474,7 +523,7 @@ static int fuse_readpage(struct file *file, struct page *page) | |||
474 | goto out; | 523 | goto out; |
475 | 524 | ||
476 | /* | 525 | /* |
477 | * Page writeback can extend beyond the liftime of the | 526 | * Page writeback can extend beyond the lifetime of the |
478 | * page-cache page, so make sure we read a properly synced | 527 | * page-cache page, so make sure we read a properly synced |
479 | * page. | 528 | * page. |
480 | */ | 529 | */ |
@@ -547,7 +596,7 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req) | |||
547 | page_cache_release(page); | 596 | page_cache_release(page); |
548 | } | 597 | } |
549 | if (req->ff) | 598 | if (req->ff) |
550 | fuse_file_put(req->ff); | 599 | fuse_file_put(req->ff, false); |
551 | } | 600 | } |
552 | 601 | ||
553 | static void fuse_send_readpages(struct fuse_req *req, struct file *file) | 602 | static void fuse_send_readpages(struct fuse_req *req, struct file *file) |
@@ -1126,7 +1175,7 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, | |||
1126 | static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req) | 1175 | static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req) |
1127 | { | 1176 | { |
1128 | __free_page(req->pages[0]); | 1177 | __free_page(req->pages[0]); |
1129 | fuse_file_put(req->ff); | 1178 | fuse_file_put(req->ff, false); |
1130 | } | 1179 | } |
1131 | 1180 | ||
1132 | static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req) | 1181 | static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req) |
@@ -1618,6 +1667,94 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, | |||
1618 | } | 1667 | } |
1619 | 1668 | ||
1620 | /* | 1669 | /* |
1670 | * CUSE servers compiled on 32bit broke on 64bit kernels because the | ||
1671 | * ABI was defined to be 'struct iovec' which is different on 32bit | ||
1672 | * and 64bit. Fortunately we can determine which structure the server | ||
1673 | * used from the size of the reply. | ||
1674 | */ | ||
1675 | static int fuse_copy_ioctl_iovec_old(struct iovec *dst, void *src, | ||
1676 | size_t transferred, unsigned count, | ||
1677 | bool is_compat) | ||
1678 | { | ||
1679 | #ifdef CONFIG_COMPAT | ||
1680 | if (count * sizeof(struct compat_iovec) == transferred) { | ||
1681 | struct compat_iovec *ciov = src; | ||
1682 | unsigned i; | ||
1683 | |||
1684 | /* | ||
1685 | * With this interface a 32bit server cannot support | ||
1686 | * non-compat (i.e. ones coming from 64bit apps) ioctl | ||
1687 | * requests | ||
1688 | */ | ||
1689 | if (!is_compat) | ||
1690 | return -EINVAL; | ||
1691 | |||
1692 | for (i = 0; i < count; i++) { | ||
1693 | dst[i].iov_base = compat_ptr(ciov[i].iov_base); | ||
1694 | dst[i].iov_len = ciov[i].iov_len; | ||
1695 | } | ||
1696 | return 0; | ||
1697 | } | ||
1698 | #endif | ||
1699 | |||
1700 | if (count * sizeof(struct iovec) != transferred) | ||
1701 | return -EIO; | ||
1702 | |||
1703 | memcpy(dst, src, transferred); | ||
1704 | return 0; | ||
1705 | } | ||
1706 | |||
1707 | /* Make sure iov_length() won't overflow */ | ||
1708 | static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) | ||
1709 | { | ||
1710 | size_t n; | ||
1711 | u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; | ||
1712 | |||
1713 | for (n = 0; n < count; n++) { | ||
1714 | if (iov->iov_len > (size_t) max) | ||
1715 | return -ENOMEM; | ||
1716 | max -= iov->iov_len; | ||
1717 | } | ||
1718 | return 0; | ||
1719 | } | ||
1720 | |||
1721 | static int fuse_copy_ioctl_iovec(struct fuse_conn *fc, struct iovec *dst, | ||
1722 | void *src, size_t transferred, unsigned count, | ||
1723 | bool is_compat) | ||
1724 | { | ||
1725 | unsigned i; | ||
1726 | struct fuse_ioctl_iovec *fiov = src; | ||
1727 | |||
1728 | if (fc->minor < 16) { | ||
1729 | return fuse_copy_ioctl_iovec_old(dst, src, transferred, | ||
1730 | count, is_compat); | ||
1731 | } | ||
1732 | |||
1733 | if (count * sizeof(struct fuse_ioctl_iovec) != transferred) | ||
1734 | return -EIO; | ||
1735 | |||
1736 | for (i = 0; i < count; i++) { | ||
1737 | /* Did the server supply an inappropriate value? */ | ||
1738 | if (fiov[i].base != (unsigned long) fiov[i].base || | ||
1739 | fiov[i].len != (unsigned long) fiov[i].len) | ||
1740 | return -EIO; | ||
1741 | |||
1742 | dst[i].iov_base = (void __user *) (unsigned long) fiov[i].base; | ||
1743 | dst[i].iov_len = (size_t) fiov[i].len; | ||
1744 | |||
1745 | #ifdef CONFIG_COMPAT | ||
1746 | if (is_compat && | ||
1747 | (ptr_to_compat(dst[i].iov_base) != fiov[i].base || | ||
1748 | (compat_size_t) dst[i].iov_len != fiov[i].len)) | ||
1749 | return -EIO; | ||
1750 | #endif | ||
1751 | } | ||
1752 | |||
1753 | return 0; | ||
1754 | } | ||
1755 | |||
1756 | |||
1757 | /* | ||
1621 | * For ioctls, there is no generic way to determine how much memory | 1758 | * For ioctls, there is no generic way to determine how much memory |
1622 | * needs to be read and/or written. Furthermore, ioctls are allowed | 1759 | * needs to be read and/or written. Furthermore, ioctls are allowed |
1623 | * to dereference the passed pointer, so the parameter requires deep | 1760 | * to dereference the passed pointer, so the parameter requires deep |
@@ -1677,18 +1814,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
1677 | struct fuse_ioctl_out outarg; | 1814 | struct fuse_ioctl_out outarg; |
1678 | struct fuse_req *req = NULL; | 1815 | struct fuse_req *req = NULL; |
1679 | struct page **pages = NULL; | 1816 | struct page **pages = NULL; |
1680 | struct page *iov_page = NULL; | 1817 | struct iovec *iov_page = NULL; |
1681 | struct iovec *in_iov = NULL, *out_iov = NULL; | 1818 | struct iovec *in_iov = NULL, *out_iov = NULL; |
1682 | unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; | 1819 | unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; |
1683 | size_t in_size, out_size, transferred; | 1820 | size_t in_size, out_size, transferred; |
1684 | int err; | 1821 | int err; |
1685 | 1822 | ||
1823 | #if BITS_PER_LONG == 32 | ||
1824 | inarg.flags |= FUSE_IOCTL_32BIT; | ||
1825 | #else | ||
1826 | if (flags & FUSE_IOCTL_COMPAT) | ||
1827 | inarg.flags |= FUSE_IOCTL_32BIT; | ||
1828 | #endif | ||
1829 | |||
1686 | /* assume all the iovs returned by client always fits in a page */ | 1830 | /* assume all the iovs returned by client always fits in a page */ |
1687 | BUILD_BUG_ON(sizeof(struct iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); | 1831 | BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); |
1688 | 1832 | ||
1689 | err = -ENOMEM; | 1833 | err = -ENOMEM; |
1690 | pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL); | 1834 | pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL); |
1691 | iov_page = alloc_page(GFP_KERNEL); | 1835 | iov_page = (struct iovec *) __get_free_page(GFP_KERNEL); |
1692 | if (!pages || !iov_page) | 1836 | if (!pages || !iov_page) |
1693 | goto out; | 1837 | goto out; |
1694 | 1838 | ||
@@ -1697,7 +1841,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
1697 | * RETRY from server is not allowed. | 1841 | * RETRY from server is not allowed. |
1698 | */ | 1842 | */ |
1699 | if (!(flags & FUSE_IOCTL_UNRESTRICTED)) { | 1843 | if (!(flags & FUSE_IOCTL_UNRESTRICTED)) { |
1700 | struct iovec *iov = page_address(iov_page); | 1844 | struct iovec *iov = iov_page; |
1701 | 1845 | ||
1702 | iov->iov_base = (void __user *)arg; | 1846 | iov->iov_base = (void __user *)arg; |
1703 | iov->iov_len = _IOC_SIZE(cmd); | 1847 | iov->iov_len = _IOC_SIZE(cmd); |
@@ -1778,7 +1922,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
1778 | 1922 | ||
1779 | /* did it ask for retry? */ | 1923 | /* did it ask for retry? */ |
1780 | if (outarg.flags & FUSE_IOCTL_RETRY) { | 1924 | if (outarg.flags & FUSE_IOCTL_RETRY) { |
1781 | char *vaddr; | 1925 | void *vaddr; |
1782 | 1926 | ||
1783 | /* no retry if in restricted mode */ | 1927 | /* no retry if in restricted mode */ |
1784 | err = -EIO; | 1928 | err = -EIO; |
@@ -1798,18 +1942,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
1798 | in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) | 1942 | in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) |
1799 | goto out; | 1943 | goto out; |
1800 | 1944 | ||
1801 | err = -EIO; | ||
1802 | if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred) | ||
1803 | goto out; | ||
1804 | |||
1805 | /* okay, copy in iovs and retry */ | ||
1806 | vaddr = kmap_atomic(pages[0], KM_USER0); | 1945 | vaddr = kmap_atomic(pages[0], KM_USER0); |
1807 | memcpy(page_address(iov_page), vaddr, transferred); | 1946 | err = fuse_copy_ioctl_iovec(fc, iov_page, vaddr, |
1947 | transferred, in_iovs + out_iovs, | ||
1948 | (flags & FUSE_IOCTL_COMPAT) != 0); | ||
1808 | kunmap_atomic(vaddr, KM_USER0); | 1949 | kunmap_atomic(vaddr, KM_USER0); |
1950 | if (err) | ||
1951 | goto out; | ||
1809 | 1952 | ||
1810 | in_iov = page_address(iov_page); | 1953 | in_iov = iov_page; |
1811 | out_iov = in_iov + in_iovs; | 1954 | out_iov = in_iov + in_iovs; |
1812 | 1955 | ||
1956 | err = fuse_verify_ioctl_iov(in_iov, in_iovs); | ||
1957 | if (err) | ||
1958 | goto out; | ||
1959 | |||
1960 | err = fuse_verify_ioctl_iov(out_iov, out_iovs); | ||
1961 | if (err) | ||
1962 | goto out; | ||
1963 | |||
1813 | goto retry; | 1964 | goto retry; |
1814 | } | 1965 | } |
1815 | 1966 | ||
@@ -1821,8 +1972,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
1821 | out: | 1972 | out: |
1822 | if (req) | 1973 | if (req) |
1823 | fuse_put_request(fc, req); | 1974 | fuse_put_request(fc, req); |
1824 | if (iov_page) | 1975 | free_page((unsigned long) iov_page); |
1825 | __free_page(iov_page); | ||
1826 | while (num_pages) | 1976 | while (num_pages) |
1827 | __free_page(pages[--num_pages]); | 1977 | __free_page(pages[--num_pages]); |
1828 | kfree(pages); | 1978 | kfree(pages); |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 57d4a3a0f102..b788becada76 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/rwsem.h> | 21 | #include <linux/rwsem.h> |
22 | #include <linux/rbtree.h> | 22 | #include <linux/rbtree.h> |
23 | #include <linux/poll.h> | 23 | #include <linux/poll.h> |
24 | #include <linux/workqueue.h> | ||
24 | 25 | ||
25 | /** Max number of pages that can be used in a single read request */ | 26 | /** Max number of pages that can be used in a single read request */ |
26 | #define FUSE_MAX_PAGES_PER_REQ 32 | 27 | #define FUSE_MAX_PAGES_PER_REQ 32 |
@@ -53,6 +54,12 @@ extern struct mutex fuse_mutex; | |||
53 | extern unsigned max_user_bgreq; | 54 | extern unsigned max_user_bgreq; |
54 | extern unsigned max_user_congthresh; | 55 | extern unsigned max_user_congthresh; |
55 | 56 | ||
57 | /* One forget request */ | ||
58 | struct fuse_forget_link { | ||
59 | struct fuse_forget_one forget_one; | ||
60 | struct fuse_forget_link *next; | ||
61 | }; | ||
62 | |||
56 | /** FUSE inode */ | 63 | /** FUSE inode */ |
57 | struct fuse_inode { | 64 | struct fuse_inode { |
58 | /** Inode data */ | 65 | /** Inode data */ |
@@ -66,7 +73,7 @@ struct fuse_inode { | |||
66 | u64 nlookup; | 73 | u64 nlookup; |
67 | 74 | ||
68 | /** The request used for sending the FORGET message */ | 75 | /** The request used for sending the FORGET message */ |
69 | struct fuse_req *forget_req; | 76 | struct fuse_forget_link *forget; |
70 | 77 | ||
71 | /** Time in jiffies until the file attributes are valid */ | 78 | /** Time in jiffies until the file attributes are valid */ |
72 | u64 i_time; | 79 | u64 i_time; |
@@ -255,15 +262,16 @@ struct fuse_req { | |||
255 | 262 | ||
256 | /** Data for asynchronous requests */ | 263 | /** Data for asynchronous requests */ |
257 | union { | 264 | union { |
258 | struct fuse_forget_in forget_in; | ||
259 | struct { | 265 | struct { |
260 | struct fuse_release_in in; | 266 | union { |
267 | struct fuse_release_in in; | ||
268 | struct work_struct work; | ||
269 | }; | ||
261 | struct path path; | 270 | struct path path; |
262 | } release; | 271 | } release; |
263 | struct fuse_init_in init_in; | 272 | struct fuse_init_in init_in; |
264 | struct fuse_init_out init_out; | 273 | struct fuse_init_out init_out; |
265 | struct cuse_init_in cuse_init_in; | 274 | struct cuse_init_in cuse_init_in; |
266 | struct cuse_init_out cuse_init_out; | ||
267 | struct { | 275 | struct { |
268 | struct fuse_read_in in; | 276 | struct fuse_read_in in; |
269 | u64 attr_ver; | 277 | u64 attr_ver; |
@@ -369,6 +377,13 @@ struct fuse_conn { | |||
369 | /** Pending interrupts */ | 377 | /** Pending interrupts */ |
370 | struct list_head interrupts; | 378 | struct list_head interrupts; |
371 | 379 | ||
380 | /** Queue of pending forgets */ | ||
381 | struct fuse_forget_link forget_list_head; | ||
382 | struct fuse_forget_link *forget_list_tail; | ||
383 | |||
384 | /** Batching of FORGET requests (positive indicates FORGET batch) */ | ||
385 | int forget_batch; | ||
386 | |||
372 | /** Flag indicating if connection is blocked. This will be | 387 | /** Flag indicating if connection is blocked. This will be |
373 | the case before the INIT reply is received, and if there | 388 | the case before the INIT reply is received, and if there |
374 | are too many outstading backgrounds requests */ | 389 | are too many outstading backgrounds requests */ |
@@ -543,8 +558,10 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, | |||
543 | /** | 558 | /** |
544 | * Send FORGET command | 559 | * Send FORGET command |
545 | */ | 560 | */ |
546 | void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, | 561 | void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, |
547 | u64 nodeid, u64 nlookup); | 562 | u64 nodeid, u64 nlookup); |
563 | |||
564 | struct fuse_forget_link *fuse_alloc_forget(void); | ||
548 | 565 | ||
549 | /** | 566 | /** |
550 | * Initialize READ or READDIR request | 567 | * Initialize READ or READDIR request |
@@ -656,11 +673,6 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req); | |||
656 | void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req); | 673 | void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req); |
657 | 674 | ||
658 | /** | 675 | /** |
659 | * Send a request with no reply | ||
660 | */ | ||
661 | void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); | ||
662 | |||
663 | /** | ||
664 | * Send a request in the background | 676 | * Send a request in the background |
665 | */ | 677 | */ |
666 | void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req); | 678 | void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req); |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index da9e6e11374c..38f84cd48b67 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -71,6 +71,11 @@ struct fuse_mount_data { | |||
71 | unsigned blksize; | 71 | unsigned blksize; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | struct fuse_forget_link *fuse_alloc_forget() | ||
75 | { | ||
76 | return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL); | ||
77 | } | ||
78 | |||
74 | static struct inode *fuse_alloc_inode(struct super_block *sb) | 79 | static struct inode *fuse_alloc_inode(struct super_block *sb) |
75 | { | 80 | { |
76 | struct inode *inode; | 81 | struct inode *inode; |
@@ -90,8 +95,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
90 | INIT_LIST_HEAD(&fi->queued_writes); | 95 | INIT_LIST_HEAD(&fi->queued_writes); |
91 | INIT_LIST_HEAD(&fi->writepages); | 96 | INIT_LIST_HEAD(&fi->writepages); |
92 | init_waitqueue_head(&fi->page_waitq); | 97 | init_waitqueue_head(&fi->page_waitq); |
93 | fi->forget_req = fuse_request_alloc(); | 98 | fi->forget = fuse_alloc_forget(); |
94 | if (!fi->forget_req) { | 99 | if (!fi->forget) { |
95 | kmem_cache_free(fuse_inode_cachep, inode); | 100 | kmem_cache_free(fuse_inode_cachep, inode); |
96 | return NULL; | 101 | return NULL; |
97 | } | 102 | } |
@@ -99,27 +104,20 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
99 | return inode; | 104 | return inode; |
100 | } | 105 | } |
101 | 106 | ||
102 | static void fuse_destroy_inode(struct inode *inode) | 107 | static void fuse_i_callback(struct rcu_head *head) |
103 | { | 108 | { |
104 | struct fuse_inode *fi = get_fuse_inode(inode); | 109 | struct inode *inode = container_of(head, struct inode, i_rcu); |
105 | BUG_ON(!list_empty(&fi->write_files)); | 110 | INIT_LIST_HEAD(&inode->i_dentry); |
106 | BUG_ON(!list_empty(&fi->queued_writes)); | ||
107 | if (fi->forget_req) | ||
108 | fuse_request_free(fi->forget_req); | ||
109 | kmem_cache_free(fuse_inode_cachep, inode); | 111 | kmem_cache_free(fuse_inode_cachep, inode); |
110 | } | 112 | } |
111 | 113 | ||
112 | void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, | 114 | static void fuse_destroy_inode(struct inode *inode) |
113 | u64 nodeid, u64 nlookup) | ||
114 | { | 115 | { |
115 | struct fuse_forget_in *inarg = &req->misc.forget_in; | 116 | struct fuse_inode *fi = get_fuse_inode(inode); |
116 | inarg->nlookup = nlookup; | 117 | BUG_ON(!list_empty(&fi->write_files)); |
117 | req->in.h.opcode = FUSE_FORGET; | 118 | BUG_ON(!list_empty(&fi->queued_writes)); |
118 | req->in.h.nodeid = nodeid; | 119 | kfree(fi->forget); |
119 | req->in.numargs = 1; | 120 | call_rcu(&inode->i_rcu, fuse_i_callback); |
120 | req->in.args[0].size = sizeof(struct fuse_forget_in); | ||
121 | req->in.args[0].value = inarg; | ||
122 | fuse_request_send_noreply(fc, req); | ||
123 | } | 121 | } |
124 | 122 | ||
125 | static void fuse_evict_inode(struct inode *inode) | 123 | static void fuse_evict_inode(struct inode *inode) |
@@ -129,8 +127,8 @@ static void fuse_evict_inode(struct inode *inode) | |||
129 | if (inode->i_sb->s_flags & MS_ACTIVE) { | 127 | if (inode->i_sb->s_flags & MS_ACTIVE) { |
130 | struct fuse_conn *fc = get_fuse_conn(inode); | 128 | struct fuse_conn *fc = get_fuse_conn(inode); |
131 | struct fuse_inode *fi = get_fuse_inode(inode); | 129 | struct fuse_inode *fi = get_fuse_inode(inode); |
132 | fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup); | 130 | fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup); |
133 | fi->forget_req = NULL; | 131 | fi->forget = NULL; |
134 | } | 132 | } |
135 | } | 133 | } |
136 | 134 | ||
@@ -534,6 +532,7 @@ void fuse_conn_init(struct fuse_conn *fc) | |||
534 | INIT_LIST_HEAD(&fc->interrupts); | 532 | INIT_LIST_HEAD(&fc->interrupts); |
535 | INIT_LIST_HEAD(&fc->bg_queue); | 533 | INIT_LIST_HEAD(&fc->bg_queue); |
536 | INIT_LIST_HEAD(&fc->entry); | 534 | INIT_LIST_HEAD(&fc->entry); |
535 | fc->forget_list_tail = &fc->forget_list_head; | ||
537 | atomic_set(&fc->num_waiting, 0); | 536 | atomic_set(&fc->num_waiting, 0); |
538 | fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; | 537 | fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; |
539 | fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; | 538 | fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; |
@@ -618,10 +617,8 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, | |||
618 | goto out_iput; | 617 | goto out_iput; |
619 | 618 | ||
620 | entry = d_obtain_alias(inode); | 619 | entry = d_obtain_alias(inode); |
621 | if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) { | 620 | if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) |
622 | entry->d_op = &fuse_dentry_operations; | ||
623 | fuse_invalidate_entry_cache(entry); | 621 | fuse_invalidate_entry_cache(entry); |
624 | } | ||
625 | 622 | ||
626 | return entry; | 623 | return entry; |
627 | 624 | ||
@@ -640,8 +637,10 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | |||
640 | u64 nodeid; | 637 | u64 nodeid; |
641 | u32 generation; | 638 | u32 generation; |
642 | 639 | ||
643 | if (*max_len < len) | 640 | if (*max_len < len) { |
641 | *max_len = len; | ||
644 | return 255; | 642 | return 255; |
643 | } | ||
645 | 644 | ||
646 | nodeid = get_fuse_inode(inode)->nodeid; | 645 | nodeid = get_fuse_inode(inode)->nodeid; |
647 | generation = inode->i_generation; | 646 | generation = inode->i_generation; |
@@ -720,10 +719,8 @@ static struct dentry *fuse_get_parent(struct dentry *child) | |||
720 | } | 719 | } |
721 | 720 | ||
722 | parent = d_obtain_alias(inode); | 721 | parent = d_obtain_alias(inode); |
723 | if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) { | 722 | if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) |
724 | parent->d_op = &fuse_dentry_operations; | ||
725 | fuse_invalidate_entry_cache(parent); | 723 | fuse_invalidate_entry_cache(parent); |
726 | } | ||
727 | 724 | ||
728 | return parent; | 725 | return parent; |
729 | } | 726 | } |
@@ -873,7 +870,6 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) | |||
873 | 870 | ||
874 | fc->bdi.name = "fuse"; | 871 | fc->bdi.name = "fuse"; |
875 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; | 872 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; |
876 | fc->bdi.unplug_io_fn = default_unplug_io_fn; | ||
877 | /* fuse does it's own writeback accounting */ | 873 | /* fuse does it's own writeback accounting */ |
878 | fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; | 874 | fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; |
879 | 875 | ||
@@ -925,6 +921,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
925 | if (sb->s_flags & MS_MANDLOCK) | 921 | if (sb->s_flags & MS_MANDLOCK) |
926 | goto err; | 922 | goto err; |
927 | 923 | ||
924 | sb->s_flags &= ~MS_NOSEC; | ||
925 | |||
928 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) | 926 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) |
929 | goto err; | 927 | goto err; |
930 | 928 | ||
@@ -990,6 +988,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
990 | iput(root); | 988 | iput(root); |
991 | goto err_put_conn; | 989 | goto err_put_conn; |
992 | } | 990 | } |
991 | /* only now - we want root dentry with NULL ->d_op */ | ||
992 | sb->s_d_op = &fuse_dentry_operations; | ||
993 | 993 | ||
994 | init_req = fuse_request_alloc(); | 994 | init_req = fuse_request_alloc(); |
995 | if (!init_req) | 995 | if (!init_req) |
@@ -1041,11 +1041,11 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
1041 | return err; | 1041 | return err; |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | static int fuse_get_sb(struct file_system_type *fs_type, | 1044 | static struct dentry *fuse_mount(struct file_system_type *fs_type, |
1045 | int flags, const char *dev_name, | 1045 | int flags, const char *dev_name, |
1046 | void *raw_data, struct vfsmount *mnt) | 1046 | void *raw_data) |
1047 | { | 1047 | { |
1048 | return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super, mnt); | 1048 | return mount_nodev(fs_type, flags, raw_data, fuse_fill_super); |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | static void fuse_kill_sb_anon(struct super_block *sb) | 1051 | static void fuse_kill_sb_anon(struct super_block *sb) |
@@ -1065,17 +1065,16 @@ static struct file_system_type fuse_fs_type = { | |||
1065 | .owner = THIS_MODULE, | 1065 | .owner = THIS_MODULE, |
1066 | .name = "fuse", | 1066 | .name = "fuse", |
1067 | .fs_flags = FS_HAS_SUBTYPE, | 1067 | .fs_flags = FS_HAS_SUBTYPE, |
1068 | .get_sb = fuse_get_sb, | 1068 | .mount = fuse_mount, |
1069 | .kill_sb = fuse_kill_sb_anon, | 1069 | .kill_sb = fuse_kill_sb_anon, |
1070 | }; | 1070 | }; |
1071 | 1071 | ||
1072 | #ifdef CONFIG_BLOCK | 1072 | #ifdef CONFIG_BLOCK |
1073 | static int fuse_get_sb_blk(struct file_system_type *fs_type, | 1073 | static struct dentry *fuse_mount_blk(struct file_system_type *fs_type, |
1074 | int flags, const char *dev_name, | 1074 | int flags, const char *dev_name, |
1075 | void *raw_data, struct vfsmount *mnt) | 1075 | void *raw_data) |
1076 | { | 1076 | { |
1077 | return get_sb_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super, | 1077 | return mount_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super); |
1078 | mnt); | ||
1079 | } | 1078 | } |
1080 | 1079 | ||
1081 | static void fuse_kill_sb_blk(struct super_block *sb) | 1080 | static void fuse_kill_sb_blk(struct super_block *sb) |
@@ -1094,7 +1093,7 @@ static void fuse_kill_sb_blk(struct super_block *sb) | |||
1094 | static struct file_system_type fuseblk_fs_type = { | 1093 | static struct file_system_type fuseblk_fs_type = { |
1095 | .owner = THIS_MODULE, | 1094 | .owner = THIS_MODULE, |
1096 | .name = "fuseblk", | 1095 | .name = "fuseblk", |
1097 | .get_sb = fuse_get_sb_blk, | 1096 | .mount = fuse_mount_blk, |
1098 | .kill_sb = fuse_kill_sb_blk, | 1097 | .kill_sb = fuse_kill_sb_blk, |
1099 | .fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE, | 1098 | .fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE, |
1100 | }; | 1099 | }; |