diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 585c52dbb2e3..13cf7c260a83 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -992,7 +992,17 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, while (count) { if (cs->write && cs->pipebufs && page) { - return fuse_ref_page(cs, page, offset, count); + /* + * Can't control lifetime of pipe buffers, so always + * copy user pages. + */ + if (cs->req->user_pages) { + err = fuse_copy_fill(cs); + if (err) + return err; + } else { + return fuse_ref_page(cs, page, offset, count); + } } else if (!cs->len) { if (cs->move_pages && page && offset == 0 && count == PAGE_SIZE) { diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 8aef8e56eb1b..aa4f0d632bed 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1319,6 +1319,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii, (PAGE_SIZE - ret) & (PAGE_SIZE - 1); } + req->user_pages = true; if (write) req->in.argpages = 1; else diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 7e4b0e298bc7..6104534ddb7e 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -310,6 +310,8 @@ struct fuse_req { /** refcount */ atomic_t count; + bool user_pages; + /** Unique ID for the interrupt request */ u64 intr_unique;