1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include "dev.h" 4 #include "fuse_i.h" 5 6 void fuse_end_polls(struct fuse_conn *fc) 7 { 8 struct rb_node *p; 9 10 spin_lock(&fc->lock); 11 p = rb_first(&fc->polled_files); 12 13 while (p) { 14 struct fuse_file *ff; 15 ff = rb_entry(p, struct fuse_file, polled_node); 16 wake_up_interruptible_all(&ff->poll_wait); 17 18 p = rb_next(p); 19 } 20 spin_unlock(&fc->lock); 21 } 22 23 /* 24 * All files which have been polled are linked to RB tree 25 * fuse_conn->polled_files which is indexed by kh. Walk the tree and 26 * find the matching one. 27 */ 28 static struct rb_node **fuse_find_polled_node(struct fuse_conn *fc, u64 kh, 29 struct rb_node **parent_out) 30 { 31 struct rb_node **link = &fc->polled_files.rb_node; 32 struct rb_node *last = NULL; 33 34 while (*link) { 35 struct fuse_file *ff; 36 37 last = *link; 38 ff = rb_entry(last, struct fuse_file, polled_node); 39 40 if (kh < ff->kh) 41 link = &last->rb_left; 42 else if (kh > ff->kh) 43 link = &last->rb_right; 44 else 45 return link; 46 } 47 48 if (parent_out) 49 *parent_out = last; 50 return link; 51 } 52 53 /* 54 * The file is about to be polled. Make sure it's on the polled_files 55 * RB tree. Note that files once added to the polled_files tree are 56 * not removed before the file is released. This is because a file 57 * polled once is likely to be polled again. 58 */ 59 static void fuse_register_polled_file(struct fuse_conn *fc, 60 struct fuse_file *ff) 61 { 62 spin_lock(&fc->lock); 63 if (RB_EMPTY_NODE(&ff->polled_node)) { 64 struct rb_node **link, *parent; 65 66 link = fuse_find_polled_node(fc, ff->kh, &parent); 67 BUG_ON(*link); 68 rb_link_node(&ff->polled_node, parent, link); 69 rb_insert_color(&ff->polled_node, &fc->polled_files); 70 } 71 spin_unlock(&fc->lock); 72 } 73 74 __poll_t fuse_file_poll(struct file *file, poll_table *wait) 75 { 76 struct fuse_file *ff = file->private_data; 77 struct fuse_mount *fm = ff->fm; 78 struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh }; 79 struct fuse_poll_out outarg; 80 FUSE_ARGS(args); 81 int err; 82 83 if (fm->fc->no_poll) 84 return DEFAULT_POLLMASK; 85 86 poll_wait(file, &ff->poll_wait, wait); 87 inarg.events = mangle_poll(poll_requested_events(wait)); 88 89 /* 90 * Ask for notification iff there's someone waiting for it. 91 * The client may ignore the flag and always notify. 92 */ 93 if (waitqueue_active(&ff->poll_wait)) { 94 inarg.flags |= FUSE_POLL_SCHEDULE_NOTIFY; 95 fuse_register_polled_file(fm->fc, ff); 96 } 97 98 args.opcode = FUSE_POLL; 99 args.nodeid = ff->nodeid; 100 args.in_numargs = 1; 101 args.in_args[0].size = sizeof(inarg); 102 args.in_args[0].value = &inarg; 103 args.out_numargs = 1; 104 args.out_args[0].size = sizeof(outarg); 105 args.out_args[0].value = &outarg; 106 err = fuse_simple_request(fm, &args); 107 108 if (!err) 109 return demangle_poll(outarg.revents); 110 if (err == -ENOSYS) { 111 fm->fc->no_poll = 1; 112 return DEFAULT_POLLMASK; 113 } 114 return EPOLLERR; 115 } 116 EXPORT_SYMBOL_GPL(fuse_file_poll); 117 118 /* 119 * This is called from fuse_handle_notify() on FUSE_NOTIFY_POLL and 120 * wakes up the poll waiters. 121 */ 122 int fuse_notify_poll_wakeup(struct fuse_conn *fc, 123 struct fuse_notify_poll_wakeup_out *outarg) 124 { 125 u64 kh = outarg->kh; 126 struct rb_node **link; 127 128 spin_lock(&fc->lock); 129 130 link = fuse_find_polled_node(fc, kh, NULL); 131 if (*link) { 132 struct fuse_file *ff; 133 134 ff = rb_entry(*link, struct fuse_file, polled_node); 135 wake_up_interruptible_sync(&ff->poll_wait); 136 } 137 138 spin_unlock(&fc->lock); 139 return 0; 140 } 141 142