1919#include <linux/uio.h>
2020#include <linux/fs.h>
2121
22- static int fuse_send_open (struct fuse_mount * fm , u64 nodeid , struct file * file ,
23- int opcode , struct fuse_open_out * outargp )
22+ static int fuse_send_open (struct fuse_mount * fm , u64 nodeid ,
23+ unsigned int open_flags , int opcode ,
24+ struct fuse_open_out * outargp )
2425{
2526 struct fuse_open_in inarg ;
2627 FUSE_ARGS (args );
2728
2829 memset (& inarg , 0 , sizeof (inarg ));
29- inarg .flags = file -> f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY );
30+ inarg .flags = open_flags & ~(O_CREAT | O_EXCL | O_NOCTTY );
3031 if (!fm -> fc -> atomic_o_trunc )
3132 inarg .flags &= ~O_TRUNC ;
3233
@@ -123,16 +124,16 @@ static void fuse_file_put(struct fuse_file *ff, bool sync, bool isdir)
123124 }
124125}
125126
126- int fuse_do_open (struct fuse_mount * fm , u64 nodeid , struct file * file ,
127- bool isdir )
127+ struct fuse_file * fuse_file_open (struct fuse_mount * fm , u64 nodeid ,
128+ unsigned int open_flags , bool isdir )
128129{
129130 struct fuse_conn * fc = fm -> fc ;
130131 struct fuse_file * ff ;
131132 int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN ;
132133
133134 ff = fuse_file_alloc (fm );
134135 if (!ff )
135- return - ENOMEM ;
136+ return ERR_PTR ( - ENOMEM ) ;
136137
137138 ff -> fh = 0 ;
138139 /* Default for no-open */
@@ -141,14 +142,14 @@ int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
141142 struct fuse_open_out outarg ;
142143 int err ;
143144
144- err = fuse_send_open (fm , nodeid , file , opcode , & outarg );
145+ err = fuse_send_open (fm , nodeid , open_flags , opcode , & outarg );
145146 if (!err ) {
146147 ff -> fh = outarg .fh ;
147148 ff -> open_flags = outarg .open_flags ;
148149
149150 } else if (err != - ENOSYS ) {
150151 fuse_file_free (ff );
151- return err ;
152+ return ERR_PTR ( err ) ;
152153 } else {
153154 if (isdir )
154155 fc -> no_opendir = 1 ;
@@ -161,9 +162,19 @@ int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file,
161162 ff -> open_flags &= ~FOPEN_DIRECT_IO ;
162163
163164 ff -> nodeid = nodeid ;
164- file -> private_data = ff ;
165165
166- return 0 ;
166+ return ff ;
167+ }
168+
169+ int fuse_do_open (struct fuse_mount * fm , u64 nodeid , struct file * file ,
170+ bool isdir )
171+ {
172+ struct fuse_file * ff = fuse_file_open (fm , nodeid , file -> f_flags , isdir );
173+
174+ if (!IS_ERR (ff ))
175+ file -> private_data = ff ;
176+
177+ return PTR_ERR_OR_ZERO (ff );
167178}
168179EXPORT_SYMBOL_GPL (fuse_do_open );
169180
@@ -284,22 +295,21 @@ static void fuse_prepare_release(struct fuse_inode *fi, struct fuse_file *ff,
284295 ra -> args .nocreds = true;
285296}
286297
287- void fuse_release_common (struct file * file , bool isdir )
298+ void fuse_file_release (struct inode * inode , struct fuse_file * ff ,
299+ unsigned int open_flags , fl_owner_t id , bool isdir )
288300{
289- struct fuse_inode * fi = get_fuse_inode (file_inode (file ));
290- struct fuse_file * ff = file -> private_data ;
301+ struct fuse_inode * fi = get_fuse_inode (inode );
291302 struct fuse_release_args * ra = ff -> release_args ;
292303 int opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE ;
293304
294- fuse_prepare_release (fi , ff , file -> f_flags , opcode );
305+ fuse_prepare_release (fi , ff , open_flags , opcode );
295306
296307 if (ff -> flock ) {
297308 ra -> inarg .release_flags |= FUSE_RELEASE_FLOCK_UNLOCK ;
298- ra -> inarg .lock_owner = fuse_lock_owner_id (ff -> fm -> fc ,
299- (fl_owner_t ) file );
309+ ra -> inarg .lock_owner = fuse_lock_owner_id (ff -> fm -> fc , id );
300310 }
301311 /* Hold inode until release is finished */
302- ra -> inode = igrab (file_inode ( file ) );
312+ ra -> inode = igrab (inode );
303313
304314 /*
305315 * Normally this will send the RELEASE request, however if
@@ -313,6 +323,12 @@ void fuse_release_common(struct file *file, bool isdir)
313323 fuse_file_put (ff , ff -> fm -> fc -> destroy , isdir );
314324}
315325
326+ void fuse_release_common (struct file * file , bool isdir )
327+ {
328+ fuse_file_release (file_inode (file ), file -> private_data , file -> f_flags ,
329+ (fl_owner_t ) file , isdir );
330+ }
331+
316332static int fuse_open (struct inode * inode , struct file * file )
317333{
318334 return fuse_open_common (inode , file , false);
0 commit comments