aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 20:01:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 20:01:20 -0500
commit5fec8bdbf9a1c4df4ad3f20e52aa2d8caed490c8 (patch)
treee8c1b1a9f3ea6b6a0edb972f082d0d7338c98af4 /fs/fuse/dev.c
parent59e3af21e94bd56f6a31ba774786a2bfc753581b (diff)
parent5d9ec854bfb6f1e122b1d96b344164a71eac5be8 (diff)
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
Diffstat (limited to 'fs/fuse/dev.c')
-rw-r--r--fs/fuse/dev.c113
1 files changed, 83 insertions, 30 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index fba571648a8e..e0c7ada08a1f 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1,6 +1,6 @@
1/* 1/*
2 FUSE: Filesystem in Userspace 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 This program can be distributed under the terms of the GNU GPL. 5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING. 6 See the file COPYING.
@@ -269,7 +269,7 @@ static void flush_bg_queue(struct fuse_conn *fc)
269 * Called with fc->lock, unlocks it 269 * Called with fc->lock, unlocks it
270 */ 270 */
271static void request_end(struct fuse_conn *fc, struct fuse_req *req) 271static void request_end(struct fuse_conn *fc, struct fuse_req *req)
272 __releases(fc->lock) 272__releases(&fc->lock)
273{ 273{
274 void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 274 void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
275 req->end = NULL; 275 req->end = NULL;
@@ -293,13 +293,13 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
293 wake_up(&req->waitq); 293 wake_up(&req->waitq);
294 if (end) 294 if (end)
295 end(fc, req); 295 end(fc, req);
296 else 296 fuse_put_request(fc, req);
297 fuse_put_request(fc, req);
298} 297}
299 298
300static void wait_answer_interruptible(struct fuse_conn *fc, 299static void wait_answer_interruptible(struct fuse_conn *fc,
301 struct fuse_req *req) 300 struct fuse_req *req)
302 __releases(fc->lock) __acquires(fc->lock) 301__releases(&fc->lock)
302__acquires(&fc->lock)
303{ 303{
304 if (signal_pending(current)) 304 if (signal_pending(current))
305 return; 305 return;
@@ -317,7 +317,8 @@ static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req)
317} 317}
318 318
319static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) 319static 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 if (!fc->no_interrupt) { 323 if (!fc->no_interrupt) {
323 /* Any signal may interrupt this */ 324 /* Any signal may interrupt this */
@@ -380,7 +381,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
380 } 381 }
381} 382}
382 383
383void request_send(struct fuse_conn *fc, struct fuse_req *req) 384void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
384{ 385{
385 req->isreply = 1; 386 req->isreply = 1;
386 spin_lock(&fc->lock); 387 spin_lock(&fc->lock);
@@ -399,8 +400,8 @@ void request_send(struct fuse_conn *fc, struct fuse_req *req)
399 spin_unlock(&fc->lock); 400 spin_unlock(&fc->lock);
400} 401}
401 402
402static void request_send_nowait_locked(struct fuse_conn *fc, 403static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
403 struct fuse_req *req) 404 struct fuse_req *req)
404{ 405{
405 req->background = 1; 406 req->background = 1;
406 fc->num_background++; 407 fc->num_background++;
@@ -414,11 +415,11 @@ static void request_send_nowait_locked(struct fuse_conn *fc,
414 flush_bg_queue(fc); 415 flush_bg_queue(fc);
415} 416}
416 417
417static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) 418static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
418{ 419{
419 spin_lock(&fc->lock); 420 spin_lock(&fc->lock);
420 if (fc->connected) { 421 if (fc->connected) {
421 request_send_nowait_locked(fc, req); 422 fuse_request_send_nowait_locked(fc, req);
422 spin_unlock(&fc->lock); 423 spin_unlock(&fc->lock);
423 } else { 424 } else {
424 req->out.h.error = -ENOTCONN; 425 req->out.h.error = -ENOTCONN;
@@ -426,16 +427,16 @@ static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
426 } 427 }
427} 428}
428 429
429void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) 430void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
430{ 431{
431 req->isreply = 0; 432 req->isreply = 0;
432 request_send_nowait(fc, req); 433 fuse_request_send_nowait(fc, req);
433} 434}
434 435
435void request_send_background(struct fuse_conn *fc, struct fuse_req *req) 436void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
436{ 437{
437 req->isreply = 1; 438 req->isreply = 1;
438 request_send_nowait(fc, req); 439 fuse_request_send_nowait(fc, req);
439} 440}
440 441
441/* 442/*
@@ -443,10 +444,11 @@ void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
443 * 444 *
444 * fc->connected must have been checked previously 445 * fc->connected must have been checked previously
445 */ 446 */
446void request_send_background_locked(struct fuse_conn *fc, struct fuse_req *req) 447void fuse_request_send_background_locked(struct fuse_conn *fc,
448 struct fuse_req *req)
447{ 449{
448 req->isreply = 1; 450 req->isreply = 1;
449 request_send_nowait_locked(fc, req); 451 fuse_request_send_nowait_locked(fc, req);
450} 452}
451 453
452/* 454/*
@@ -539,8 +541,8 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
539 BUG_ON(!cs->nr_segs); 541 BUG_ON(!cs->nr_segs);
540 cs->seglen = cs->iov[0].iov_len; 542 cs->seglen = cs->iov[0].iov_len;
541 cs->addr = (unsigned long) cs->iov[0].iov_base; 543 cs->addr = (unsigned long) cs->iov[0].iov_base;
542 cs->iov ++; 544 cs->iov++;
543 cs->nr_segs --; 545 cs->nr_segs--;
544 } 546 }
545 down_read(&current->mm->mmap_sem); 547 down_read(&current->mm->mmap_sem);
546 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, 548 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
@@ -589,9 +591,11 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
589 kunmap_atomic(mapaddr, KM_USER1); 591 kunmap_atomic(mapaddr, KM_USER1);
590 } 592 }
591 while (count) { 593 while (count) {
592 int err; 594 if (!cs->len) {
593 if (!cs->len && (err = fuse_copy_fill(cs))) 595 int err = fuse_copy_fill(cs);
594 return err; 596 if (err)
597 return err;
598 }
595 if (page) { 599 if (page) {
596 void *mapaddr = kmap_atomic(page, KM_USER1); 600 void *mapaddr = kmap_atomic(page, KM_USER1);
597 void *buf = mapaddr + offset; 601 void *buf = mapaddr + offset;
@@ -631,9 +635,11 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
631static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 635static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
632{ 636{
633 while (size) { 637 while (size) {
634 int err; 638 if (!cs->len) {
635 if (!cs->len && (err = fuse_copy_fill(cs))) 639 int err = fuse_copy_fill(cs);
636 return err; 640 if (err)
641 return err;
642 }
637 fuse_copy_do(cs, &val, &size); 643 fuse_copy_do(cs, &val, &size);
638 } 644 }
639 return 0; 645 return 0;
@@ -664,6 +670,8 @@ static int request_pending(struct fuse_conn *fc)
664 670
665/* Wait until a request is available on the pending list */ 671/* Wait until a request is available on the pending list */
666static void request_wait(struct fuse_conn *fc) 672static void request_wait(struct fuse_conn *fc)
673__releases(&fc->lock)
674__acquires(&fc->lock)
667{ 675{
668 DECLARE_WAITQUEUE(wait, current); 676 DECLARE_WAITQUEUE(wait, current);
669 677
@@ -691,7 +699,7 @@ static void request_wait(struct fuse_conn *fc)
691 */ 699 */
692static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, 700static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req,
693 const struct iovec *iov, unsigned long nr_segs) 701 const struct iovec *iov, unsigned long nr_segs)
694 __releases(fc->lock) 702__releases(&fc->lock)
695{ 703{
696 struct fuse_copy_state cs; 704 struct fuse_copy_state cs;
697 struct fuse_in_header ih; 705 struct fuse_in_header ih;
@@ -813,6 +821,34 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
813 return err; 821 return err;
814} 822}
815 823
824static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
825 struct fuse_copy_state *cs)
826{
827 struct fuse_notify_poll_wakeup_out outarg;
828 int err;
829
830 if (size != sizeof(outarg))
831 return -EINVAL;
832
833 err = fuse_copy_one(cs, &outarg, sizeof(outarg));
834 if (err)
835 return err;
836
837 return fuse_notify_poll_wakeup(fc, &outarg);
838}
839
840static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
841 unsigned int size, struct fuse_copy_state *cs)
842{
843 switch (code) {
844 case FUSE_NOTIFY_POLL:
845 return fuse_notify_poll(fc, size, cs);
846
847 default:
848 return -EINVAL;
849 }
850}
851
816/* Look up request on processing list by unique ID */ 852/* Look up request on processing list by unique ID */
817static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) 853static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
818{ 854{
@@ -876,9 +912,23 @@ static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
876 err = fuse_copy_one(&cs, &oh, sizeof(oh)); 912 err = fuse_copy_one(&cs, &oh, sizeof(oh));
877 if (err) 913 if (err)
878 goto err_finish; 914 goto err_finish;
915
916 err = -EINVAL;
917 if (oh.len != nbytes)
918 goto err_finish;
919
920 /*
921 * Zero oh.unique indicates unsolicited notification message
922 * and error contains notification code.
923 */
924 if (!oh.unique) {
925 err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), &cs);
926 fuse_copy_finish(&cs);
927 return err ? err : nbytes;
928 }
929
879 err = -EINVAL; 930 err = -EINVAL;
880 if (!oh.unique || oh.error <= -1000 || oh.error > 0 || 931 if (oh.error <= -1000 || oh.error > 0)
881 oh.len != nbytes)
882 goto err_finish; 932 goto err_finish;
883 933
884 spin_lock(&fc->lock); 934 spin_lock(&fc->lock);
@@ -966,6 +1016,8 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
966 * This function releases and reacquires fc->lock 1016 * This function releases and reacquires fc->lock
967 */ 1017 */
968static void end_requests(struct fuse_conn *fc, struct list_head *head) 1018static void end_requests(struct fuse_conn *fc, struct list_head *head)
1019__releases(&fc->lock)
1020__acquires(&fc->lock)
969{ 1021{
970 while (!list_empty(head)) { 1022 while (!list_empty(head)) {
971 struct fuse_req *req; 1023 struct fuse_req *req;
@@ -988,7 +1040,8 @@ static void end_requests(struct fuse_conn *fc, struct list_head *head)
988 * locked). 1040 * locked).
989 */ 1041 */
990static void end_io_requests(struct fuse_conn *fc) 1042static void end_io_requests(struct fuse_conn *fc)
991 __releases(fc->lock) __acquires(fc->lock) 1043__releases(&fc->lock)
1044__acquires(&fc->lock)
992{ 1045{
993 while (!list_empty(&fc->io)) { 1046 while (!list_empty(&fc->io)) {
994 struct fuse_req *req = 1047 struct fuse_req *req =
@@ -1002,11 +1055,11 @@ static void end_io_requests(struct fuse_conn *fc)
1002 wake_up(&req->waitq); 1055 wake_up(&req->waitq);
1003 if (end) { 1056 if (end) {
1004 req->end = NULL; 1057 req->end = NULL;
1005 /* The end function will consume this reference */
1006 __fuse_get_request(req); 1058 __fuse_get_request(req);
1007 spin_unlock(&fc->lock); 1059 spin_unlock(&fc->lock);
1008 wait_event(req->waitq, !req->locked); 1060 wait_event(req->waitq, !req->locked);
1009 end(fc, req); 1061 end(fc, req);
1062 fuse_put_request(fc, req);
1010 spin_lock(&fc->lock); 1063 spin_lock(&fc->lock);
1011 } 1064 }
1012 } 1065 }