diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2014-12-12 03:49:05 -0500 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2014-12-12 03:49:05 -0500 |
commit | 7078187a795f862465325bcadf3070867c0cb5f8 (patch) | |
tree | 1ea2a3c04a18b9c00909c7ebcef925b96f9a7f80 /fs/fuse/file.c | |
parent | f704dcb538eb80b7f5b26281a79b8e29a8e24d62 (diff) |
fuse: introduce fuse_simple_request() helper
The following pattern is repeated many times:
req = fuse_get_req_nopages(fc);
/* Initialize req->(in|out).args */
fuse_request_send(fc, req);
err = req->out.h.error;
fuse_put_request(req);
Create a new replacement helper:
/* Initialize args */
err = fuse_simple_request(fc, &args);
In addition to reducing the code size, this will ease moving from the
complex arg-based to a simpler page-based I/O on the fuse device.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r-- | fs/fuse/file.c | 189 |
1 files changed, 72 insertions, 117 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 2d4ae68943bb..e8729ac30762 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -24,30 +24,22 @@ static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, | |||
24 | int opcode, struct fuse_open_out *outargp) | 24 | int opcode, struct fuse_open_out *outargp) |
25 | { | 25 | { |
26 | struct fuse_open_in inarg; | 26 | struct fuse_open_in inarg; |
27 | struct fuse_req *req; | 27 | FUSE_ARGS(args); |
28 | int err; | ||
29 | |||
30 | req = fuse_get_req_nopages(fc); | ||
31 | if (IS_ERR(req)) | ||
32 | return PTR_ERR(req); | ||
33 | 28 | ||
34 | memset(&inarg, 0, sizeof(inarg)); | 29 | memset(&inarg, 0, sizeof(inarg)); |
35 | inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); | 30 | inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); |
36 | if (!fc->atomic_o_trunc) | 31 | if (!fc->atomic_o_trunc) |
37 | inarg.flags &= ~O_TRUNC; | 32 | inarg.flags &= ~O_TRUNC; |
38 | req->in.h.opcode = opcode; | 33 | args.in.h.opcode = opcode; |
39 | req->in.h.nodeid = nodeid; | 34 | args.in.h.nodeid = nodeid; |
40 | req->in.numargs = 1; | 35 | args.in.numargs = 1; |
41 | req->in.args[0].size = sizeof(inarg); | 36 | args.in.args[0].size = sizeof(inarg); |
42 | req->in.args[0].value = &inarg; | 37 | args.in.args[0].value = &inarg; |
43 | req->out.numargs = 1; | 38 | args.out.numargs = 1; |
44 | req->out.args[0].size = sizeof(*outargp); | 39 | args.out.args[0].size = sizeof(*outargp); |
45 | req->out.args[0].value = outargp; | 40 | args.out.args[0].value = outargp; |
46 | fuse_request_send(fc, req); | ||
47 | err = req->out.h.error; | ||
48 | fuse_put_request(fc, req); | ||
49 | 41 | ||
50 | return err; | 42 | return fuse_simple_request(fc, &args); |
51 | } | 43 | } |
52 | 44 | ||
53 | struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) | 45 | struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) |
@@ -451,7 +443,7 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, | |||
451 | struct inode *inode = file->f_mapping->host; | 443 | struct inode *inode = file->f_mapping->host; |
452 | struct fuse_conn *fc = get_fuse_conn(inode); | 444 | struct fuse_conn *fc = get_fuse_conn(inode); |
453 | struct fuse_file *ff = file->private_data; | 445 | struct fuse_file *ff = file->private_data; |
454 | struct fuse_req *req; | 446 | FUSE_ARGS(args); |
455 | struct fuse_fsync_in inarg; | 447 | struct fuse_fsync_in inarg; |
456 | int err; | 448 | int err; |
457 | 449 | ||
@@ -477,23 +469,15 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, | |||
477 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) | 469 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) |
478 | goto out; | 470 | goto out; |
479 | 471 | ||
480 | req = fuse_get_req_nopages(fc); | ||
481 | if (IS_ERR(req)) { | ||
482 | err = PTR_ERR(req); | ||
483 | goto out; | ||
484 | } | ||
485 | |||
486 | memset(&inarg, 0, sizeof(inarg)); | 472 | memset(&inarg, 0, sizeof(inarg)); |
487 | inarg.fh = ff->fh; | 473 | inarg.fh = ff->fh; |
488 | inarg.fsync_flags = datasync ? 1 : 0; | 474 | inarg.fsync_flags = datasync ? 1 : 0; |
489 | req->in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC; | 475 | args.in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC; |
490 | req->in.h.nodeid = get_node_id(inode); | 476 | args.in.h.nodeid = get_node_id(inode); |
491 | req->in.numargs = 1; | 477 | args.in.numargs = 1; |
492 | req->in.args[0].size = sizeof(inarg); | 478 | args.in.args[0].size = sizeof(inarg); |
493 | req->in.args[0].value = &inarg; | 479 | args.in.args[0].value = &inarg; |
494 | fuse_request_send(fc, req); | 480 | err = fuse_simple_request(fc, &args); |
495 | err = req->out.h.error; | ||
496 | fuse_put_request(fc, req); | ||
497 | if (err == -ENOSYS) { | 481 | if (err == -ENOSYS) { |
498 | if (isdir) | 482 | if (isdir) |
499 | fc->no_fsyncdir = 1; | 483 | fc->no_fsyncdir = 1; |
@@ -2127,49 +2111,44 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl, | |||
2127 | return 0; | 2111 | return 0; |
2128 | } | 2112 | } |
2129 | 2113 | ||
2130 | static void fuse_lk_fill(struct fuse_req *req, struct file *file, | 2114 | static void fuse_lk_fill(struct fuse_args *args, struct file *file, |
2131 | const struct file_lock *fl, int opcode, pid_t pid, | 2115 | const struct file_lock *fl, int opcode, pid_t pid, |
2132 | int flock) | 2116 | int flock, struct fuse_lk_in *inarg) |
2133 | { | 2117 | { |
2134 | struct inode *inode = file_inode(file); | 2118 | struct inode *inode = file_inode(file); |
2135 | struct fuse_conn *fc = get_fuse_conn(inode); | 2119 | struct fuse_conn *fc = get_fuse_conn(inode); |
2136 | struct fuse_file *ff = file->private_data; | 2120 | struct fuse_file *ff = file->private_data; |
2137 | struct fuse_lk_in *arg = &req->misc.lk_in; | 2121 | |
2138 | 2122 | memset(inarg, 0, sizeof(*inarg)); | |
2139 | arg->fh = ff->fh; | 2123 | inarg->fh = ff->fh; |
2140 | arg->owner = fuse_lock_owner_id(fc, fl->fl_owner); | 2124 | inarg->owner = fuse_lock_owner_id(fc, fl->fl_owner); |
2141 | arg->lk.start = fl->fl_start; | 2125 | inarg->lk.start = fl->fl_start; |
2142 | arg->lk.end = fl->fl_end; | 2126 | inarg->lk.end = fl->fl_end; |
2143 | arg->lk.type = fl->fl_type; | 2127 | inarg->lk.type = fl->fl_type; |
2144 | arg->lk.pid = pid; | 2128 | inarg->lk.pid = pid; |
2145 | if (flock) | 2129 | if (flock) |
2146 | arg->lk_flags |= FUSE_LK_FLOCK; | 2130 | inarg->lk_flags |= FUSE_LK_FLOCK; |
2147 | req->in.h.opcode = opcode; | 2131 | args->in.h.opcode = opcode; |
2148 | req->in.h.nodeid = get_node_id(inode); | 2132 | args->in.h.nodeid = get_node_id(inode); |
2149 | req->in.numargs = 1; | 2133 | args->in.numargs = 1; |
2150 | req->in.args[0].size = sizeof(*arg); | 2134 | args->in.args[0].size = sizeof(*inarg); |
2151 | req->in.args[0].value = arg; | 2135 | args->in.args[0].value = inarg; |
2152 | } | 2136 | } |
2153 | 2137 | ||
2154 | static int fuse_getlk(struct file *file, struct file_lock *fl) | 2138 | static int fuse_getlk(struct file *file, struct file_lock *fl) |
2155 | { | 2139 | { |
2156 | struct inode *inode = file_inode(file); | 2140 | struct inode *inode = file_inode(file); |
2157 | struct fuse_conn *fc = get_fuse_conn(inode); | 2141 | struct fuse_conn *fc = get_fuse_conn(inode); |
2158 | struct fuse_req *req; | 2142 | FUSE_ARGS(args); |
2143 | struct fuse_lk_in inarg; | ||
2159 | struct fuse_lk_out outarg; | 2144 | struct fuse_lk_out outarg; |
2160 | int err; | 2145 | int err; |
2161 | 2146 | ||
2162 | req = fuse_get_req_nopages(fc); | 2147 | fuse_lk_fill(&args, file, fl, FUSE_GETLK, 0, 0, &inarg); |
2163 | if (IS_ERR(req)) | 2148 | args.out.numargs = 1; |
2164 | return PTR_ERR(req); | 2149 | args.out.args[0].size = sizeof(outarg); |
2165 | 2150 | args.out.args[0].value = &outarg; | |
2166 | fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0); | 2151 | err = fuse_simple_request(fc, &args); |
2167 | req->out.numargs = 1; | ||
2168 | req->out.args[0].size = sizeof(outarg); | ||
2169 | req->out.args[0].value = &outarg; | ||
2170 | fuse_request_send(fc, req); | ||
2171 | err = req->out.h.error; | ||
2172 | fuse_put_request(fc, req); | ||
2173 | if (!err) | 2152 | if (!err) |
2174 | err = convert_fuse_file_lock(&outarg.lk, fl); | 2153 | err = convert_fuse_file_lock(&outarg.lk, fl); |
2175 | 2154 | ||
@@ -2180,7 +2159,8 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) | |||
2180 | { | 2159 | { |
2181 | struct inode *inode = file_inode(file); | 2160 | struct inode *inode = file_inode(file); |
2182 | struct fuse_conn *fc = get_fuse_conn(inode); | 2161 | struct fuse_conn *fc = get_fuse_conn(inode); |
2183 | struct fuse_req *req; | 2162 | FUSE_ARGS(args); |
2163 | struct fuse_lk_in inarg; | ||
2184 | int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK; | 2164 | int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK; |
2185 | pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0; | 2165 | pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0; |
2186 | int err; | 2166 | int err; |
@@ -2194,17 +2174,13 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) | |||
2194 | if (fl->fl_flags & FL_CLOSE) | 2174 | if (fl->fl_flags & FL_CLOSE) |
2195 | return 0; | 2175 | return 0; |
2196 | 2176 | ||
2197 | req = fuse_get_req_nopages(fc); | 2177 | fuse_lk_fill(&args, file, fl, opcode, pid, flock, &inarg); |
2198 | if (IS_ERR(req)) | 2178 | err = fuse_simple_request(fc, &args); |
2199 | return PTR_ERR(req); | ||
2200 | 2179 | ||
2201 | fuse_lk_fill(req, file, fl, opcode, pid, flock); | ||
2202 | fuse_request_send(fc, req); | ||
2203 | err = req->out.h.error; | ||
2204 | /* locking is restartable */ | 2180 | /* locking is restartable */ |
2205 | if (err == -EINTR) | 2181 | if (err == -EINTR) |
2206 | err = -ERESTARTSYS; | 2182 | err = -ERESTARTSYS; |
2207 | fuse_put_request(fc, req); | 2183 | |
2208 | return err; | 2184 | return err; |
2209 | } | 2185 | } |
2210 | 2186 | ||
@@ -2254,7 +2230,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) | |||
2254 | { | 2230 | { |
2255 | struct inode *inode = mapping->host; | 2231 | struct inode *inode = mapping->host; |
2256 | struct fuse_conn *fc = get_fuse_conn(inode); | 2232 | struct fuse_conn *fc = get_fuse_conn(inode); |
2257 | struct fuse_req *req; | 2233 | FUSE_ARGS(args); |
2258 | struct fuse_bmap_in inarg; | 2234 | struct fuse_bmap_in inarg; |
2259 | struct fuse_bmap_out outarg; | 2235 | struct fuse_bmap_out outarg; |
2260 | int err; | 2236 | int err; |
@@ -2262,24 +2238,18 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) | |||
2262 | if (!inode->i_sb->s_bdev || fc->no_bmap) | 2238 | if (!inode->i_sb->s_bdev || fc->no_bmap) |
2263 | return 0; | 2239 | return 0; |
2264 | 2240 | ||
2265 | req = fuse_get_req_nopages(fc); | ||
2266 | if (IS_ERR(req)) | ||
2267 | return 0; | ||
2268 | |||
2269 | memset(&inarg, 0, sizeof(inarg)); | 2241 | memset(&inarg, 0, sizeof(inarg)); |
2270 | inarg.block = block; | 2242 | inarg.block = block; |
2271 | inarg.blocksize = inode->i_sb->s_blocksize; | 2243 | inarg.blocksize = inode->i_sb->s_blocksize; |
2272 | req->in.h.opcode = FUSE_BMAP; | 2244 | args.in.h.opcode = FUSE_BMAP; |
2273 | req->in.h.nodeid = get_node_id(inode); | 2245 | args.in.h.nodeid = get_node_id(inode); |
2274 | req->in.numargs = 1; | 2246 | args.in.numargs = 1; |
2275 | req->in.args[0].size = sizeof(inarg); | 2247 | args.in.args[0].size = sizeof(inarg); |
2276 | req->in.args[0].value = &inarg; | 2248 | args.in.args[0].value = &inarg; |
2277 | req->out.numargs = 1; | 2249 | args.out.numargs = 1; |
2278 | req->out.args[0].size = sizeof(outarg); | 2250 | args.out.args[0].size = sizeof(outarg); |
2279 | req->out.args[0].value = &outarg; | 2251 | args.out.args[0].value = &outarg; |
2280 | fuse_request_send(fc, req); | 2252 | err = fuse_simple_request(fc, &args); |
2281 | err = req->out.h.error; | ||
2282 | fuse_put_request(fc, req); | ||
2283 | if (err == -ENOSYS) | 2253 | if (err == -ENOSYS) |
2284 | fc->no_bmap = 1; | 2254 | fc->no_bmap = 1; |
2285 | 2255 | ||
@@ -2747,7 +2717,7 @@ unsigned fuse_file_poll(struct file *file, poll_table *wait) | |||
2747 | struct fuse_conn *fc = ff->fc; | 2717 | struct fuse_conn *fc = ff->fc; |
2748 | struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh }; | 2718 | struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh }; |
2749 | struct fuse_poll_out outarg; | 2719 | struct fuse_poll_out outarg; |
2750 | struct fuse_req *req; | 2720 | FUSE_ARGS(args); |
2751 | int err; | 2721 | int err; |
2752 | 2722 | ||
2753 | if (fc->no_poll) | 2723 | if (fc->no_poll) |
@@ -2765,21 +2735,15 @@ unsigned fuse_file_poll(struct file *file, poll_table *wait) | |||
2765 | fuse_register_polled_file(fc, ff); | 2735 | fuse_register_polled_file(fc, ff); |
2766 | } | 2736 | } |
2767 | 2737 | ||
2768 | req = fuse_get_req_nopages(fc); | 2738 | args.in.h.opcode = FUSE_POLL; |
2769 | if (IS_ERR(req)) | 2739 | args.in.h.nodeid = ff->nodeid; |
2770 | return POLLERR; | 2740 | args.in.numargs = 1; |
2771 | 2741 | args.in.args[0].size = sizeof(inarg); | |
2772 | req->in.h.opcode = FUSE_POLL; | 2742 | args.in.args[0].value = &inarg; |
2773 | req->in.h.nodeid = ff->nodeid; | 2743 | args.out.numargs = 1; |
2774 | req->in.numargs = 1; | 2744 | args.out.args[0].size = sizeof(outarg); |
2775 | req->in.args[0].size = sizeof(inarg); | 2745 | args.out.args[0].value = &outarg; |
2776 | req->in.args[0].value = &inarg; | 2746 | err = fuse_simple_request(fc, &args); |
2777 | req->out.numargs = 1; | ||
2778 | req->out.args[0].size = sizeof(outarg); | ||
2779 | req->out.args[0].value = &outarg; | ||
2780 | fuse_request_send(fc, req); | ||
2781 | err = req->out.h.error; | ||
2782 | fuse_put_request(fc, req); | ||
2783 | 2747 | ||
2784 | if (!err) | 2748 | if (!err) |
2785 | return outarg.revents; | 2749 | return outarg.revents; |
@@ -2923,7 +2887,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2923 | struct inode *inode = file->f_inode; | 2887 | struct inode *inode = file->f_inode; |
2924 | struct fuse_inode *fi = get_fuse_inode(inode); | 2888 | struct fuse_inode *fi = get_fuse_inode(inode); |
2925 | struct fuse_conn *fc = ff->fc; | 2889 | struct fuse_conn *fc = ff->fc; |
2926 | struct fuse_req *req; | 2890 | FUSE_ARGS(args); |
2927 | struct fuse_fallocate_in inarg = { | 2891 | struct fuse_fallocate_in inarg = { |
2928 | .fh = ff->fh, | 2892 | .fh = ff->fh, |
2929 | .offset = offset, | 2893 | .offset = offset, |
@@ -2956,25 +2920,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2956 | if (!(mode & FALLOC_FL_KEEP_SIZE)) | 2920 | if (!(mode & FALLOC_FL_KEEP_SIZE)) |
2957 | set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); | 2921 | set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); |
2958 | 2922 | ||
2959 | req = fuse_get_req_nopages(fc); | 2923 | args.in.h.opcode = FUSE_FALLOCATE; |
2960 | if (IS_ERR(req)) { | 2924 | args.in.h.nodeid = ff->nodeid; |
2961 | err = PTR_ERR(req); | 2925 | args.in.numargs = 1; |
2962 | goto out; | 2926 | args.in.args[0].size = sizeof(inarg); |
2963 | } | 2927 | args.in.args[0].value = &inarg; |
2964 | 2928 | err = fuse_simple_request(fc, &args); | |
2965 | req->in.h.opcode = FUSE_FALLOCATE; | ||
2966 | req->in.h.nodeid = ff->nodeid; | ||
2967 | req->in.numargs = 1; | ||
2968 | req->in.args[0].size = sizeof(inarg); | ||
2969 | req->in.args[0].value = &inarg; | ||
2970 | fuse_request_send(fc, req); | ||
2971 | err = req->out.h.error; | ||
2972 | if (err == -ENOSYS) { | 2929 | if (err == -ENOSYS) { |
2973 | fc->no_fallocate = 1; | 2930 | fc->no_fallocate = 1; |
2974 | err = -EOPNOTSUPP; | 2931 | err = -EOPNOTSUPP; |
2975 | } | 2932 | } |
2976 | fuse_put_request(fc, req); | ||
2977 | |||
2978 | if (err) | 2933 | if (err) |
2979 | goto out; | 2934 | goto out; |
2980 | 2935 | ||