summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2019-09-10 09:04:10 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2019-09-10 10:29:49 -0400
commit43f5098eb82b1dbf3988cab0a26e729e88a004fc (patch)
treeb4f6071991ce2e704ff5d66cd51041d90ecb3ff4
parent134831e36bbdd6ce6c3ef623ddf6d9238f244ed3 (diff)
fuse: convert readdir to simple api
The old fuse_read_fill() helper can be deleted, now that the last user is gone. The fuse_io_args struct is moved to fuse_i.h so it can be shared between readdir/read code. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/fuse/file.c36
-rw-r--r--fs/fuse/fuse_i.h23
-rw-r--r--fs/fuse/readdir.c47
3 files changed, 40 insertions, 66 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index ac2323443c09..3cb98ff267cf 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -532,42 +532,6 @@ out:
532 return err; 532 return err;
533} 533}
534 534
535void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos,
536 size_t count, int opcode)
537{
538 struct fuse_read_in *inarg = &req->misc.read.in;
539 struct fuse_file *ff = file->private_data;
540
541 inarg->fh = ff->fh;
542 inarg->offset = pos;
543 inarg->size = count;
544 inarg->flags = file->f_flags;
545 req->in.h.opcode = opcode;
546 req->in.h.nodeid = ff->nodeid;
547 req->in.numargs = 1;
548 req->in.args[0].size = sizeof(struct fuse_read_in);
549 req->in.args[0].value = inarg;
550 req->out.argvar = 1;
551 req->out.numargs = 1;
552 req->out.args[0].size = count;
553}
554
555struct fuse_io_args {
556 union {
557 struct {
558 struct fuse_read_in in;
559 u64 attr_ver;
560 } read;
561 struct {
562 struct fuse_write_in in;
563 struct fuse_write_out out;
564 } write;
565 };
566 struct fuse_args_pages ap;
567 struct fuse_io_priv *io;
568 struct fuse_file *ff;
569};
570
571void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos, 535void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos,
572 size_t count, int opcode) 536 size_t count, int opcode)
573{ 537{
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 8f46c5549e57..4d7cd20967c2 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -830,11 +830,28 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
830 830
831struct fuse_forget_link *fuse_alloc_forget(void); 831struct fuse_forget_link *fuse_alloc_forget(void);
832 832
833/** 833/*
834 * Initialize READ or READDIR request 834 * Initialize READ or READDIR request
835 */ 835 */
836void fuse_read_fill(struct fuse_req *req, struct file *file, 836struct fuse_io_args {
837 loff_t pos, size_t count, int opcode); 837 union {
838 struct {
839 struct fuse_read_in in;
840 u64 attr_ver;
841 } read;
842 struct {
843 struct fuse_write_in in;
844 struct fuse_write_out out;
845 } write;
846 };
847 struct fuse_args_pages ap;
848 struct fuse_io_priv *io;
849 struct fuse_file *ff;
850};
851
852void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos,
853 size_t count, int opcode);
854
838 855
839/** 856/**
840 * Send OPEN or OPENDIR request 857 * Send OPEN or OPENDIR request
diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c
index 56a19faa855d..fae025db06f4 100644
--- a/fs/fuse/readdir.c
+++ b/fs/fuse/readdir.c
@@ -316,62 +316,55 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
316 316
317static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx) 317static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
318{ 318{
319 int plus, err; 319 int plus;
320 size_t nbytes; 320 ssize_t res;
321 struct page *page; 321 struct page *page;
322 struct inode *inode = file_inode(file); 322 struct inode *inode = file_inode(file);
323 struct fuse_conn *fc = get_fuse_conn(inode); 323 struct fuse_conn *fc = get_fuse_conn(inode);
324 struct fuse_req *req; 324 struct fuse_io_args ia = {};
325 struct fuse_args_pages *ap = &ia.ap;
326 struct fuse_page_desc desc = { .length = PAGE_SIZE };
325 u64 attr_version = 0; 327 u64 attr_version = 0;
326 bool locked; 328 bool locked;
327 329
328 req = fuse_get_req(fc, 1);
329 if (IS_ERR(req))
330 return PTR_ERR(req);
331
332 page = alloc_page(GFP_KERNEL); 330 page = alloc_page(GFP_KERNEL);
333 if (!page) { 331 if (!page)
334 fuse_put_request(fc, req);
335 return -ENOMEM; 332 return -ENOMEM;
336 }
337 333
338 plus = fuse_use_readdirplus(inode, ctx); 334 plus = fuse_use_readdirplus(inode, ctx);
339 req->out.argpages = 1; 335 ap->args.out_pages = 1;
340 req->num_pages = 1; 336 ap->num_pages = 1;
341 req->pages[0] = page; 337 ap->pages = &page;
342 req->page_descs[0].length = PAGE_SIZE; 338 ap->descs = &desc;
343 if (plus) { 339 if (plus) {
344 attr_version = fuse_get_attr_version(fc); 340 attr_version = fuse_get_attr_version(fc);
345 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, 341 fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
346 FUSE_READDIRPLUS); 342 FUSE_READDIRPLUS);
347 } else { 343 } else {
348 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, 344 fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
349 FUSE_READDIR); 345 FUSE_READDIR);
350 } 346 }
351 locked = fuse_lock_inode(inode); 347 locked = fuse_lock_inode(inode);
352 fuse_request_send(fc, req); 348 res = fuse_simple_request(fc, &ap->args);
353 fuse_unlock_inode(inode, locked); 349 fuse_unlock_inode(inode, locked);
354 nbytes = req->out.args[0].size; 350 if (res >= 0) {
355 err = req->out.h.error; 351 if (!res) {
356 fuse_put_request(fc, req);
357 if (!err) {
358 if (!nbytes) {
359 struct fuse_file *ff = file->private_data; 352 struct fuse_file *ff = file->private_data;
360 353
361 if (ff->open_flags & FOPEN_CACHE_DIR) 354 if (ff->open_flags & FOPEN_CACHE_DIR)
362 fuse_readdir_cache_end(file, ctx->pos); 355 fuse_readdir_cache_end(file, ctx->pos);
363 } else if (plus) { 356 } else if (plus) {
364 err = parse_dirplusfile(page_address(page), nbytes, 357 res = parse_dirplusfile(page_address(page), res,
365 file, ctx, attr_version); 358 file, ctx, attr_version);
366 } else { 359 } else {
367 err = parse_dirfile(page_address(page), nbytes, file, 360 res = parse_dirfile(page_address(page), res, file,
368 ctx); 361 ctx);
369 } 362 }
370 } 363 }
371 364
372 __free_page(page); 365 __free_page(page);
373 fuse_invalidate_atime(inode); 366 fuse_invalidate_atime(inode);
374 return err; 367 return res;
375} 368}
376 369
377enum fuse_parse_result { 370enum fuse_parse_result {