[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>
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index c989f0e..05deddd 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -475,7 +475,7 @@
nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
- npages = min(npages, FUSE_MAX_PAGES_PER_REQ);
+ npages = min(max(npages, 1), FUSE_MAX_PAGES_PER_REQ);
down_read(¤t->mm->mmap_sem);
npages = get_user_pages(current, current->mm, user_addr, npages, write,
0, req->pages, NULL);
@@ -506,7 +506,6 @@
return -EINTR;
while (count) {
- size_t tmp;
size_t nres;
size_t nbytes = min(count, nmax);
int err = fuse_get_user_pages(req, buf, nbytes, !write);
@@ -514,8 +513,8 @@
res = err;
break;
}
- tmp = (req->num_pages << PAGE_SHIFT) - req->page_offset;
- nbytes = min(nbytes, tmp);
+ nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
+ nbytes = min(count, nbytes);
if (write)
nres = fuse_send_write(req, file, inode, pos, nbytes);
else