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: mm: export generic_pipe_buf_*() to modules fuse: support splice() reading from fuse device fuse: allow splice to move pages mm: export remove_from_page_cache() to modules mm: export lru_cache_add_*() to modules fuse: support splice() writing to fuse device fuse: get page reference for readpages fuse: use get_user_pages_fast() fuse: remove unneeded variable
This commit is contained in:
@@ -516,18 +516,27 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
|
||||
int i;
|
||||
size_t count = req->misc.read.in.size;
|
||||
size_t num_read = req->out.args[0].size;
|
||||
struct inode *inode = req->pages[0]->mapping->host;
|
||||
struct address_space *mapping = NULL;
|
||||
|
||||
/*
|
||||
* Short read means EOF. If file size is larger, truncate it
|
||||
*/
|
||||
if (!req->out.h.error && num_read < count) {
|
||||
loff_t pos = page_offset(req->pages[0]) + num_read;
|
||||
fuse_read_update_size(inode, pos, req->misc.read.attr_ver);
|
||||
for (i = 0; mapping == NULL && i < req->num_pages; i++)
|
||||
mapping = req->pages[i]->mapping;
|
||||
|
||||
if (mapping) {
|
||||
struct inode *inode = mapping->host;
|
||||
|
||||
/*
|
||||
* Short read means EOF. If file size is larger, truncate it
|
||||
*/
|
||||
if (!req->out.h.error && num_read < count) {
|
||||
loff_t pos;
|
||||
|
||||
pos = page_offset(req->pages[0]) + num_read;
|
||||
fuse_read_update_size(inode, pos,
|
||||
req->misc.read.attr_ver);
|
||||
}
|
||||
fuse_invalidate_attr(inode); /* atime changed */
|
||||
}
|
||||
|
||||
fuse_invalidate_attr(inode); /* atime changed */
|
||||
|
||||
for (i = 0; i < req->num_pages; i++) {
|
||||
struct page *page = req->pages[i];
|
||||
if (!req->out.h.error)
|
||||
@@ -535,6 +544,7 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
|
||||
else
|
||||
SetPageError(page);
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
}
|
||||
if (req->ff)
|
||||
fuse_file_put(req->ff);
|
||||
@@ -549,6 +559,7 @@ static void fuse_send_readpages(struct fuse_req *req, struct file *file)
|
||||
|
||||
req->out.argpages = 1;
|
||||
req->out.page_zeroing = 1;
|
||||
req->out.page_replace = 1;
|
||||
fuse_read_fill(req, file, pos, count, FUSE_READ);
|
||||
req->misc.read.attr_ver = fuse_get_attr_version(fc);
|
||||
if (fc->async_read) {
|
||||
@@ -588,6 +599,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
|
||||
return PTR_ERR(req);
|
||||
}
|
||||
}
|
||||
page_cache_get(page);
|
||||
req->pages[req->num_pages] = page;
|
||||
req->num_pages++;
|
||||
return 0;
|
||||
@@ -993,10 +1005,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
|
||||
nbytes = min_t(size_t, nbytes, FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
|
||||
npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
npages = clamp(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);
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
npages = get_user_pages_fast(user_addr, npages, !write, req->pages);
|
||||
if (npages < 0)
|
||||
return npages;
|
||||
|
||||
@@ -1579,9 +1588,9 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
|
||||
while (iov_iter_count(&ii)) {
|
||||
struct page *page = pages[page_idx++];
|
||||
size_t todo = min_t(size_t, PAGE_SIZE, iov_iter_count(&ii));
|
||||
void *kaddr, *map;
|
||||
void *kaddr;
|
||||
|
||||
kaddr = map = kmap(page);
|
||||
kaddr = kmap(page);
|
||||
|
||||
while (todo) {
|
||||
char __user *uaddr = ii.iov->iov_base + ii.iov_offset;
|
||||
|
||||
Reference in New Issue
Block a user