fuse: covert readpage to simple api
authorMiklos Szeredi <mszeredi@redhat.com>
Tue, 10 Sep 2019 13:04:09 +0000 (15:04 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Tue, 10 Sep 2019 14:29:49 +0000 (16:29 +0200)
Derive fuse_io_args from struct fuse_args_pages.  This will be used for
both synchronous and asynchronous read/write requests.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/file.c

index 8e67add..d927c33 100644 (file)
@@ -552,6 +552,33 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos,
        req->out.args[0].size = count;
 }
 
+struct fuse_io_args {
+       struct {
+               struct fuse_read_in in;
+       } read;
+       struct fuse_args_pages ap;
+};
+
+void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos,
+                        size_t count, int opcode)
+{
+       struct fuse_file *ff = file->private_data;
+       struct fuse_args *args = &ia->ap.args;
+
+       ia->read.in.fh = ff->fh;
+       ia->read.in.offset = pos;
+       ia->read.in.size = count;
+       ia->read.in.flags = file->f_flags;
+       args->opcode = opcode;
+       args->nodeid = ff->nodeid;
+       args->in_numargs = 1;
+       args->in_args[0].size = sizeof(ia->read.in);
+       args->in_args[0].value = &ia->read.in;
+       args->out_argvar = true;
+       args->out_numargs = 1;
+       args->out_args[0].size = count;
+}
+
 static void fuse_release_user_pages(struct fuse_req *req, bool should_dirty)
 {
        unsigned i;
@@ -732,16 +759,19 @@ static void fuse_short_read(struct inode *inode, u64 attr_ver, size_t num_read,
 
 static int fuse_do_readpage(struct file *file, struct page *page)
 {
-       struct kiocb iocb;
-       struct fuse_io_priv io;
        struct inode *inode = page->mapping->host;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       size_t num_read;
        loff_t pos = page_offset(page);
-       size_t count = PAGE_SIZE;
+       struct fuse_page_desc desc = { .length = PAGE_SIZE };
+       struct fuse_io_args ia = {
+               .ap.args.page_zeroing = true,
+               .ap.args.out_pages = true,
+               .ap.num_pages = 1,
+               .ap.pages = &page,
+               .ap.descs = &desc,
+       };
+       ssize_t res;
        u64 attr_ver;
-       int err;
 
        /*
         * Page writeback can extend beyond the lifetime of the
@@ -750,36 +780,22 @@ static int fuse_do_readpage(struct file *file, struct page *page)
         */
        fuse_wait_on_page_writeback(inode, page->index);
 
-       req = fuse_get_req(fc, 1);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
        attr_ver = fuse_get_attr_version(fc);
 
-       req->out.page_zeroing = 1;
-       req->out.argpages = 1;
-       req->num_pages = 1;
-       req->pages[0] = page;
-       req->page_descs[0].length = count;
-       init_sync_kiocb(&iocb, file);
-       io = (struct fuse_io_priv) FUSE_IO_PRIV_SYNC(&iocb);
-       num_read = fuse_send_read(req, &io, pos, count, NULL);
-       err = req->out.h.error;
-
-       if (!err) {
-               /*
-                * Short read means EOF.  If file size is larger, truncate it
-                */
-               if (num_read < count)
-                       fuse_short_read(inode, attr_ver, num_read, req->pages,
-                                       req->num_pages);
-
-               SetPageUptodate(page);
-       }
+       fuse_read_args_fill(&ia, file, pos, desc.length, FUSE_READ);
+       res = fuse_simple_request(fc, &ia.ap.args);
+       if (res < 0)
+               return res;
+       /*
+        * Short read means EOF.  If file size is larger, truncate it
+        */
+       if (res < desc.length)
+               fuse_short_read(inode, attr_ver, res, ia.ap.pages,
+                               ia.ap.num_pages);
 
-       fuse_put_request(fc, req);
+       SetPageUptodate(page);
 
-       return err;
+       return 0;
 }
 
 static int fuse_readpage(struct file *file, struct page *page)