diff options
Diffstat (limited to 'fs/fuse')
-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); |