@@ -68,6 +68,24 @@ struct fuse_forget_link *fuse_alloc_forget(void)
6868 return kzalloc (sizeof (struct fuse_forget_link ), GFP_KERNEL_ACCOUNT );
6969}
7070
71+ static struct fuse_submount_lookup * fuse_alloc_submount_lookup (void )
72+ {
73+ struct fuse_submount_lookup * sl ;
74+
75+ sl = kzalloc (sizeof (struct fuse_submount_lookup ), GFP_KERNEL_ACCOUNT );
76+ if (!sl )
77+ return NULL ;
78+ sl -> forget = fuse_alloc_forget ();
79+ if (!sl -> forget )
80+ goto out_free ;
81+
82+ return sl ;
83+
84+ out_free :
85+ kfree (sl );
86+ return NULL ;
87+ }
88+
7189static struct inode * fuse_alloc_inode (struct super_block * sb )
7290{
7391 struct fuse_inode * fi ;
@@ -83,6 +101,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
83101 fi -> attr_version = 0 ;
84102 fi -> orig_ino = 0 ;
85103 fi -> state = 0 ;
104+ fi -> submount_lookup = NULL ;
86105 mutex_init (& fi -> mutex );
87106 spin_lock_init (& fi -> lock );
88107 fi -> forget = fuse_alloc_forget ();
@@ -113,6 +132,17 @@ static void fuse_free_inode(struct inode *inode)
113132 kmem_cache_free (fuse_inode_cachep , fi );
114133}
115134
135+ static void fuse_cleanup_submount_lookup (struct fuse_conn * fc ,
136+ struct fuse_submount_lookup * sl )
137+ {
138+ if (!refcount_dec_and_test (& sl -> count ))
139+ return ;
140+
141+ fuse_queue_forget (fc , sl -> forget , sl -> nodeid , 1 );
142+ sl -> forget = NULL ;
143+ kfree (sl );
144+ }
145+
116146static void fuse_evict_inode (struct inode * inode )
117147{
118148 struct fuse_inode * fi = get_fuse_inode (inode );
@@ -132,6 +162,11 @@ static void fuse_evict_inode(struct inode *inode)
132162 fi -> nlookup );
133163 fi -> forget = NULL ;
134164 }
165+
166+ if (fi -> submount_lookup ) {
167+ fuse_cleanup_submount_lookup (fc , fi -> submount_lookup );
168+ fi -> submount_lookup = NULL ;
169+ }
135170 }
136171 if (S_ISREG (inode -> i_mode ) && !fuse_is_bad (inode )) {
137172 WARN_ON (!list_empty (& fi -> write_files ));
@@ -330,6 +365,13 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
330365 fuse_dax_dontcache (inode , attr -> flags );
331366}
332367
368+ static void fuse_init_submount_lookup (struct fuse_submount_lookup * sl ,
369+ u64 nodeid )
370+ {
371+ sl -> nodeid = nodeid ;
372+ refcount_set (& sl -> count , 1 );
373+ }
374+
333375static void fuse_init_inode (struct inode * inode , struct fuse_attr * attr ,
334376 struct fuse_conn * fc )
335377{
@@ -392,12 +434,22 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
392434 */
393435 if (fc -> auto_submounts && (attr -> flags & FUSE_ATTR_SUBMOUNT ) &&
394436 S_ISDIR (attr -> mode )) {
437+ struct fuse_inode * fi ;
438+
395439 inode = new_inode (sb );
396440 if (!inode )
397441 return NULL ;
398442
399443 fuse_init_inode (inode , attr , fc );
400- get_fuse_inode (inode )-> nodeid = nodeid ;
444+ fi = get_fuse_inode (inode );
445+ fi -> nodeid = nodeid ;
446+ fi -> submount_lookup = fuse_alloc_submount_lookup ();
447+ if (!fi -> submount_lookup ) {
448+ iput (inode );
449+ return NULL ;
450+ }
451+ /* Sets nlookup = 1 on fi->submount_lookup->nlookup */
452+ fuse_init_submount_lookup (fi -> submount_lookup , nodeid );
401453 inode -> i_flags |= S_AUTOMOUNT ;
402454 goto done ;
403455 }
@@ -420,11 +472,11 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
420472 iput (inode );
421473 goto retry ;
422474 }
423- done :
424475 fi = get_fuse_inode (inode );
425476 spin_lock (& fi -> lock );
426477 fi -> nlookup ++ ;
427478 spin_unlock (& fi -> lock );
479+ done :
428480 fuse_change_attributes (inode , attr , NULL , attr_valid , attr_version );
429481
430482 return inode ;
@@ -1230,8 +1282,8 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
12301282 fc -> init_security = 1 ;
12311283 if (flags & FUSE_CREATE_SUPP_GROUP )
12321284 fc -> create_supp_group = 1 ;
1233- if (flags & FUSE_DIRECT_IO_RELAX )
1234- fc -> direct_io_relax = 1 ;
1285+ if (flags & FUSE_DIRECT_IO_ALLOW_MMAP )
1286+ fc -> direct_io_allow_mmap = 1 ;
12351287 } else {
12361288 ra_pages = fc -> max_read / PAGE_SIZE ;
12371289 fc -> no_lock = 1 ;
@@ -1278,7 +1330,7 @@ void fuse_send_init(struct fuse_mount *fm)
12781330 FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA |
12791331 FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT | FUSE_INIT_EXT |
12801332 FUSE_SECURITY_CTX | FUSE_CREATE_SUPP_GROUP |
1281- FUSE_HAS_EXPIRE_ONLY | FUSE_DIRECT_IO_RELAX ;
1333+ FUSE_HAS_EXPIRE_ONLY | FUSE_DIRECT_IO_ALLOW_MMAP ;
12821334#ifdef CONFIG_FUSE_DAX
12831335 if (fm -> fc -> dax )
12841336 flags |= FUSE_MAP_ALIGNMENT ;
@@ -1465,6 +1517,8 @@ static int fuse_fill_super_submount(struct super_block *sb,
14651517 struct super_block * parent_sb = parent_fi -> inode .i_sb ;
14661518 struct fuse_attr root_attr ;
14671519 struct inode * root ;
1520+ struct fuse_submount_lookup * sl ;
1521+ struct fuse_inode * fi ;
14681522
14691523 fuse_sb_defaults (sb );
14701524 fm -> sb = sb ;
@@ -1487,12 +1541,27 @@ static int fuse_fill_super_submount(struct super_block *sb,
14871541 * its nlookup should not be incremented. fuse_iget() does
14881542 * that, though, so undo it here.
14891543 */
1490- get_fuse_inode (root )-> nlookup -- ;
1544+ fi = get_fuse_inode (root );
1545+ fi -> nlookup -- ;
1546+
14911547 sb -> s_d_op = & fuse_dentry_operations ;
14921548 sb -> s_root = d_make_root (root );
14931549 if (!sb -> s_root )
14941550 return - ENOMEM ;
14951551
1552+ /*
1553+ * Grab the parent's submount_lookup pointer and take a
1554+ * reference on the shared nlookup from the parent. This is to
1555+ * prevent the last forget for this nodeid from getting
1556+ * triggered until all users have finished with it.
1557+ */
1558+ sl = parent_fi -> submount_lookup ;
1559+ WARN_ON (!sl );
1560+ if (sl ) {
1561+ refcount_inc (& sl -> count );
1562+ fi -> submount_lookup = sl ;
1563+ }
1564+
14961565 return 0 ;
14971566}
14981567
0 commit comments