@@ -56,7 +56,7 @@ struct fuse_release_args {
5656 struct inode * inode ;
5757};
5858
59- struct fuse_file * fuse_file_alloc (struct fuse_mount * fm )
59+ struct fuse_file * fuse_file_alloc (struct fuse_mount * fm , bool release )
6060{
6161 struct fuse_file * ff ;
6262
@@ -65,11 +65,13 @@ struct fuse_file *fuse_file_alloc(struct fuse_mount *fm)
6565 return NULL ;
6666
6767 ff -> fm = fm ;
68- ff -> release_args = kzalloc (sizeof (* ff -> release_args ),
69- GFP_KERNEL_ACCOUNT );
70- if (!ff -> release_args ) {
71- kfree (ff );
72- return NULL ;
68+ if (release ) {
69+ ff -> release_args = kzalloc (sizeof (* ff -> release_args ),
70+ GFP_KERNEL_ACCOUNT );
71+ if (!ff -> release_args ) {
72+ kfree (ff );
73+ return NULL ;
74+ }
7375 }
7476
7577 INIT_LIST_HEAD (& ff -> write_entry );
@@ -105,14 +107,14 @@ static void fuse_release_end(struct fuse_mount *fm, struct fuse_args *args,
105107 kfree (ra );
106108}
107109
108- static void fuse_file_put (struct fuse_file * ff , bool sync , bool isdir )
110+ static void fuse_file_put (struct fuse_file * ff , bool sync )
109111{
110112 if (refcount_dec_and_test (& ff -> count )) {
111- struct fuse_args * args = & ff -> release_args -> args ;
113+ struct fuse_release_args * ra = ff -> release_args ;
114+ struct fuse_args * args = (ra ? & ra -> args : NULL );
112115
113- if (isdir ? ff -> fm -> fc -> no_opendir : ff -> fm -> fc -> no_open ) {
114- /* Do nothing when client does not implement 'open' */
115- fuse_release_end (ff -> fm , args , 0 );
116+ if (!args ) {
117+ /* Do nothing when server does not implement 'open' */
116118 } else if (sync ) {
117119 fuse_simple_request (ff -> fm , args );
118120 fuse_release_end (ff -> fm , args , 0 );
@@ -132,27 +134,30 @@ struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid,
132134 struct fuse_conn * fc = fm -> fc ;
133135 struct fuse_file * ff ;
134136 int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN ;
137+ bool open = isdir ? !fc -> no_opendir : !fc -> no_open ;
135138
136- ff = fuse_file_alloc (fm );
139+ ff = fuse_file_alloc (fm , open );
137140 if (!ff )
138141 return ERR_PTR (- ENOMEM );
139142
140143 ff -> fh = 0 ;
141144 /* Default for no-open */
142145 ff -> open_flags = FOPEN_KEEP_CACHE | (isdir ? FOPEN_CACHE_DIR : 0 );
143- if (isdir ? ! fc -> no_opendir : ! fc -> no_open ) {
146+ if (open ) {
144147 struct fuse_open_out outarg ;
145148 int err ;
146149
147150 err = fuse_send_open (fm , nodeid , open_flags , opcode , & outarg );
148151 if (!err ) {
149152 ff -> fh = outarg .fh ;
150153 ff -> open_flags = outarg .open_flags ;
151-
152154 } else if (err != - ENOSYS ) {
153155 fuse_file_free (ff );
154156 return ERR_PTR (err );
155157 } else {
158+ /* No release needed */
159+ kfree (ff -> release_args );
160+ ff -> release_args = NULL ;
156161 if (isdir )
157162 fc -> no_opendir = 1 ;
158163 else
@@ -278,7 +283,7 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
278283}
279284
280285static void fuse_prepare_release (struct fuse_inode * fi , struct fuse_file * ff ,
281- unsigned int flags , int opcode )
286+ unsigned int flags , int opcode , bool sync )
282287{
283288 struct fuse_conn * fc = ff -> fm -> fc ;
284289 struct fuse_release_args * ra = ff -> release_args ;
@@ -296,6 +301,9 @@ static void fuse_prepare_release(struct fuse_inode *fi, struct fuse_file *ff,
296301
297302 wake_up_interruptible_all (& ff -> poll_wait );
298303
304+ if (!ra )
305+ return ;
306+
299307 ra -> inarg .fh = ff -> fh ;
300308 ra -> inarg .flags = flags ;
301309 ra -> args .in_numargs = 1 ;
@@ -305,6 +313,13 @@ static void fuse_prepare_release(struct fuse_inode *fi, struct fuse_file *ff,
305313 ra -> args .nodeid = ff -> nodeid ;
306314 ra -> args .force = true;
307315 ra -> args .nocreds = true;
316+
317+ /*
318+ * Hold inode until release is finished.
319+ * From fuse_sync_release() the refcount is 1 and everything's
320+ * synchronous, so we are fine with not doing igrab() here.
321+ */
322+ ra -> inode = sync ? NULL : igrab (& fi -> inode );
308323}
309324
310325void fuse_file_release (struct inode * inode , struct fuse_file * ff ,
@@ -314,14 +329,12 @@ void fuse_file_release(struct inode *inode, struct fuse_file *ff,
314329 struct fuse_release_args * ra = ff -> release_args ;
315330 int opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE ;
316331
317- fuse_prepare_release (fi , ff , open_flags , opcode );
332+ fuse_prepare_release (fi , ff , open_flags , opcode , false );
318333
319- if (ff -> flock ) {
334+ if (ra && ff -> flock ) {
320335 ra -> inarg .release_flags |= FUSE_RELEASE_FLOCK_UNLOCK ;
321336 ra -> inarg .lock_owner = fuse_lock_owner_id (ff -> fm -> fc , id );
322337 }
323- /* Hold inode until release is finished */
324- ra -> inode = igrab (inode );
325338
326339 /*
327340 * Normally this will send the RELEASE request, however if
@@ -332,7 +345,7 @@ void fuse_file_release(struct inode *inode, struct fuse_file *ff,
332345 * synchronous RELEASE is allowed (and desirable) in this case
333346 * because the server can be trusted not to screw up.
334347 */
335- fuse_file_put (ff , ff -> fm -> fc -> destroy , isdir );
348+ fuse_file_put (ff , ff -> fm -> fc -> destroy );
336349}
337350
338351void fuse_release_common (struct file * file , bool isdir )
@@ -367,12 +380,8 @@ void fuse_sync_release(struct fuse_inode *fi, struct fuse_file *ff,
367380 unsigned int flags )
368381{
369382 WARN_ON (refcount_read (& ff -> count ) > 1 );
370- fuse_prepare_release (fi , ff , flags , FUSE_RELEASE );
371- /*
372- * iput(NULL) is a no-op and since the refcount is 1 and everything's
373- * synchronous, we are fine with not doing igrab() here"
374- */
375- fuse_file_put (ff , true, false);
383+ fuse_prepare_release (fi , ff , flags , FUSE_RELEASE , true);
384+ fuse_file_put (ff , true);
376385}
377386EXPORT_SYMBOL_GPL (fuse_sync_release );
378387
@@ -929,7 +938,7 @@ static void fuse_readpages_end(struct fuse_mount *fm, struct fuse_args *args,
929938 put_page (page );
930939 }
931940 if (ia -> ff )
932- fuse_file_put (ia -> ff , false, false );
941+ fuse_file_put (ia -> ff , false);
933942
934943 fuse_io_free (ia );
935944}
@@ -1705,7 +1714,7 @@ static void fuse_writepage_free(struct fuse_writepage_args *wpa)
17051714 __free_page (ap -> pages [i ]);
17061715
17071716 if (wpa -> ia .ff )
1708- fuse_file_put (wpa -> ia .ff , false, false );
1717+ fuse_file_put (wpa -> ia .ff , false);
17091718
17101719 kfree (ap -> pages );
17111720 kfree (wpa );
@@ -1947,7 +1956,7 @@ int fuse_write_inode(struct inode *inode, struct writeback_control *wbc)
19471956 ff = __fuse_write_file_get (fi );
19481957 err = fuse_flush_times (inode , ff );
19491958 if (ff )
1950- fuse_file_put (ff , false, false );
1959+ fuse_file_put (ff , false);
19511960
19521961 return err ;
19531962}
@@ -2345,7 +2354,7 @@ static int fuse_writepages(struct address_space *mapping,
23452354 fuse_writepages_send (& data );
23462355 }
23472356 if (data .ff )
2348- fuse_file_put (data .ff , false, false );
2357+ fuse_file_put (data .ff , false);
23492358
23502359 kfree (data .orig_pages );
23512360out :
0 commit comments