diff options
| author | Miklos Szeredi <mszeredi@suse.cz> | 2009-04-28 10:56:37 -0400 |
|---|---|---|
| committer | Miklos Szeredi <mszeredi@suse.cz> | 2009-04-28 10:56:37 -0400 |
| commit | 91fe96b403f8a0a4a8a045a39b1bd549b0da7941 (patch) | |
| tree | 38188f1dff969c050b26093d806ae0092f8c30b9 | |
| parent | c7b7143c6342b8751d47b03a025ac5c0ac1ae809 (diff) | |
fuse: create fuse_do_open() helper for CUSE
Create a helper for sending an OPEN request that doesn't need a struct
inode pointer.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
| -rw-r--r-- | fs/fuse/dir.c | 2 | ||||
| -rw-r--r-- | fs/fuse/file.c | 65 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 2 |
3 files changed, 42 insertions, 27 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index da87a3d8a8ea..faa3b2f86740 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -1103,7 +1103,7 @@ static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c) | |||
| 1103 | 1103 | ||
| 1104 | static int fuse_dir_open(struct inode *inode, struct file *file) | 1104 | static int fuse_dir_open(struct inode *inode, struct file *file) |
| 1105 | { | 1105 | { |
| 1106 | return fuse_open_common(inode, file, 1); | 1106 | return fuse_open_common(inode, file, true); |
| 1107 | } | 1107 | } |
| 1108 | 1108 | ||
| 1109 | static int fuse_dir_release(struct inode *inode, struct file *file) | 1109 | static int fuse_dir_release(struct inode *inode, struct file *file) |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index d9458cace425..6bdaa55ae613 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -15,10 +15,9 @@ | |||
| 15 | 15 | ||
| 16 | static const struct file_operations fuse_direct_io_file_operations; | 16 | static const struct file_operations fuse_direct_io_file_operations; |
| 17 | 17 | ||
| 18 | static int fuse_send_open(struct inode *inode, struct file *file, int isdir, | 18 | static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, |
| 19 | struct fuse_open_out *outargp) | 19 | int opcode, struct fuse_open_out *outargp) |
| 20 | { | 20 | { |
| 21 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
| 22 | struct fuse_open_in inarg; | 21 | struct fuse_open_in inarg; |
| 23 | struct fuse_req *req; | 22 | struct fuse_req *req; |
| 24 | int err; | 23 | int err; |
| @@ -31,8 +30,8 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir, | |||
| 31 | inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); | 30 | inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); |
| 32 | if (!fc->atomic_o_trunc) | 31 | if (!fc->atomic_o_trunc) |
| 33 | inarg.flags &= ~O_TRUNC; | 32 | inarg.flags &= ~O_TRUNC; |
| 34 | req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; | 33 | req->in.h.opcode = opcode; |
| 35 | req->in.h.nodeid = get_node_id(inode); | 34 | req->in.h.nodeid = nodeid; |
| 36 | req->in.numargs = 1; | 35 | req->in.numargs = 1; |
| 37 | req->in.args[0].size = sizeof(inarg); | 36 | req->in.args[0].size = sizeof(inarg); |
| 38 | req->in.args[0].value = &inarg; | 37 | req->in.args[0].value = &inarg; |
| @@ -102,6 +101,35 @@ static void fuse_file_put(struct fuse_file *ff) | |||
| 102 | } | 101 | } |
| 103 | } | 102 | } |
| 104 | 103 | ||
| 104 | static int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, | ||
| 105 | bool isdir) | ||
| 106 | { | ||
| 107 | struct fuse_open_out outarg; | ||
| 108 | struct fuse_file *ff; | ||
| 109 | int err; | ||
| 110 | int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; | ||
| 111 | |||
| 112 | ff = fuse_file_alloc(fc); | ||
| 113 | if (!ff) | ||
| 114 | return -ENOMEM; | ||
| 115 | |||
| 116 | err = fuse_send_open(fc, nodeid, file, opcode, &outarg); | ||
| 117 | if (err) { | ||
| 118 | fuse_file_free(ff); | ||
| 119 | return err; | ||
| 120 | } | ||
| 121 | |||
| 122 | if (isdir) | ||
| 123 | outarg.open_flags &= ~FOPEN_DIRECT_IO; | ||
| 124 | |||
| 125 | ff->fh = outarg.fh; | ||
| 126 | ff->nodeid = nodeid; | ||
| 127 | ff->open_flags = outarg.open_flags; | ||
| 128 | file->private_data = fuse_file_get(ff); | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | } | ||
| 132 | |||
| 105 | void fuse_finish_open(struct inode *inode, struct file *file) | 133 | void fuse_finish_open(struct inode *inode, struct file *file) |
| 106 | { | 134 | { |
| 107 | struct fuse_file *ff = file->private_data; | 135 | struct fuse_file *ff = file->private_data; |
| @@ -114,11 +142,9 @@ void fuse_finish_open(struct inode *inode, struct file *file) | |||
| 114 | nonseekable_open(inode, file); | 142 | nonseekable_open(inode, file); |
| 115 | } | 143 | } |
| 116 | 144 | ||
| 117 | int fuse_open_common(struct inode *inode, struct file *file, int isdir) | 145 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) |
| 118 | { | 146 | { |
| 119 | struct fuse_conn *fc = get_fuse_conn(inode); | 147 | struct fuse_conn *fc = get_fuse_conn(inode); |
| 120 | struct fuse_open_out outarg; | ||
| 121 | struct fuse_file *ff; | ||
| 122 | int err; | 148 | int err; |
| 123 | 149 | ||
| 124 | /* VFS checks this, but only _after_ ->open() */ | 150 | /* VFS checks this, but only _after_ ->open() */ |
| @@ -129,24 +155,13 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir) | |||
| 129 | if (err) | 155 | if (err) |
| 130 | return err; | 156 | return err; |
| 131 | 157 | ||
| 132 | ff = fuse_file_alloc(fc); | 158 | err = fuse_do_open(fc, get_node_id(inode), file, isdir); |
| 133 | if (!ff) | ||
| 134 | return -ENOMEM; | ||
| 135 | |||
| 136 | err = fuse_send_open(inode, file, isdir, &outarg); | ||
| 137 | if (err) | 159 | if (err) |
| 138 | fuse_file_free(ff); | 160 | return err; |
| 139 | else { | ||
| 140 | if (isdir) | ||
| 141 | outarg.open_flags &= ~FOPEN_DIRECT_IO; | ||
| 142 | ff->fh = outarg.fh; | ||
| 143 | ff->nodeid = get_node_id(inode); | ||
| 144 | ff->open_flags = outarg.open_flags; | ||
| 145 | file->private_data = fuse_file_get(ff); | ||
| 146 | fuse_finish_open(inode, file); | ||
| 147 | } | ||
| 148 | 161 | ||
| 149 | return err; | 162 | fuse_finish_open(inode, file); |
| 163 | |||
| 164 | return 0; | ||
| 150 | } | 165 | } |
| 151 | 166 | ||
| 152 | void fuse_release_fill(struct fuse_file *ff, int flags, int opcode) | 167 | void fuse_release_fill(struct fuse_file *ff, int flags, int opcode) |
| @@ -201,7 +216,7 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) | |||
| 201 | 216 | ||
| 202 | static int fuse_open(struct inode *inode, struct file *file) | 217 | static int fuse_open(struct inode *inode, struct file *file) |
| 203 | { | 218 | { |
| 204 | return fuse_open_common(inode, file, 0); | 219 | return fuse_open_common(inode, file, false); |
| 205 | } | 220 | } |
| 206 | 221 | ||
| 207 | static int fuse_release(struct inode *inode, struct file *file) | 222 | static int fuse_release(struct inode *inode, struct file *file) |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index ce46c120f48a..429e669d7859 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
| @@ -528,7 +528,7 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, | |||
| 528 | /** | 528 | /** |
| 529 | * Send OPEN or OPENDIR request | 529 | * Send OPEN or OPENDIR request |
| 530 | */ | 530 | */ |
| 531 | int fuse_open_common(struct inode *inode, struct file *file, int isdir); | 531 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir); |
| 532 | 532 | ||
| 533 | struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); | 533 | struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); |
| 534 | struct fuse_file *fuse_file_get(struct fuse_file *ff); | 534 | struct fuse_file *fuse_file_get(struct fuse_file *ff); |
