diff options
-rw-r--r-- | fs/fuse/dir.c | 2 | ||||
-rw-r--r-- | fs/fuse/file.c | 62 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 2 |
3 files changed, 32 insertions, 34 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8b8eebc5614b..222584b34ce4 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1035,7 +1035,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
1035 | req->out.argpages = 1; | 1035 | req->out.argpages = 1; |
1036 | req->num_pages = 1; | 1036 | req->num_pages = 1; |
1037 | req->pages[0] = page; | 1037 | req->pages[0] = page; |
1038 | fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); | 1038 | fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, FUSE_READDIR); |
1039 | fuse_request_send(fc, req); | 1039 | fuse_request_send(fc, req); |
1040 | nbytes = req->out.args[0].size; | 1040 | nbytes = req->out.args[0].size; |
1041 | err = req->out.h.error; | 1041 | err = req->out.h.error; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 3be030105354..aa4a3876ca37 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -379,8 +379,8 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync) | |||
379 | return fuse_fsync_common(file, de, datasync, 0); | 379 | return fuse_fsync_common(file, de, datasync, 0); |
380 | } | 380 | } |
381 | 381 | ||
382 | void fuse_read_fill(struct fuse_req *req, struct file *file, | 382 | void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, |
383 | struct inode *inode, loff_t pos, size_t count, int opcode) | 383 | size_t count, int opcode) |
384 | { | 384 | { |
385 | struct fuse_read_in *inarg = &req->misc.read.in; | 385 | struct fuse_read_in *inarg = &req->misc.read.in; |
386 | struct fuse_file *ff = file->private_data; | 386 | struct fuse_file *ff = file->private_data; |
@@ -390,7 +390,7 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, | |||
390 | inarg->size = count; | 390 | inarg->size = count; |
391 | inarg->flags = file->f_flags; | 391 | inarg->flags = file->f_flags; |
392 | req->in.h.opcode = opcode; | 392 | req->in.h.opcode = opcode; |
393 | req->in.h.nodeid = get_node_id(inode); | 393 | req->in.h.nodeid = ff->nodeid; |
394 | req->in.numargs = 1; | 394 | req->in.numargs = 1; |
395 | req->in.args[0].size = sizeof(struct fuse_read_in); | 395 | req->in.args[0].size = sizeof(struct fuse_read_in); |
396 | req->in.args[0].value = inarg; | 396 | req->in.args[0].value = inarg; |
@@ -400,12 +400,12 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, | |||
400 | } | 400 | } |
401 | 401 | ||
402 | static size_t fuse_send_read(struct fuse_req *req, struct file *file, | 402 | static size_t fuse_send_read(struct fuse_req *req, struct file *file, |
403 | struct inode *inode, loff_t pos, size_t count, | 403 | loff_t pos, size_t count, fl_owner_t owner) |
404 | fl_owner_t owner) | ||
405 | { | 404 | { |
406 | struct fuse_conn *fc = get_fuse_conn(inode); | 405 | struct fuse_file *ff = file->private_data; |
406 | struct fuse_conn *fc = ff->fc; | ||
407 | 407 | ||
408 | fuse_read_fill(req, file, inode, pos, count, FUSE_READ); | 408 | fuse_read_fill(req, file, pos, count, FUSE_READ); |
409 | if (owner != NULL) { | 409 | if (owner != NULL) { |
410 | struct fuse_read_in *inarg = &req->misc.read.in; | 410 | struct fuse_read_in *inarg = &req->misc.read.in; |
411 | 411 | ||
@@ -463,7 +463,7 @@ static int fuse_readpage(struct file *file, struct page *page) | |||
463 | req->out.argpages = 1; | 463 | req->out.argpages = 1; |
464 | req->num_pages = 1; | 464 | req->num_pages = 1; |
465 | req->pages[0] = page; | 465 | req->pages[0] = page; |
466 | num_read = fuse_send_read(req, file, inode, pos, count, NULL); | 466 | num_read = fuse_send_read(req, file, pos, count, NULL); |
467 | err = req->out.h.error; | 467 | err = req->out.h.error; |
468 | fuse_put_request(fc, req); | 468 | fuse_put_request(fc, req); |
469 | 469 | ||
@@ -512,19 +512,18 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req) | |||
512 | fuse_file_put(req->ff); | 512 | fuse_file_put(req->ff); |
513 | } | 513 | } |
514 | 514 | ||
515 | static void fuse_send_readpages(struct fuse_req *req, struct file *file, | 515 | static void fuse_send_readpages(struct fuse_req *req, struct file *file) |
516 | struct inode *inode) | ||
517 | { | 516 | { |
518 | struct fuse_conn *fc = get_fuse_conn(inode); | 517 | struct fuse_file *ff = file->private_data; |
518 | struct fuse_conn *fc = ff->fc; | ||
519 | loff_t pos = page_offset(req->pages[0]); | 519 | loff_t pos = page_offset(req->pages[0]); |
520 | size_t count = req->num_pages << PAGE_CACHE_SHIFT; | 520 | size_t count = req->num_pages << PAGE_CACHE_SHIFT; |
521 | 521 | ||
522 | req->out.argpages = 1; | 522 | req->out.argpages = 1; |
523 | req->out.page_zeroing = 1; | 523 | req->out.page_zeroing = 1; |
524 | fuse_read_fill(req, file, inode, pos, count, FUSE_READ); | 524 | fuse_read_fill(req, file, pos, count, FUSE_READ); |
525 | req->misc.read.attr_ver = fuse_get_attr_version(fc); | 525 | req->misc.read.attr_ver = fuse_get_attr_version(fc); |
526 | if (fc->async_read) { | 526 | if (fc->async_read) { |
527 | struct fuse_file *ff = file->private_data; | ||
528 | req->ff = fuse_file_get(ff); | 527 | req->ff = fuse_file_get(ff); |
529 | req->end = fuse_readpages_end; | 528 | req->end = fuse_readpages_end; |
530 | fuse_request_send_background(fc, req); | 529 | fuse_request_send_background(fc, req); |
@@ -554,7 +553,7 @@ static int fuse_readpages_fill(void *_data, struct page *page) | |||
554 | (req->num_pages == FUSE_MAX_PAGES_PER_REQ || | 553 | (req->num_pages == FUSE_MAX_PAGES_PER_REQ || |
555 | (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read || | 554 | (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read || |
556 | req->pages[req->num_pages - 1]->index + 1 != page->index)) { | 555 | req->pages[req->num_pages - 1]->index + 1 != page->index)) { |
557 | fuse_send_readpages(req, data->file, inode); | 556 | fuse_send_readpages(req, data->file); |
558 | data->req = req = fuse_get_req(fc); | 557 | data->req = req = fuse_get_req(fc); |
559 | if (IS_ERR(req)) { | 558 | if (IS_ERR(req)) { |
560 | unlock_page(page); | 559 | unlock_page(page); |
@@ -588,7 +587,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, | |||
588 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); | 587 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); |
589 | if (!err) { | 588 | if (!err) { |
590 | if (data.req->num_pages) | 589 | if (data.req->num_pages) |
591 | fuse_send_readpages(data.req, file, inode); | 590 | fuse_send_readpages(data.req, file); |
592 | else | 591 | else |
593 | fuse_put_request(fc, data.req); | 592 | fuse_put_request(fc, data.req); |
594 | } | 593 | } |
@@ -616,9 +615,8 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
616 | } | 615 | } |
617 | 616 | ||
618 | static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, | 617 | static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, |
619 | struct inode *inode, loff_t pos, size_t count) | 618 | loff_t pos, size_t count) |
620 | { | 619 | { |
621 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
622 | struct fuse_write_in *inarg = &req->misc.write.in; | 620 | struct fuse_write_in *inarg = &req->misc.write.in; |
623 | struct fuse_write_out *outarg = &req->misc.write.out; | 621 | struct fuse_write_out *outarg = &req->misc.write.out; |
624 | 622 | ||
@@ -626,9 +624,9 @@ static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, | |||
626 | inarg->offset = pos; | 624 | inarg->offset = pos; |
627 | inarg->size = count; | 625 | inarg->size = count; |
628 | req->in.h.opcode = FUSE_WRITE; | 626 | req->in.h.opcode = FUSE_WRITE; |
629 | req->in.h.nodeid = get_node_id(inode); | 627 | req->in.h.nodeid = ff->nodeid; |
630 | req->in.numargs = 2; | 628 | req->in.numargs = 2; |
631 | if (fc->minor < 9) | 629 | if (ff->fc->minor < 9) |
632 | req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE; | 630 | req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE; |
633 | else | 631 | else |
634 | req->in.args[0].size = sizeof(struct fuse_write_in); | 632 | req->in.args[0].size = sizeof(struct fuse_write_in); |
@@ -640,13 +638,13 @@ static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, | |||
640 | } | 638 | } |
641 | 639 | ||
642 | static size_t fuse_send_write(struct fuse_req *req, struct file *file, | 640 | static size_t fuse_send_write(struct fuse_req *req, struct file *file, |
643 | struct inode *inode, loff_t pos, size_t count, | 641 | loff_t pos, size_t count, fl_owner_t owner) |
644 | fl_owner_t owner) | ||
645 | { | 642 | { |
646 | struct fuse_conn *fc = get_fuse_conn(inode); | 643 | struct fuse_file *ff = file->private_data; |
644 | struct fuse_conn *fc = ff->fc; | ||
647 | struct fuse_write_in *inarg = &req->misc.write.in; | 645 | struct fuse_write_in *inarg = &req->misc.write.in; |
648 | 646 | ||
649 | fuse_write_fill(req, file->private_data, inode, pos, count); | 647 | fuse_write_fill(req, ff, pos, count); |
650 | inarg->flags = file->f_flags; | 648 | inarg->flags = file->f_flags; |
651 | if (owner != NULL) { | 649 | if (owner != NULL) { |
652 | inarg->write_flags |= FUSE_WRITE_LOCKOWNER; | 650 | inarg->write_flags |= FUSE_WRITE_LOCKOWNER; |
@@ -706,7 +704,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode, | |||
706 | req->num_pages = 1; | 704 | req->num_pages = 1; |
707 | req->pages[0] = page; | 705 | req->pages[0] = page; |
708 | req->page_offset = offset; | 706 | req->page_offset = offset; |
709 | nres = fuse_send_write(req, file, inode, pos, count, NULL); | 707 | nres = fuse_send_write(req, file, pos, count, NULL); |
710 | err = req->out.h.error; | 708 | err = req->out.h.error; |
711 | fuse_put_request(fc, req); | 709 | fuse_put_request(fc, req); |
712 | if (!err && !nres) | 710 | if (!err && !nres) |
@@ -747,7 +745,7 @@ static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file, | |||
747 | for (i = 0; i < req->num_pages; i++) | 745 | for (i = 0; i < req->num_pages; i++) |
748 | fuse_wait_on_page_writeback(inode, req->pages[i]->index); | 746 | fuse_wait_on_page_writeback(inode, req->pages[i]->index); |
749 | 747 | ||
750 | res = fuse_send_write(req, file, inode, pos, count, NULL); | 748 | res = fuse_send_write(req, file, pos, count, NULL); |
751 | 749 | ||
752 | offset = req->page_offset; | 750 | offset = req->page_offset; |
753 | count = res; | 751 | count = res; |
@@ -988,8 +986,8 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf, | |||
988 | static ssize_t fuse_direct_io(struct file *file, const char __user *buf, | 986 | static ssize_t fuse_direct_io(struct file *file, const char __user *buf, |
989 | size_t count, loff_t *ppos, int write) | 987 | size_t count, loff_t *ppos, int write) |
990 | { | 988 | { |
991 | struct inode *inode = file->f_path.dentry->d_inode; | 989 | struct fuse_file *ff = file->private_data; |
992 | struct fuse_conn *fc = get_fuse_conn(inode); | 990 | struct fuse_conn *fc = ff->fc; |
993 | size_t nmax = write ? fc->max_write : fc->max_read; | 991 | size_t nmax = write ? fc->max_write : fc->max_read; |
994 | loff_t pos = *ppos; | 992 | loff_t pos = *ppos; |
995 | ssize_t res = 0; | 993 | ssize_t res = 0; |
@@ -1001,6 +999,7 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, | |||
1001 | 999 | ||
1002 | while (count) { | 1000 | while (count) { |
1003 | size_t nres; | 1001 | size_t nres; |
1002 | fl_owner_t owner = current->files; | ||
1004 | size_t nbytes = min(count, nmax); | 1003 | size_t nbytes = min(count, nmax); |
1005 | int err = fuse_get_user_pages(req, buf, &nbytes, write); | 1004 | int err = fuse_get_user_pages(req, buf, &nbytes, write); |
1006 | if (err) { | 1005 | if (err) { |
@@ -1009,11 +1008,10 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, | |||
1009 | } | 1008 | } |
1010 | 1009 | ||
1011 | if (write) | 1010 | if (write) |
1012 | nres = fuse_send_write(req, file, inode, pos, nbytes, | 1011 | nres = fuse_send_write(req, file, pos, nbytes, owner); |
1013 | current->files); | ||
1014 | else | 1012 | else |
1015 | nres = fuse_send_read(req, file, inode, pos, nbytes, | 1013 | nres = fuse_send_read(req, file, pos, nbytes, owner); |
1016 | current->files); | 1014 | |
1017 | fuse_release_user_pages(req, !write); | 1015 | fuse_release_user_pages(req, !write); |
1018 | if (req->out.h.error) { | 1016 | if (req->out.h.error) { |
1019 | if (!res) | 1017 | if (!res) |
@@ -1196,7 +1194,7 @@ static int fuse_writepage_locked(struct page *page) | |||
1196 | req->ff = fuse_file_get(ff); | 1194 | req->ff = fuse_file_get(ff); |
1197 | spin_unlock(&fc->lock); | 1195 | spin_unlock(&fc->lock); |
1198 | 1196 | ||
1199 | fuse_write_fill(req, ff, inode, page_offset(page), 0); | 1197 | fuse_write_fill(req, ff, page_offset(page), 0); |
1200 | 1198 | ||
1201 | copy_highpage(tmp_page, page); | 1199 | copy_highpage(tmp_page, page); |
1202 | req->misc.write.in.write_flags |= FUSE_WRITE_CACHE; | 1200 | req->misc.write.in.write_flags |= FUSE_WRITE_CACHE; |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 4469d9971588..a51f63c7d423 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -520,7 +520,7 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, | |||
520 | * Initialize READ or READDIR request | 520 | * Initialize READ or READDIR request |
521 | */ | 521 | */ |
522 | void fuse_read_fill(struct fuse_req *req, struct file *file, | 522 | void fuse_read_fill(struct fuse_req *req, struct file *file, |
523 | struct inode *inode, loff_t pos, size_t count, int opcode); | 523 | loff_t pos, size_t count, int opcode); |
524 | 524 | ||
525 | /** | 525 | /** |
526 | * Send OPEN or OPENDIR request | 526 | * Send OPEN or OPENDIR request |