Commit 6ad84aca authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds

[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: default avatarMiklos Szeredi <miklos@szeredi.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3ec870d5
...@@ -475,7 +475,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf, ...@@ -475,7 +475,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT); nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
npages = (nbytes + offset + PAGE_SIZE - 1) >> 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(&current->mm->mmap_sem); down_read(&current->mm->mmap_sem);
npages = get_user_pages(current, current->mm, user_addr, npages, write, npages = get_user_pages(current, current->mm, user_addr, npages, write,
0, req->pages, NULL); 0, req->pages, NULL);
...@@ -506,7 +506,6 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, ...@@ -506,7 +506,6 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
return -EINTR; return -EINTR;
while (count) { while (count) {
size_t tmp;
size_t nres; size_t nres;
size_t nbytes = min(count, nmax); size_t nbytes = min(count, nmax);
int err = fuse_get_user_pages(req, buf, nbytes, !write); 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,8 +513,8 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
res = err; res = err;
break; break;
} }
tmp = (req->num_pages << PAGE_SHIFT) - req->page_offset; nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
nbytes = min(nbytes, tmp); nbytes = min(count, nbytes);
if (write) if (write)
nres = fuse_send_write(req, file, inode, pos, nbytes); nres = fuse_send_write(req, file, inode, pos, nbytes);
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment