Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: clean up annotations of fc->lock
fuse: fix sparse warning in ioctl
fuse: update interface version
fuse: add fuse_conn->release()
fuse: separate out fuse_conn_init() from new_conn()
fuse: add fuse_ prefix to several functions
fuse: implement poll support
fuse: implement unsolicited notification
fuse: add file kernel handle
fuse: implement ioctl support
fuse: don't let fuse_req->end() put the base reference
fuse: move FUSE_MINOR to miscdevice.h
fuse: style fixes

+783 -202
+4 -2
fs/fuse/control.c
··· 1 1 /* 2 2 FUSE: Filesystem in Userspace 3 - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 3 + Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 4 5 5 This program can be distributed under the terms of the GNU GPL. 6 6 See the file COPYING. ··· 48 48 size_t size; 49 49 50 50 if (!*ppos) { 51 + long value; 51 52 struct fuse_conn *fc = fuse_ctl_file_conn_get(file); 52 53 if (!fc) 53 54 return 0; 54 55 55 - file->private_data=(void *)(long)atomic_read(&fc->num_waiting); 56 + value = atomic_read(&fc->num_waiting); 57 + file->private_data = (void *)value; 56 58 fuse_conn_put(fc); 57 59 } 58 60 size = sprintf(tmp, "%ld\n", (long)file->private_data);
+83 -30
fs/fuse/dev.c
··· 1 1 /* 2 2 FUSE: Filesystem in Userspace 3 - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 3 + Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 4 5 5 This program can be distributed under the terms of the GNU GPL. 6 6 See the file COPYING. ··· 269 269 * Called with fc->lock, unlocks it 270 270 */ 271 271 static void request_end(struct fuse_conn *fc, struct fuse_req *req) 272 - __releases(fc->lock) 272 + __releases(&fc->lock) 273 273 { 274 274 void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 275 275 req->end = NULL; ··· 293 293 wake_up(&req->waitq); 294 294 if (end) 295 295 end(fc, req); 296 - else 297 - fuse_put_request(fc, req); 296 + fuse_put_request(fc, req); 298 297 } 299 298 300 299 static void wait_answer_interruptible(struct fuse_conn *fc, 301 300 struct fuse_req *req) 302 - __releases(fc->lock) __acquires(fc->lock) 301 + __releases(&fc->lock) 302 + __acquires(&fc->lock) 303 303 { 304 304 if (signal_pending(current)) 305 305 return; ··· 317 317 } 318 318 319 319 static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) 320 - __releases(fc->lock) __acquires(fc->lock) 320 + __releases(&fc->lock) 321 + __acquires(&fc->lock) 321 322 { 322 323 if (!fc->no_interrupt) { 323 324 /* Any signal may interrupt this */ ··· 381 380 } 382 381 } 383 382 384 - void request_send(struct fuse_conn *fc, struct fuse_req *req) 383 + void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 385 384 { 386 385 req->isreply = 1; 387 386 spin_lock(&fc->lock); ··· 400 399 spin_unlock(&fc->lock); 401 400 } 402 401 403 - static void request_send_nowait_locked(struct fuse_conn *fc, 404 - struct fuse_req *req) 402 + static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 403 + struct fuse_req *req) 405 404 { 406 405 req->background = 1; 407 406 fc->num_background++; ··· 415 414 flush_bg_queue(fc); 416 415 } 417 416 418 - static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) 417 + static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) 419 418 { 420 419 spin_lock(&fc->lock); 421 420 if (fc->connected) { 422 - request_send_nowait_locked(fc, req); 421 + fuse_request_send_nowait_locked(fc, req); 423 422 spin_unlock(&fc->lock); 424 423 } else { 425 424 req->out.h.error = -ENOTCONN; ··· 427 426 } 428 427 } 429 428 430 - void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) 429 + void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) 431 430 { 432 431 req->isreply = 0; 433 - request_send_nowait(fc, req); 432 + fuse_request_send_nowait(fc, req); 434 433 } 435 434 436 - void request_send_background(struct fuse_conn *fc, struct fuse_req *req) 435 + void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) 437 436 { 438 437 req->isreply = 1; 439 - request_send_nowait(fc, req); 438 + fuse_request_send_nowait(fc, req); 440 439 } 441 440 442 441 /* ··· 444 443 * 445 444 * fc->connected must have been checked previously 446 445 */ 447 - void request_send_background_locked(struct fuse_conn *fc, struct fuse_req *req) 446 + void fuse_request_send_background_locked(struct fuse_conn *fc, 447 + struct fuse_req *req) 448 448 { 449 449 req->isreply = 1; 450 - request_send_nowait_locked(fc, req); 450 + fuse_request_send_nowait_locked(fc, req); 451 451 } 452 452 453 453 /* ··· 541 539 BUG_ON(!cs->nr_segs); 542 540 cs->seglen = cs->iov[0].iov_len; 543 541 cs->addr = (unsigned long) cs->iov[0].iov_base; 544 - cs->iov ++; 545 - cs->nr_segs --; 542 + cs->iov++; 543 + cs->nr_segs--; 546 544 } 547 545 down_read(&current->mm->mmap_sem); 548 546 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, ··· 591 589 kunmap_atomic(mapaddr, KM_USER1); 592 590 } 593 591 while (count) { 594 - int err; 595 - if (!cs->len && (err = fuse_copy_fill(cs))) 596 - return err; 592 + if (!cs->len) { 593 + int err = fuse_copy_fill(cs); 594 + if (err) 595 + return err; 596 + } 597 597 if (page) { 598 598 void *mapaddr = kmap_atomic(page, KM_USER1); 599 599 void *buf = mapaddr + offset; ··· 635 631 static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 636 632 { 637 633 while (size) { 638 - int err; 639 - if (!cs->len && (err = fuse_copy_fill(cs))) 640 - return err; 634 + if (!cs->len) { 635 + int err = fuse_copy_fill(cs); 636 + if (err) 637 + return err; 638 + } 641 639 fuse_copy_do(cs, &val, &size); 642 640 } 643 641 return 0; ··· 670 664 671 665 /* Wait until a request is available on the pending list */ 672 666 static void request_wait(struct fuse_conn *fc) 667 + __releases(&fc->lock) 668 + __acquires(&fc->lock) 673 669 { 674 670 DECLARE_WAITQUEUE(wait, current); 675 671 ··· 699 691 */ 700 692 static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, 701 693 const struct iovec *iov, unsigned long nr_segs) 702 - __releases(fc->lock) 694 + __releases(&fc->lock) 703 695 { 704 696 struct fuse_copy_state cs; 705 697 struct fuse_in_header ih; ··· 821 813 return err; 822 814 } 823 815 816 + static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 817 + struct fuse_copy_state *cs) 818 + { 819 + struct fuse_notify_poll_wakeup_out outarg; 820 + int err; 821 + 822 + if (size != sizeof(outarg)) 823 + return -EINVAL; 824 + 825 + err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 826 + if (err) 827 + return err; 828 + 829 + return fuse_notify_poll_wakeup(fc, &outarg); 830 + } 831 + 832 + static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 833 + unsigned int size, struct fuse_copy_state *cs) 834 + { 835 + switch (code) { 836 + case FUSE_NOTIFY_POLL: 837 + return fuse_notify_poll(fc, size, cs); 838 + 839 + default: 840 + return -EINVAL; 841 + } 842 + } 843 + 824 844 /* Look up request on processing list by unique ID */ 825 845 static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) 826 846 { ··· 912 876 err = fuse_copy_one(&cs, &oh, sizeof(oh)); 913 877 if (err) 914 878 goto err_finish; 879 + 915 880 err = -EINVAL; 916 - if (!oh.unique || oh.error <= -1000 || oh.error > 0 || 917 - oh.len != nbytes) 881 + if (oh.len != nbytes) 882 + goto err_finish; 883 + 884 + /* 885 + * Zero oh.unique indicates unsolicited notification message 886 + * and error contains notification code. 887 + */ 888 + if (!oh.unique) { 889 + err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), &cs); 890 + fuse_copy_finish(&cs); 891 + return err ? err : nbytes; 892 + } 893 + 894 + err = -EINVAL; 895 + if (oh.error <= -1000 || oh.error > 0) 918 896 goto err_finish; 919 897 920 898 spin_lock(&fc->lock); ··· 1016 966 * This function releases and reacquires fc->lock 1017 967 */ 1018 968 static void end_requests(struct fuse_conn *fc, struct list_head *head) 969 + __releases(&fc->lock) 970 + __acquires(&fc->lock) 1019 971 { 1020 972 while (!list_empty(head)) { 1021 973 struct fuse_req *req; ··· 1040 988 * locked). 1041 989 */ 1042 990 static void end_io_requests(struct fuse_conn *fc) 1043 - __releases(fc->lock) __acquires(fc->lock) 991 + __releases(&fc->lock) 992 + __acquires(&fc->lock) 1044 993 { 1045 994 while (!list_empty(&fc->io)) { 1046 995 struct fuse_req *req = ··· 1055 1002 wake_up(&req->waitq); 1056 1003 if (end) { 1057 1004 req->end = NULL; 1058 - /* The end function will consume this reference */ 1059 1005 __fuse_get_request(req); 1060 1006 spin_unlock(&fc->lock); 1061 1007 wait_event(req->waitq, !req->locked); 1062 1008 end(fc, req); 1009 + fuse_put_request(fc, req); 1063 1010 spin_lock(&fc->lock); 1064 1011 } 1065 1012 }
+25 -23
fs/fuse/dir.c
··· 1 1 /* 2 2 FUSE: Filesystem in Userspace 3 - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 3 + Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 4 5 5 This program can be distributed under the terms of the GNU GPL. 6 6 See the file COPYING. ··· 189 189 parent = dget_parent(entry); 190 190 fuse_lookup_init(fc, req, get_node_id(parent->d_inode), 191 191 &entry->d_name, &outarg); 192 - request_send(fc, req); 192 + fuse_request_send(fc, req); 193 193 dput(parent); 194 194 err = req->out.h.error; 195 195 fuse_put_request(fc, req); ··· 204 204 return 0; 205 205 } 206 206 spin_lock(&fc->lock); 207 - fi->nlookup ++; 207 + fi->nlookup++; 208 208 spin_unlock(&fc->lock); 209 209 } 210 210 fuse_put_request(fc, forget_req); ··· 283 283 attr_version = fuse_get_attr_version(fc); 284 284 285 285 fuse_lookup_init(fc, req, nodeid, name, outarg); 286 - request_send(fc, req); 286 + fuse_request_send(fc, req); 287 287 err = req->out.h.error; 288 288 fuse_put_request(fc, req); 289 289 /* Zero nodeid is same as -ENOENT, but with valid timeout */ ··· 369 369 { 370 370 fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE); 371 371 ff->reserved_req->force = 1; 372 - request_send(fc, ff->reserved_req); 372 + fuse_request_send(fc, ff->reserved_req); 373 373 fuse_put_request(fc, ff->reserved_req); 374 374 kfree(ff); 375 375 } ··· 408 408 goto out_put_forget_req; 409 409 410 410 err = -ENOMEM; 411 - ff = fuse_file_alloc(); 411 + ff = fuse_file_alloc(fc); 412 412 if (!ff) 413 413 goto out_put_request; 414 414 ··· 432 432 req->out.args[0].value = &outentry; 433 433 req->out.args[1].size = sizeof(outopen); 434 434 req->out.args[1].value = &outopen; 435 - request_send(fc, req); 435 + fuse_request_send(fc, req); 436 436 err = req->out.h.error; 437 437 if (err) { 438 438 if (err == -ENOSYS) ··· 502 502 else 503 503 req->out.args[0].size = sizeof(outarg); 504 504 req->out.args[0].value = &outarg; 505 - request_send(fc, req); 505 + fuse_request_send(fc, req); 506 506 err = req->out.h.error; 507 507 fuse_put_request(fc, req); 508 508 if (err) ··· 631 631 req->in.numargs = 1; 632 632 req->in.args[0].size = entry->d_name.len + 1; 633 633 req->in.args[0].value = entry->d_name.name; 634 - request_send(fc, req); 634 + fuse_request_send(fc, req); 635 635 err = req->out.h.error; 636 636 fuse_put_request(fc, req); 637 637 if (!err) { 638 638 struct inode *inode = entry->d_inode; 639 639 640 - /* Set nlink to zero so the inode can be cleared, if 641 - the inode does have more links this will be 642 - discovered at the next lookup/getattr */ 640 + /* 641 + * Set nlink to zero so the inode can be cleared, if the inode 642 + * does have more links this will be discovered at the next 643 + * lookup/getattr. 644 + */ 643 645 clear_nlink(inode); 644 646 fuse_invalidate_attr(inode); 645 647 fuse_invalidate_attr(dir); ··· 664 662 req->in.numargs = 1; 665 663 req->in.args[0].size = entry->d_name.len + 1; 666 664 req->in.args[0].value = entry->d_name.name; 667 - request_send(fc, req); 665 + fuse_request_send(fc, req); 668 666 err = req->out.h.error; 669 667 fuse_put_request(fc, req); 670 668 if (!err) { ··· 697 695 req->in.args[1].value = oldent->d_name.name; 698 696 req->in.args[2].size = newent->d_name.len + 1; 699 697 req->in.args[2].value = newent->d_name.name; 700 - request_send(fc, req); 698 + fuse_request_send(fc, req); 701 699 err = req->out.h.error; 702 700 fuse_put_request(fc, req); 703 701 if (!err) { ··· 813 811 else 814 812 req->out.args[0].size = sizeof(outarg); 815 813 req->out.args[0].value = &outarg; 816 - request_send(fc, req); 814 + fuse_request_send(fc, req); 817 815 err = req->out.h.error; 818 816 fuse_put_request(fc, req); 819 817 if (!err) { ··· 913 911 req->in.numargs = 1; 914 912 req->in.args[0].size = sizeof(inarg); 915 913 req->in.args[0].value = &inarg; 916 - request_send(fc, req); 914 + fuse_request_send(fc, req); 917 915 err = req->out.h.error; 918 916 fuse_put_request(fc, req); 919 917 if (err == -ENOSYS) { ··· 1035 1033 req->num_pages = 1; 1036 1034 req->pages[0] = page; 1037 1035 fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); 1038 - request_send(fc, req); 1036 + fuse_request_send(fc, req); 1039 1037 nbytes = req->out.args[0].size; 1040 1038 err = req->out.h.error; 1041 1039 fuse_put_request(fc, req); ··· 1069 1067 req->out.numargs = 1; 1070 1068 req->out.args[0].size = PAGE_SIZE - 1; 1071 1069 req->out.args[0].value = link; 1072 - request_send(fc, req); 1070 + fuse_request_send(fc, req); 1073 1071 if (req->out.h.error) { 1074 1072 free_page((unsigned long) link); 1075 1073 link = ERR_PTR(req->out.h.error); ··· 1275 1273 else 1276 1274 req->out.args[0].size = sizeof(outarg); 1277 1275 req->out.args[0].value = &outarg; 1278 - request_send(fc, req); 1276 + fuse_request_send(fc, req); 1279 1277 err = req->out.h.error; 1280 1278 fuse_put_request(fc, req); 1281 1279 if (err) { ··· 1369 1367 req->in.args[1].value = name; 1370 1368 req->in.args[2].size = size; 1371 1369 req->in.args[2].value = value; 1372 - request_send(fc, req); 1370 + fuse_request_send(fc, req); 1373 1371 err = req->out.h.error; 1374 1372 fuse_put_request(fc, req); 1375 1373 if (err == -ENOSYS) { ··· 1415 1413 req->out.args[0].size = sizeof(outarg); 1416 1414 req->out.args[0].value = &outarg; 1417 1415 } 1418 - request_send(fc, req); 1416 + fuse_request_send(fc, req); 1419 1417 ret = req->out.h.error; 1420 1418 if (!ret) 1421 1419 ret = size ? req->out.args[0].size : outarg.size; ··· 1465 1463 req->out.args[0].size = sizeof(outarg); 1466 1464 req->out.args[0].value = &outarg; 1467 1465 } 1468 - request_send(fc, req); 1466 + fuse_request_send(fc, req); 1469 1467 ret = req->out.h.error; 1470 1468 if (!ret) 1471 1469 ret = size ? req->out.args[0].size : outarg.size; ··· 1498 1496 req->in.numargs = 1; 1499 1497 req->in.args[0].size = strlen(name) + 1; 1500 1498 req->in.args[0].value = name; 1501 - request_send(fc, req); 1499 + fuse_request_send(fc, req); 1502 1500 err = req->out.h.error; 1503 1501 fuse_put_request(fc, req); 1504 1502 if (err == -ENOSYS) {
+438 -19
fs/fuse/file.c
··· 1 1 /* 2 2 FUSE: Filesystem in Userspace 3 - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 3 + Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 4 5 5 This program can be distributed under the terms of the GNU GPL. 6 6 See the file COPYING. ··· 39 39 req->out.numargs = 1; 40 40 req->out.args[0].size = sizeof(*outargp); 41 41 req->out.args[0].value = outargp; 42 - request_send(fc, req); 42 + fuse_request_send(fc, req); 43 43 err = req->out.h.error; 44 44 fuse_put_request(fc, req); 45 45 46 46 return err; 47 47 } 48 48 49 - struct fuse_file *fuse_file_alloc(void) 49 + struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) 50 50 { 51 51 struct fuse_file *ff; 52 52 ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL); ··· 58 58 } else { 59 59 INIT_LIST_HEAD(&ff->write_entry); 60 60 atomic_set(&ff->count, 0); 61 + spin_lock(&fc->lock); 62 + ff->kh = ++fc->khctr; 63 + spin_unlock(&fc->lock); 61 64 } 65 + RB_CLEAR_NODE(&ff->polled_node); 66 + init_waitqueue_head(&ff->poll_wait); 62 67 } 63 68 return ff; 64 69 } ··· 84 79 { 85 80 dput(req->misc.release.dentry); 86 81 mntput(req->misc.release.vfsmount); 87 - fuse_put_request(fc, req); 88 82 } 89 83 90 84 static void fuse_file_put(struct fuse_file *ff) ··· 93 89 struct inode *inode = req->misc.release.dentry->d_inode; 94 90 struct fuse_conn *fc = get_fuse_conn(inode); 95 91 req->end = fuse_release_end; 96 - request_send_background(fc, req); 92 + fuse_request_send_background(fc, req); 97 93 kfree(ff); 98 94 } 99 95 } ··· 113 109 114 110 int fuse_open_common(struct inode *inode, struct file *file, int isdir) 115 111 { 112 + struct fuse_conn *fc = get_fuse_conn(inode); 116 113 struct fuse_open_out outarg; 117 114 struct fuse_file *ff; 118 115 int err; ··· 126 121 if (err) 127 122 return err; 128 123 129 - ff = fuse_file_alloc(); 124 + ff = fuse_file_alloc(fc); 130 125 if (!ff) 131 126 return -ENOMEM; 132 127 ··· 172 167 173 168 spin_lock(&fc->lock); 174 169 list_del(&ff->write_entry); 170 + if (!RB_EMPTY_NODE(&ff->polled_node)) 171 + rb_erase(&ff->polled_node, &fc->polled_files); 175 172 spin_unlock(&fc->lock); 173 + 174 + wake_up_interruptible_sync(&ff->poll_wait); 176 175 /* 177 176 * Normally this will send the RELEASE request, 178 177 * however if some asynchronous READ or WRITE requests ··· 289 280 req->in.args[0].size = sizeof(inarg); 290 281 req->in.args[0].value = &inarg; 291 282 req->force = 1; 292 - request_send(fc, req); 283 + fuse_request_send(fc, req); 293 284 err = req->out.h.error; 294 285 fuse_put_request(fc, req); 295 286 if (err == -ENOSYS) { ··· 353 344 req->in.numargs = 1; 354 345 req->in.args[0].size = sizeof(inarg); 355 346 req->in.args[0].value = &inarg; 356 - request_send(fc, req); 347 + fuse_request_send(fc, req); 357 348 err = req->out.h.error; 358 349 fuse_put_request(fc, req); 359 350 if (err == -ENOSYS) { ··· 405 396 inarg->read_flags |= FUSE_READ_LOCKOWNER; 406 397 inarg->lock_owner = fuse_lock_owner_id(fc, owner); 407 398 } 408 - request_send(fc, req); 399 + fuse_request_send(fc, req); 409 400 return req->out.args[0].size; 410 401 } 411 402 ··· 502 493 } 503 494 if (req->ff) 504 495 fuse_file_put(req->ff); 505 - fuse_put_request(fc, req); 506 496 } 507 497 508 498 static void fuse_send_readpages(struct fuse_req *req, struct file *file, ··· 517 509 struct fuse_file *ff = file->private_data; 518 510 req->ff = fuse_file_get(ff); 519 511 req->end = fuse_readpages_end; 520 - request_send_background(fc, req); 512 + fuse_request_send_background(fc, req); 521 513 } else { 522 - request_send(fc, req); 514 + fuse_request_send(fc, req); 523 515 fuse_readpages_end(fc, req); 516 + fuse_put_request(fc, req); 524 517 } 525 518 } 526 519 ··· 552 543 } 553 544 } 554 545 req->pages[req->num_pages] = page; 555 - req->num_pages ++; 546 + req->num_pages++; 556 547 return 0; 557 548 } 558 549 ··· 645 636 inarg->write_flags |= FUSE_WRITE_LOCKOWNER; 646 637 inarg->lock_owner = fuse_lock_owner_id(fc, owner); 647 638 } 648 - request_send(fc, req); 639 + fuse_request_send(fc, req); 649 640 return req->misc.write.out.size; 650 641 } 651 642 ··· 1051 1042 { 1052 1043 __free_page(req->pages[0]); 1053 1044 fuse_file_put(req->ff); 1054 - fuse_put_request(fc, req); 1055 1045 } 1056 1046 1057 1047 static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req) ··· 1068 1060 1069 1061 /* Called under fc->lock, may release and reacquire it */ 1070 1062 static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req) 1063 + __releases(&fc->lock) 1064 + __acquires(&fc->lock) 1071 1065 { 1072 1066 struct fuse_inode *fi = get_fuse_inode(req->inode); 1073 1067 loff_t size = i_size_read(req->inode); ··· 1089 1079 1090 1080 req->in.args[1].size = inarg->size; 1091 1081 fi->writectr++; 1092 - request_send_background_locked(fc, req); 1082 + fuse_request_send_background_locked(fc, req); 1093 1083 return; 1094 1084 1095 1085 out_free: 1096 1086 fuse_writepage_finish(fc, req); 1097 1087 spin_unlock(&fc->lock); 1098 1088 fuse_writepage_free(fc, req); 1089 + fuse_put_request(fc, req); 1099 1090 spin_lock(&fc->lock); 1100 1091 } 1101 1092 ··· 1107 1096 * Called with fc->lock 1108 1097 */ 1109 1098 void fuse_flush_writepages(struct inode *inode) 1099 + __releases(&fc->lock) 1100 + __acquires(&fc->lock) 1110 1101 { 1111 1102 struct fuse_conn *fc = get_fuse_conn(inode); 1112 1103 struct fuse_inode *fi = get_fuse_inode(inode); ··· 1338 1325 req->out.numargs = 1; 1339 1326 req->out.args[0].size = sizeof(outarg); 1340 1327 req->out.args[0].value = &outarg; 1341 - request_send(fc, req); 1328 + fuse_request_send(fc, req); 1342 1329 err = req->out.h.error; 1343 1330 fuse_put_request(fc, req); 1344 1331 if (!err) ··· 1370 1357 return PTR_ERR(req); 1371 1358 1372 1359 fuse_lk_fill(req, file, fl, opcode, pid, flock); 1373 - request_send(fc, req); 1360 + fuse_request_send(fc, req); 1374 1361 err = req->out.h.error; 1375 1362 /* locking is restartable */ 1376 1363 if (err == -EINTR) ··· 1446 1433 req->out.numargs = 1; 1447 1434 req->out.args[0].size = sizeof(outarg); 1448 1435 req->out.args[0].value = &outarg; 1449 - request_send(fc, req); 1436 + fuse_request_send(fc, req); 1450 1437 err = req->out.h.error; 1451 1438 fuse_put_request(fc, req); 1452 1439 if (err == -ENOSYS) ··· 1483 1470 return retval; 1484 1471 } 1485 1472 1473 + static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, 1474 + unsigned int nr_segs, size_t bytes, bool to_user) 1475 + { 1476 + struct iov_iter ii; 1477 + int page_idx = 0; 1478 + 1479 + if (!bytes) 1480 + return 0; 1481 + 1482 + iov_iter_init(&ii, iov, nr_segs, bytes, 0); 1483 + 1484 + while (iov_iter_count(&ii)) { 1485 + struct page *page = pages[page_idx++]; 1486 + size_t todo = min_t(size_t, PAGE_SIZE, iov_iter_count(&ii)); 1487 + void *kaddr, *map; 1488 + 1489 + kaddr = map = kmap(page); 1490 + 1491 + while (todo) { 1492 + char __user *uaddr = ii.iov->iov_base + ii.iov_offset; 1493 + size_t iov_len = ii.iov->iov_len - ii.iov_offset; 1494 + size_t copy = min(todo, iov_len); 1495 + size_t left; 1496 + 1497 + if (!to_user) 1498 + left = copy_from_user(kaddr, uaddr, copy); 1499 + else 1500 + left = copy_to_user(uaddr, kaddr, copy); 1501 + 1502 + if (unlikely(left)) 1503 + return -EFAULT; 1504 + 1505 + iov_iter_advance(&ii, copy); 1506 + todo -= copy; 1507 + kaddr += copy; 1508 + } 1509 + 1510 + kunmap(map); 1511 + } 1512 + 1513 + return 0; 1514 + } 1515 + 1516 + /* 1517 + * For ioctls, there is no generic way to determine how much memory 1518 + * needs to be read and/or written. Furthermore, ioctls are allowed 1519 + * to dereference the passed pointer, so the parameter requires deep 1520 + * copying but FUSE has no idea whatsoever about what to copy in or 1521 + * out. 1522 + * 1523 + * This is solved by allowing FUSE server to retry ioctl with 1524 + * necessary in/out iovecs. Let's assume the ioctl implementation 1525 + * needs to read in the following structure. 1526 + * 1527 + * struct a { 1528 + * char *buf; 1529 + * size_t buflen; 1530 + * } 1531 + * 1532 + * On the first callout to FUSE server, inarg->in_size and 1533 + * inarg->out_size will be NULL; then, the server completes the ioctl 1534 + * with FUSE_IOCTL_RETRY set in out->flags, out->in_iovs set to 1 and 1535 + * the actual iov array to 1536 + * 1537 + * { { .iov_base = inarg.arg, .iov_len = sizeof(struct a) } } 1538 + * 1539 + * which tells FUSE to copy in the requested area and retry the ioctl. 1540 + * On the second round, the server has access to the structure and 1541 + * from that it can tell what to look for next, so on the invocation, 1542 + * it sets FUSE_IOCTL_RETRY, out->in_iovs to 2 and iov array to 1543 + * 1544 + * { { .iov_base = inarg.arg, .iov_len = sizeof(struct a) }, 1545 + * { .iov_base = a.buf, .iov_len = a.buflen } } 1546 + * 1547 + * FUSE will copy both struct a and the pointed buffer from the 1548 + * process doing the ioctl and retry ioctl with both struct a and the 1549 + * buffer. 1550 + * 1551 + * This time, FUSE server has everything it needs and completes ioctl 1552 + * without FUSE_IOCTL_RETRY which finishes the ioctl call. 1553 + * 1554 + * Copying data out works the same way. 1555 + * 1556 + * Note that if FUSE_IOCTL_UNRESTRICTED is clear, the kernel 1557 + * automatically initializes in and out iovs by decoding @cmd with 1558 + * _IOC_* macros and the server is not allowed to request RETRY. This 1559 + * limits ioctl data transfers to well-formed ioctls and is the forced 1560 + * behavior for all FUSE servers. 1561 + */ 1562 + static long fuse_file_do_ioctl(struct file *file, unsigned int cmd, 1563 + unsigned long arg, unsigned int flags) 1564 + { 1565 + struct inode *inode = file->f_dentry->d_inode; 1566 + struct fuse_file *ff = file->private_data; 1567 + struct fuse_conn *fc = get_fuse_conn(inode); 1568 + struct fuse_ioctl_in inarg = { 1569 + .fh = ff->fh, 1570 + .cmd = cmd, 1571 + .arg = arg, 1572 + .flags = flags 1573 + }; 1574 + struct fuse_ioctl_out outarg; 1575 + struct fuse_req *req = NULL; 1576 + struct page **pages = NULL; 1577 + struct page *iov_page = NULL; 1578 + struct iovec *in_iov = NULL, *out_iov = NULL; 1579 + unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; 1580 + size_t in_size, out_size, transferred; 1581 + int err; 1582 + 1583 + /* assume all the iovs returned by client always fits in a page */ 1584 + BUILD_BUG_ON(sizeof(struct iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); 1585 + 1586 + if (!fuse_allow_task(fc, current)) 1587 + return -EACCES; 1588 + 1589 + err = -EIO; 1590 + if (is_bad_inode(inode)) 1591 + goto out; 1592 + 1593 + err = -ENOMEM; 1594 + pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL); 1595 + iov_page = alloc_page(GFP_KERNEL); 1596 + if (!pages || !iov_page) 1597 + goto out; 1598 + 1599 + /* 1600 + * If restricted, initialize IO parameters as encoded in @cmd. 1601 + * RETRY from server is not allowed. 1602 + */ 1603 + if (!(flags & FUSE_IOCTL_UNRESTRICTED)) { 1604 + struct iovec *iov = page_address(iov_page); 1605 + 1606 + iov->iov_base = (void __user *)arg; 1607 + iov->iov_len = _IOC_SIZE(cmd); 1608 + 1609 + if (_IOC_DIR(cmd) & _IOC_WRITE) { 1610 + in_iov = iov; 1611 + in_iovs = 1; 1612 + } 1613 + 1614 + if (_IOC_DIR(cmd) & _IOC_READ) { 1615 + out_iov = iov; 1616 + out_iovs = 1; 1617 + } 1618 + } 1619 + 1620 + retry: 1621 + inarg.in_size = in_size = iov_length(in_iov, in_iovs); 1622 + inarg.out_size = out_size = iov_length(out_iov, out_iovs); 1623 + 1624 + /* 1625 + * Out data can be used either for actual out data or iovs, 1626 + * make sure there always is at least one page. 1627 + */ 1628 + out_size = max_t(size_t, out_size, PAGE_SIZE); 1629 + max_pages = DIV_ROUND_UP(max(in_size, out_size), PAGE_SIZE); 1630 + 1631 + /* make sure there are enough buffer pages and init request with them */ 1632 + err = -ENOMEM; 1633 + if (max_pages > FUSE_MAX_PAGES_PER_REQ) 1634 + goto out; 1635 + while (num_pages < max_pages) { 1636 + pages[num_pages] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); 1637 + if (!pages[num_pages]) 1638 + goto out; 1639 + num_pages++; 1640 + } 1641 + 1642 + req = fuse_get_req(fc); 1643 + if (IS_ERR(req)) { 1644 + err = PTR_ERR(req); 1645 + req = NULL; 1646 + goto out; 1647 + } 1648 + memcpy(req->pages, pages, sizeof(req->pages[0]) * num_pages); 1649 + req->num_pages = num_pages; 1650 + 1651 + /* okay, let's send it to the client */ 1652 + req->in.h.opcode = FUSE_IOCTL; 1653 + req->in.h.nodeid = get_node_id(inode); 1654 + req->in.numargs = 1; 1655 + req->in.args[0].size = sizeof(inarg); 1656 + req->in.args[0].value = &inarg; 1657 + if (in_size) { 1658 + req->in.numargs++; 1659 + req->in.args[1].size = in_size; 1660 + req->in.argpages = 1; 1661 + 1662 + err = fuse_ioctl_copy_user(pages, in_iov, in_iovs, in_size, 1663 + false); 1664 + if (err) 1665 + goto out; 1666 + } 1667 + 1668 + req->out.numargs = 2; 1669 + req->out.args[0].size = sizeof(outarg); 1670 + req->out.args[0].value = &outarg; 1671 + req->out.args[1].size = out_size; 1672 + req->out.argpages = 1; 1673 + req->out.argvar = 1; 1674 + 1675 + fuse_request_send(fc, req); 1676 + err = req->out.h.error; 1677 + transferred = req->out.args[1].size; 1678 + fuse_put_request(fc, req); 1679 + req = NULL; 1680 + if (err) 1681 + goto out; 1682 + 1683 + /* did it ask for retry? */ 1684 + if (outarg.flags & FUSE_IOCTL_RETRY) { 1685 + char *vaddr; 1686 + 1687 + /* no retry if in restricted mode */ 1688 + err = -EIO; 1689 + if (!(flags & FUSE_IOCTL_UNRESTRICTED)) 1690 + goto out; 1691 + 1692 + in_iovs = outarg.in_iovs; 1693 + out_iovs = outarg.out_iovs; 1694 + 1695 + /* 1696 + * Make sure things are in boundary, separate checks 1697 + * are to protect against overflow. 1698 + */ 1699 + err = -ENOMEM; 1700 + if (in_iovs > FUSE_IOCTL_MAX_IOV || 1701 + out_iovs > FUSE_IOCTL_MAX_IOV || 1702 + in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) 1703 + goto out; 1704 + 1705 + err = -EIO; 1706 + if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred) 1707 + goto out; 1708 + 1709 + /* okay, copy in iovs and retry */ 1710 + vaddr = kmap_atomic(pages[0], KM_USER0); 1711 + memcpy(page_address(iov_page), vaddr, transferred); 1712 + kunmap_atomic(vaddr, KM_USER0); 1713 + 1714 + in_iov = page_address(iov_page); 1715 + out_iov = in_iov + in_iovs; 1716 + 1717 + goto retry; 1718 + } 1719 + 1720 + err = -EIO; 1721 + if (transferred > inarg.out_size) 1722 + goto out; 1723 + 1724 + err = fuse_ioctl_copy_user(pages, out_iov, out_iovs, transferred, true); 1725 + out: 1726 + if (req) 1727 + fuse_put_request(fc, req); 1728 + if (iov_page) 1729 + __free_page(iov_page); 1730 + while (num_pages) 1731 + __free_page(pages[--num_pages]); 1732 + kfree(pages); 1733 + 1734 + return err ? err : outarg.result; 1735 + } 1736 + 1737 + static long fuse_file_ioctl(struct file *file, unsigned int cmd, 1738 + unsigned long arg) 1739 + { 1740 + return fuse_file_do_ioctl(file, cmd, arg, 0); 1741 + } 1742 + 1743 + static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd, 1744 + unsigned long arg) 1745 + { 1746 + return fuse_file_do_ioctl(file, cmd, arg, FUSE_IOCTL_COMPAT); 1747 + } 1748 + 1749 + /* 1750 + * All files which have been polled are linked to RB tree 1751 + * fuse_conn->polled_files which is indexed by kh. Walk the tree and 1752 + * find the matching one. 1753 + */ 1754 + static struct rb_node **fuse_find_polled_node(struct fuse_conn *fc, u64 kh, 1755 + struct rb_node **parent_out) 1756 + { 1757 + struct rb_node **link = &fc->polled_files.rb_node; 1758 + struct rb_node *last = NULL; 1759 + 1760 + while (*link) { 1761 + struct fuse_file *ff; 1762 + 1763 + last = *link; 1764 + ff = rb_entry(last, struct fuse_file, polled_node); 1765 + 1766 + if (kh < ff->kh) 1767 + link = &last->rb_left; 1768 + else if (kh > ff->kh) 1769 + link = &last->rb_right; 1770 + else 1771 + return link; 1772 + } 1773 + 1774 + if (parent_out) 1775 + *parent_out = last; 1776 + return link; 1777 + } 1778 + 1779 + /* 1780 + * The file is about to be polled. Make sure it's on the polled_files 1781 + * RB tree. Note that files once added to the polled_files tree are 1782 + * not removed before the file is released. This is because a file 1783 + * polled once is likely to be polled again. 1784 + */ 1785 + static void fuse_register_polled_file(struct fuse_conn *fc, 1786 + struct fuse_file *ff) 1787 + { 1788 + spin_lock(&fc->lock); 1789 + if (RB_EMPTY_NODE(&ff->polled_node)) { 1790 + struct rb_node **link, *parent; 1791 + 1792 + link = fuse_find_polled_node(fc, ff->kh, &parent); 1793 + BUG_ON(*link); 1794 + rb_link_node(&ff->polled_node, parent, link); 1795 + rb_insert_color(&ff->polled_node, &fc->polled_files); 1796 + } 1797 + spin_unlock(&fc->lock); 1798 + } 1799 + 1800 + static unsigned fuse_file_poll(struct file *file, poll_table *wait) 1801 + { 1802 + struct inode *inode = file->f_dentry->d_inode; 1803 + struct fuse_file *ff = file->private_data; 1804 + struct fuse_conn *fc = get_fuse_conn(inode); 1805 + struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh }; 1806 + struct fuse_poll_out outarg; 1807 + struct fuse_req *req; 1808 + int err; 1809 + 1810 + if (fc->no_poll) 1811 + return DEFAULT_POLLMASK; 1812 + 1813 + poll_wait(file, &ff->poll_wait, wait); 1814 + 1815 + /* 1816 + * Ask for notification iff there's someone waiting for it. 1817 + * The client may ignore the flag and always notify. 1818 + */ 1819 + if (waitqueue_active(&ff->poll_wait)) { 1820 + inarg.flags |= FUSE_POLL_SCHEDULE_NOTIFY; 1821 + fuse_register_polled_file(fc, ff); 1822 + } 1823 + 1824 + req = fuse_get_req(fc); 1825 + if (IS_ERR(req)) 1826 + return PTR_ERR(req); 1827 + 1828 + req->in.h.opcode = FUSE_POLL; 1829 + req->in.h.nodeid = get_node_id(inode); 1830 + req->in.numargs = 1; 1831 + req->in.args[0].size = sizeof(inarg); 1832 + req->in.args[0].value = &inarg; 1833 + req->out.numargs = 1; 1834 + req->out.args[0].size = sizeof(outarg); 1835 + req->out.args[0].value = &outarg; 1836 + fuse_request_send(fc, req); 1837 + err = req->out.h.error; 1838 + fuse_put_request(fc, req); 1839 + 1840 + if (!err) 1841 + return outarg.revents; 1842 + if (err == -ENOSYS) { 1843 + fc->no_poll = 1; 1844 + return DEFAULT_POLLMASK; 1845 + } 1846 + return POLLERR; 1847 + } 1848 + 1849 + /* 1850 + * This is called from fuse_handle_notify() on FUSE_NOTIFY_POLL and 1851 + * wakes up the poll waiters. 1852 + */ 1853 + int fuse_notify_poll_wakeup(struct fuse_conn *fc, 1854 + struct fuse_notify_poll_wakeup_out *outarg) 1855 + { 1856 + u64 kh = outarg->kh; 1857 + struct rb_node **link; 1858 + 1859 + spin_lock(&fc->lock); 1860 + 1861 + link = fuse_find_polled_node(fc, kh, NULL); 1862 + if (*link) { 1863 + struct fuse_file *ff; 1864 + 1865 + ff = rb_entry(*link, struct fuse_file, polled_node); 1866 + wake_up_interruptible_sync(&ff->poll_wait); 1867 + } 1868 + 1869 + spin_unlock(&fc->lock); 1870 + return 0; 1871 + } 1872 + 1486 1873 static const struct file_operations fuse_file_operations = { 1487 1874 .llseek = fuse_file_llseek, 1488 1875 .read = do_sync_read, ··· 1897 1484 .lock = fuse_file_lock, 1898 1485 .flock = fuse_file_flock, 1899 1486 .splice_read = generic_file_splice_read, 1487 + .unlocked_ioctl = fuse_file_ioctl, 1488 + .compat_ioctl = fuse_file_compat_ioctl, 1489 + .poll = fuse_file_poll, 1900 1490 }; 1901 1491 1902 1492 static const struct file_operations fuse_direct_io_file_operations = { ··· 1912 1496 .fsync = fuse_fsync, 1913 1497 .lock = fuse_file_lock, 1914 1498 .flock = fuse_file_flock, 1499 + .unlocked_ioctl = fuse_file_ioctl, 1500 + .compat_ioctl = fuse_file_compat_ioctl, 1501 + .poll = fuse_file_poll, 1915 1502 /* no mmap and splice_read */ 1916 1503 }; 1917 1504
+59 -24
fs/fuse/fuse_i.h
··· 1 1 /* 2 2 FUSE: Filesystem in Userspace 3 - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 3 + Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 4 5 5 This program can be distributed under the terms of the GNU GPL. 6 6 See the file COPYING. ··· 19 19 #include <linux/backing-dev.h> 20 20 #include <linux/mutex.h> 21 21 #include <linux/rwsem.h> 22 + #include <linux/rbtree.h> 23 + #include <linux/poll.h> 22 24 23 25 /** Max number of pages that can be used in a single read request */ 24 26 #define FUSE_MAX_PAGES_PER_REQ 32 ··· 102 100 /** Request reserved for flush and release */ 103 101 struct fuse_req *reserved_req; 104 102 103 + /** Kernel file handle guaranteed to be unique */ 104 + u64 kh; 105 + 105 106 /** File handle used by userspace */ 106 107 u64 fh; 107 108 ··· 113 108 114 109 /** Entry on inode's write_files list */ 115 110 struct list_head write_entry; 111 + 112 + /** RB node to be linked on fuse_conn->polled_files */ 113 + struct rb_node polled_node; 114 + 115 + /** Wait queue head for poll */ 116 + wait_queue_head_t poll_wait; 116 117 }; 117 118 118 119 /** One input argument of a request */ ··· 333 322 /** The list of requests under I/O */ 334 323 struct list_head io; 335 324 325 + /** The next unique kernel file handle */ 326 + u64 khctr; 327 + 328 + /** rbtree of fuse_files waiting for poll events indexed by ph */ 329 + struct rb_root polled_files; 330 + 336 331 /** Number of requests currently in the background */ 337 332 unsigned num_background; 338 333 ··· 372 355 /** Connection failed (version mismatch). Cannot race with 373 356 setting other bitfields since it is only set once in INIT 374 357 reply, before any other request, and never cleared */ 375 - unsigned conn_error : 1; 358 + unsigned conn_error:1; 376 359 377 360 /** Connection successful. Only set in INIT */ 378 - unsigned conn_init : 1; 361 + unsigned conn_init:1; 379 362 380 363 /** Do readpages asynchronously? Only set in INIT */ 381 - unsigned async_read : 1; 364 + unsigned async_read:1; 382 365 383 366 /** Do not send separate SETATTR request before open(O_TRUNC) */ 384 - unsigned atomic_o_trunc : 1; 367 + unsigned atomic_o_trunc:1; 385 368 386 369 /** Filesystem supports NFS exporting. Only set in INIT */ 387 - unsigned export_support : 1; 370 + unsigned export_support:1; 388 371 389 372 /* 390 373 * The following bitfields are only for optimization purposes ··· 392 375 */ 393 376 394 377 /** Is fsync not implemented by fs? */ 395 - unsigned no_fsync : 1; 378 + unsigned no_fsync:1; 396 379 397 380 /** Is fsyncdir not implemented by fs? */ 398 - unsigned no_fsyncdir : 1; 381 + unsigned no_fsyncdir:1; 399 382 400 383 /** Is flush not implemented by fs? */ 401 - unsigned no_flush : 1; 384 + unsigned no_flush:1; 402 385 403 386 /** Is setxattr not implemented by fs? */ 404 - unsigned no_setxattr : 1; 387 + unsigned no_setxattr:1; 405 388 406 389 /** Is getxattr not implemented by fs? */ 407 - unsigned no_getxattr : 1; 390 + unsigned no_getxattr:1; 408 391 409 392 /** Is listxattr not implemented by fs? */ 410 - unsigned no_listxattr : 1; 393 + unsigned no_listxattr:1; 411 394 412 395 /** Is removexattr not implemented by fs? */ 413 - unsigned no_removexattr : 1; 396 + unsigned no_removexattr:1; 414 397 415 398 /** Are file locking primitives not implemented by fs? */ 416 - unsigned no_lock : 1; 399 + unsigned no_lock:1; 417 400 418 401 /** Is access not implemented by fs? */ 419 - unsigned no_access : 1; 402 + unsigned no_access:1; 420 403 421 404 /** Is create not implemented by fs? */ 422 - unsigned no_create : 1; 405 + unsigned no_create:1; 423 406 424 407 /** Is interrupt not implemented by fs? */ 425 - unsigned no_interrupt : 1; 408 + unsigned no_interrupt:1; 426 409 427 410 /** Is bmap not implemented by fs? */ 428 - unsigned no_bmap : 1; 411 + unsigned no_bmap:1; 412 + 413 + /** Is poll not implemented by fs? */ 414 + unsigned no_poll:1; 429 415 430 416 /** Do multi-page cached writes */ 431 - unsigned big_writes : 1; 417 + unsigned big_writes:1; 432 418 433 419 /** The number of requests waiting for completion */ 434 420 atomic_t num_waiting; ··· 465 445 466 446 /** Version counter for attribute changes */ 467 447 u64 attr_version; 448 + 449 + /** Called on final put */ 450 + void (*release)(struct fuse_conn *); 468 451 }; 469 452 470 453 static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) ··· 522 499 */ 523 500 int fuse_open_common(struct inode *inode, struct file *file, int isdir); 524 501 525 - struct fuse_file *fuse_file_alloc(void); 502 + struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); 526 503 void fuse_file_free(struct fuse_file *ff); 527 504 void fuse_finish_open(struct inode *inode, struct file *file, 528 505 struct fuse_file *ff, struct fuse_open_out *outarg); ··· 540 517 */ 541 518 int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, 542 519 int isdir); 520 + 521 + /** 522 + * Notify poll wakeup 523 + */ 524 + int fuse_notify_poll_wakeup(struct fuse_conn *fc, 525 + struct fuse_notify_poll_wakeup_out *outarg); 543 526 544 527 /** 545 528 * Initialize file operations on a regular file ··· 622 593 /** 623 594 * Send a request (synchronous) 624 595 */ 625 - void request_send(struct fuse_conn *fc, struct fuse_req *req); 596 + void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req); 626 597 627 598 /** 628 599 * Send a request with no reply 629 600 */ 630 - void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); 601 + void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); 631 602 632 603 /** 633 604 * Send a request in the background 634 605 */ 635 - void request_send_background(struct fuse_conn *fc, struct fuse_req *req); 606 + void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req); 636 607 637 - void request_send_background_locked(struct fuse_conn *fc, struct fuse_req *req); 608 + void fuse_request_send_background_locked(struct fuse_conn *fc, 609 + struct fuse_req *req); 638 610 639 611 /* Abort all requests */ 640 612 void fuse_abort_conn(struct fuse_conn *fc); ··· 651 621 * Acquire reference to fuse_conn 652 622 */ 653 623 struct fuse_conn *fuse_conn_get(struct fuse_conn *fc); 624 + 625 + /** 626 + * Initialize fuse_conn 627 + */ 628 + int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb); 654 629 655 630 /** 656 631 * Release reference to fuse_conn
+84 -73
fs/fuse/inode.c
··· 1 1 /* 2 2 FUSE: Filesystem in Userspace 3 - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 3 + Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 4 5 5 This program can be distributed under the terms of the GNU GPL. 6 6 See the file COPYING. ··· 37 37 unsigned rootmode; 38 38 unsigned user_id; 39 39 unsigned group_id; 40 - unsigned fd_present : 1; 41 - unsigned rootmode_present : 1; 42 - unsigned user_id_present : 1; 43 - unsigned group_id_present : 1; 40 + unsigned fd_present:1; 41 + unsigned rootmode_present:1; 42 + unsigned user_id_present:1; 43 + unsigned group_id_present:1; 44 44 unsigned flags; 45 45 unsigned max_read; 46 46 unsigned blksize; ··· 94 94 req->in.numargs = 1; 95 95 req->in.args[0].size = sizeof(struct fuse_forget_in); 96 96 req->in.args[0].value = inarg; 97 - request_send_noreply(fc, req); 97 + fuse_request_send_noreply(fc, req); 98 98 } 99 99 100 100 static void fuse_clear_inode(struct inode *inode) ··· 250 250 251 251 fi = get_fuse_inode(inode); 252 252 spin_lock(&fc->lock); 253 - fi->nlookup ++; 253 + fi->nlookup++; 254 254 spin_unlock(&fc->lock); 255 255 fuse_change_attributes(inode, attr, attr_valid, attr_version); 256 256 ··· 269 269 fc->destroy_req = NULL; 270 270 req->in.h.opcode = FUSE_DESTROY; 271 271 req->force = 1; 272 - request_send(fc, req); 272 + fuse_request_send(fc, req); 273 273 fuse_put_request(fc, req); 274 274 } 275 275 } ··· 334 334 req->out.args[0].size = 335 335 fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); 336 336 req->out.args[0].value = &outarg; 337 - request_send(fc, req); 337 + fuse_request_send(fc, req); 338 338 err = req->out.h.error; 339 339 if (!err) 340 340 convert_fuse_statfs(buf, &outarg.st); ··· 462 462 return 0; 463 463 } 464 464 465 - static struct fuse_conn *new_conn(struct super_block *sb) 465 + int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb) 466 466 { 467 - struct fuse_conn *fc; 468 467 int err; 469 468 470 - fc = kzalloc(sizeof(*fc), GFP_KERNEL); 471 - if (fc) { 472 - spin_lock_init(&fc->lock); 473 - mutex_init(&fc->inst_mutex); 474 - atomic_set(&fc->count, 1); 475 - init_waitqueue_head(&fc->waitq); 476 - init_waitqueue_head(&fc->blocked_waitq); 477 - init_waitqueue_head(&fc->reserved_req_waitq); 478 - INIT_LIST_HEAD(&fc->pending); 479 - INIT_LIST_HEAD(&fc->processing); 480 - INIT_LIST_HEAD(&fc->io); 481 - INIT_LIST_HEAD(&fc->interrupts); 482 - INIT_LIST_HEAD(&fc->bg_queue); 483 - atomic_set(&fc->num_waiting, 0); 484 - fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; 485 - fc->bdi.unplug_io_fn = default_unplug_io_fn; 486 - /* fuse does it's own writeback accounting */ 487 - fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; 488 - fc->dev = sb->s_dev; 489 - err = bdi_init(&fc->bdi); 490 - if (err) 491 - goto error_kfree; 492 - if (sb->s_bdev) { 493 - err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", 494 - MAJOR(fc->dev), MINOR(fc->dev)); 495 - } else { 496 - err = bdi_register_dev(&fc->bdi, fc->dev); 497 - } 498 - if (err) 499 - goto error_bdi_destroy; 500 - /* 501 - * For a single fuse filesystem use max 1% of dirty + 502 - * writeback threshold. 503 - * 504 - * This gives about 1M of write buffer for memory maps on a 505 - * machine with 1G and 10% dirty_ratio, which should be more 506 - * than enough. 507 - * 508 - * Privileged users can raise it by writing to 509 - * 510 - * /sys/class/bdi/<bdi>/max_ratio 511 - */ 512 - bdi_set_max_ratio(&fc->bdi, 1); 513 - fc->reqctr = 0; 514 - fc->blocked = 1; 515 - fc->attr_version = 1; 516 - get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); 469 + memset(fc, 0, sizeof(*fc)); 470 + spin_lock_init(&fc->lock); 471 + mutex_init(&fc->inst_mutex); 472 + atomic_set(&fc->count, 1); 473 + init_waitqueue_head(&fc->waitq); 474 + init_waitqueue_head(&fc->blocked_waitq); 475 + init_waitqueue_head(&fc->reserved_req_waitq); 476 + INIT_LIST_HEAD(&fc->pending); 477 + INIT_LIST_HEAD(&fc->processing); 478 + INIT_LIST_HEAD(&fc->io); 479 + INIT_LIST_HEAD(&fc->interrupts); 480 + INIT_LIST_HEAD(&fc->bg_queue); 481 + INIT_LIST_HEAD(&fc->entry); 482 + atomic_set(&fc->num_waiting, 0); 483 + fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; 484 + fc->bdi.unplug_io_fn = default_unplug_io_fn; 485 + /* fuse does it's own writeback accounting */ 486 + fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; 487 + fc->khctr = 0; 488 + fc->polled_files = RB_ROOT; 489 + fc->dev = sb->s_dev; 490 + err = bdi_init(&fc->bdi); 491 + if (err) 492 + goto error_mutex_destroy; 493 + if (sb->s_bdev) { 494 + err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", 495 + MAJOR(fc->dev), MINOR(fc->dev)); 496 + } else { 497 + err = bdi_register_dev(&fc->bdi, fc->dev); 517 498 } 518 - return fc; 499 + if (err) 500 + goto error_bdi_destroy; 501 + /* 502 + * For a single fuse filesystem use max 1% of dirty + 503 + * writeback threshold. 504 + * 505 + * This gives about 1M of write buffer for memory maps on a 506 + * machine with 1G and 10% dirty_ratio, which should be more 507 + * than enough. 508 + * 509 + * Privileged users can raise it by writing to 510 + * 511 + * /sys/class/bdi/<bdi>/max_ratio 512 + */ 513 + bdi_set_max_ratio(&fc->bdi, 1); 514 + fc->reqctr = 0; 515 + fc->blocked = 1; 516 + fc->attr_version = 1; 517 + get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); 519 518 520 - error_bdi_destroy: 519 + return 0; 520 + 521 + error_bdi_destroy: 521 522 bdi_destroy(&fc->bdi); 522 - error_kfree: 523 + error_mutex_destroy: 523 524 mutex_destroy(&fc->inst_mutex); 524 - kfree(fc); 525 - return NULL; 525 + return err; 526 526 } 527 + EXPORT_SYMBOL_GPL(fuse_conn_init); 527 528 528 529 void fuse_conn_put(struct fuse_conn *fc) 529 530 { ··· 533 532 fuse_request_free(fc->destroy_req); 534 533 mutex_destroy(&fc->inst_mutex); 535 534 bdi_destroy(&fc->bdi); 536 - kfree(fc); 535 + fc->release(fc); 537 536 } 538 537 } 539 538 ··· 543 542 return fc; 544 543 } 545 544 546 - static struct inode *get_root_inode(struct super_block *sb, unsigned mode) 545 + static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode) 547 546 { 548 547 struct fuse_attr attr; 549 548 memset(&attr, 0, sizeof(attr)); ··· 554 553 return fuse_iget(sb, 1, 0, &attr, 0, 0); 555 554 } 556 555 557 - struct fuse_inode_handle 558 - { 556 + struct fuse_inode_handle { 559 557 u64 nodeid; 560 558 u32 generation; 561 559 }; ··· 761 761 fc->max_write = max_t(unsigned, 4096, fc->max_write); 762 762 fc->conn_init = 1; 763 763 } 764 - fuse_put_request(fc, req); 765 764 fc->blocked = 0; 766 765 wake_up_all(&fc->blocked_waitq); 767 766 } ··· 786 787 req->out.args[0].size = sizeof(struct fuse_init_out); 787 788 req->out.args[0].value = &req->misc.init_out; 788 789 req->end = process_init_reply; 789 - request_send_background(fc, req); 790 + fuse_request_send_background(fc, req); 791 + } 792 + 793 + static void fuse_free_conn(struct fuse_conn *fc) 794 + { 795 + kfree(fc); 790 796 } 791 797 792 798 static int fuse_fill_super(struct super_block *sb, void *data, int silent) ··· 832 828 if (file->f_op != &fuse_dev_operations) 833 829 return -EINVAL; 834 830 835 - fc = new_conn(sb); 831 + fc = kmalloc(sizeof(*fc), GFP_KERNEL); 836 832 if (!fc) 837 833 return -ENOMEM; 838 834 835 + err = fuse_conn_init(fc, sb); 836 + if (err) { 837 + kfree(fc); 838 + return err; 839 + } 840 + 841 + fc->release = fuse_free_conn; 839 842 fc->flags = d.flags; 840 843 fc->user_id = d.user_id; 841 844 fc->group_id = d.group_id; ··· 852 841 sb->s_fs_info = fc; 853 842 854 843 err = -ENOMEM; 855 - root = get_root_inode(sb, d.rootmode); 844 + root = fuse_get_root_inode(sb, d.rootmode); 856 845 if (!root) 857 846 goto err; 858 847 ··· 963 952 964 953 static void fuse_inode_init_once(void *foo) 965 954 { 966 - struct inode * inode = foo; 955 + struct inode *inode = foo; 967 956 968 957 inode_init_once(inode); 969 958 } ··· 1042 1031 { 1043 1032 int res; 1044 1033 1045 - printk("fuse init (API version %i.%i)\n", 1034 + printk(KERN_INFO "fuse init (API version %i.%i)\n", 1046 1035 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); 1047 1036 1048 1037 INIT_LIST_HEAD(&fuse_conn_list);
+69 -10
include/linux/fuse.h
··· 1 1 /* 2 2 FUSE: Filesystem in Userspace 3 - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 3 + Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 4 5 5 This program can be distributed under the terms of the GNU GPL. 6 6 See the file COPYING. ··· 20 20 * 21 21 * 7.10 22 22 * - add nonseekable open flag 23 + * 24 + * 7.11 25 + * - add IOCTL message 26 + * - add unsolicited notification support 27 + * - add POLL message and NOTIFY_POLL notification 23 28 */ 24 29 25 30 #ifndef _LINUX_FUSE_H 26 31 #define _LINUX_FUSE_H 27 32 28 - #include <asm/types.h> 29 - #include <linux/major.h> 33 + #include <linux/types.h> 30 34 31 35 /** Version number of this interface */ 32 36 #define FUSE_KERNEL_VERSION 7 33 37 34 38 /** Minor version number of this interface */ 35 - #define FUSE_KERNEL_MINOR_VERSION 10 39 + #define FUSE_KERNEL_MINOR_VERSION 11 36 40 37 41 /** The node ID of the root inode */ 38 42 #define FUSE_ROOT_ID 1 39 - 40 - /** The major number of the fuse character device */ 41 - #define FUSE_MAJOR MISC_MAJOR 42 - 43 - /** The minor number of the fuse character device */ 44 - #define FUSE_MINOR 229 45 43 46 44 /* Make sure all structures are padded to 64bit boundary, so 32bit 47 45 userspace works under 64bit kernels */ ··· 149 151 */ 150 152 #define FUSE_READ_LOCKOWNER (1 << 1) 151 153 154 + /** 155 + * Ioctl flags 156 + * 157 + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine 158 + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed 159 + * FUSE_IOCTL_RETRY: retry with new iovecs 160 + * 161 + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs 162 + */ 163 + #define FUSE_IOCTL_COMPAT (1 << 0) 164 + #define FUSE_IOCTL_UNRESTRICTED (1 << 1) 165 + #define FUSE_IOCTL_RETRY (1 << 2) 166 + 167 + #define FUSE_IOCTL_MAX_IOV 256 168 + 169 + /** 170 + * Poll flags 171 + * 172 + * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify 173 + */ 174 + #define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) 175 + 152 176 enum fuse_opcode { 153 177 FUSE_LOOKUP = 1, 154 178 FUSE_FORGET = 2, /* no reply */ ··· 208 188 FUSE_INTERRUPT = 36, 209 189 FUSE_BMAP = 37, 210 190 FUSE_DESTROY = 38, 191 + FUSE_IOCTL = 39, 192 + FUSE_POLL = 40, 193 + }; 194 + 195 + enum fuse_notify_code { 196 + FUSE_NOTIFY_POLL = 1, 197 + FUSE_NOTIFY_CODE_MAX, 211 198 }; 212 199 213 200 /* The read buffer is required to be at least 8k, but may be much larger */ ··· 413 386 414 387 struct fuse_bmap_out { 415 388 __u64 block; 389 + }; 390 + 391 + struct fuse_ioctl_in { 392 + __u64 fh; 393 + __u32 flags; 394 + __u32 cmd; 395 + __u64 arg; 396 + __u32 in_size; 397 + __u32 out_size; 398 + }; 399 + 400 + struct fuse_ioctl_out { 401 + __s32 result; 402 + __u32 flags; 403 + __u32 in_iovs; 404 + __u32 out_iovs; 405 + }; 406 + 407 + struct fuse_poll_in { 408 + __u64 fh; 409 + __u64 kh; 410 + __u32 flags; 411 + __u32 padding; 412 + }; 413 + 414 + struct fuse_poll_out { 415 + __u32 revents; 416 + __u32 padding; 417 + }; 418 + 419 + struct fuse_notify_poll_wakeup_out { 420 + __u64 kh; 416 421 }; 417 422 418 423 struct fuse_in_header {
+21 -21
include/linux/miscdevice.h
··· 3 3 #include <linux/module.h> 4 4 #include <linux/major.h> 5 5 6 - #define PSMOUSE_MINOR 1 7 - #define MS_BUSMOUSE_MINOR 2 8 - #define ATIXL_BUSMOUSE_MINOR 3 9 - /*#define AMIGAMOUSE_MINOR 4 FIXME OBSOLETE */ 10 - #define ATARIMOUSE_MINOR 5 11 - #define SUN_MOUSE_MINOR 6 12 - #define APOLLO_MOUSE_MINOR 7 13 - #define PC110PAD_MINOR 9 14 - /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */ 6 + #define PSMOUSE_MINOR 1 7 + #define MS_BUSMOUSE_MINOR 2 8 + #define ATIXL_BUSMOUSE_MINOR 3 9 + /*#define AMIGAMOUSE_MINOR 4 FIXME OBSOLETE */ 10 + #define ATARIMOUSE_MINOR 5 11 + #define SUN_MOUSE_MINOR 6 12 + #define APOLLO_MOUSE_MINOR 7 13 + #define PC110PAD_MINOR 9 14 + /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */ 15 15 #define WATCHDOG_MINOR 130 /* Watchdog timer */ 16 16 #define TEMP_MINOR 131 /* Temperature Sensor */ 17 - #define RTC_MINOR 135 17 + #define RTC_MINOR 135 18 18 #define EFI_RTC_MINOR 136 /* EFI Time services */ 19 - #define SUN_OPENPROM_MINOR 139 19 + #define SUN_OPENPROM_MINOR 139 20 20 #define DMAPI_MINOR 140 /* DMAPI */ 21 - #define NVRAM_MINOR 144 22 - #define SGI_MMTIMER 153 21 + #define NVRAM_MINOR 144 22 + #define SGI_MMTIMER 153 23 23 #define STORE_QUEUE_MINOR 155 24 - #define I2O_MINOR 166 24 + #define I2O_MINOR 166 25 25 #define MICROCODE_MINOR 184 26 - #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ 27 - #define MPT_MINOR 220 28 - #define MISC_DYNAMIC_MINOR 255 29 - 30 - #define TUN_MINOR 200 31 - #define HPET_MINOR 228 32 - #define KVM_MINOR 232 26 + #define TUN_MINOR 200 27 + #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ 28 + #define MPT_MINOR 220 29 + #define HPET_MINOR 228 30 + #define FUSE_MINOR 229 31 + #define KVM_MINOR 232 32 + #define MISC_DYNAMIC_MINOR 255 33 33 34 34 struct device; 35 35