diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2019-09-10 09:04:10 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2019-09-10 10:29:49 -0400 |
commit | 43f5098eb82b1dbf3988cab0a26e729e88a004fc (patch) | |
tree | b4f6071991ce2e704ff5d66cd51041d90ecb3ff4 | |
parent | 134831e36bbdd6ce6c3ef623ddf6d9238f244ed3 (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.c | 36 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 23 | ||||
-rw-r--r-- | fs/fuse/readdir.c | 47 |
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 | ||
535 | void 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 | |||
555 | struct 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 | |||
571 | void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos, | 535 | void 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 | ||
831 | struct fuse_forget_link *fuse_alloc_forget(void); | 831 | struct 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 | */ |
836 | void fuse_read_fill(struct fuse_req *req, struct file *file, | 836 | struct 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 | |||
852 | void 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 | ||
317 | static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx) | 317 | static 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 | ||
377 | enum fuse_parse_result { | 370 | enum fuse_parse_result { |