aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dir.c2
-rw-r--r--fs/fuse/file.c65
-rw-r--r--fs/fuse/fuse_i.h2
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
1104static int fuse_dir_open(struct inode *inode, struct file *file) 1104static 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
1109static int fuse_dir_release(struct inode *inode, struct file *file) 1109static 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
16static const struct file_operations fuse_direct_io_file_operations; 16static const struct file_operations fuse_direct_io_file_operations;
17 17
18static int fuse_send_open(struct inode *inode, struct file *file, int isdir, 18static 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
104static 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
105void fuse_finish_open(struct inode *inode, struct file *file) 133void 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
117int fuse_open_common(struct inode *inode, struct file *file, int isdir) 145int 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
152void fuse_release_fill(struct fuse_file *ff, int flags, int opcode) 167void 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
202static int fuse_open(struct inode *inode, struct file *file) 217static 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
207static int fuse_release(struct inode *inode, struct file *file) 222static 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 */
531int fuse_open_common(struct inode *inode, struct file *file, int isdir); 531int fuse_open_common(struct inode *inode, struct file *file, bool isdir);
532 532
533struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); 533struct fuse_file *fuse_file_alloc(struct fuse_conn *fc);
534struct fuse_file *fuse_file_get(struct fuse_file *ff); 534struct fuse_file *fuse_file_get(struct fuse_file *ff);