aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/file.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-01-06 03:19:42 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:56 -0500
commit6ad84acab972f4dfc78e6fdb04c419f82c497d29 (patch)
treed1a1370c158fbbf42b5e6d66e5f8046ac7bb9485 /fs/fuse/file.c
parent3ec870d524c9150add120475c8ddcfa50574f98e (diff)
[PATCH] fuse: ensure progress in read and write
In direct_io mode, send at least one page per reqest. Previously it was possible that reqests with zero data were sent, and hence the read/write didn't make any progress, resulting in an infinite (though interruptible) loop. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r--fs/fuse/file.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index c989f0e9456b..05dedddf4289 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -475,7 +475,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
475 475
476 nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT); 476 nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
477 npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 477 npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
478 npages = min(npages, FUSE_MAX_PAGES_PER_REQ); 478 npages = min(max(npages, 1), FUSE_MAX_PAGES_PER_REQ);
479 down_read(&current->mm->mmap_sem); 479 down_read(&current->mm->mmap_sem);
480 npages = get_user_pages(current, current->mm, user_addr, npages, write, 480 npages = get_user_pages(current, current->mm, user_addr, npages, write,
481 0, req->pages, NULL); 481 0, req->pages, NULL);
@@ -506,7 +506,6 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
506 return -EINTR; 506 return -EINTR;
507 507
508 while (count) { 508 while (count) {
509 size_t tmp;
510 size_t nres; 509 size_t nres;
511 size_t nbytes = min(count, nmax); 510 size_t nbytes = min(count, nmax);
512 int err = fuse_get_user_pages(req, buf, nbytes, !write); 511 int err = fuse_get_user_pages(req, buf, nbytes, !write);
@@ -514,8 +513,8 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
514 res = err; 513 res = err;
515 break; 514 break;
516 } 515 }
517 tmp = (req->num_pages << PAGE_SHIFT) - req->page_offset; 516 nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
518 nbytes = min(nbytes, tmp); 517 nbytes = min(count, nbytes);
519 if (write) 518 if (write)
520 nres = fuse_send_write(req, file, inode, pos, nbytes); 519 nres = fuse_send_write(req, file, inode, pos, nbytes);
521 else 520 else