@@ -1973,3 +1973,97 @@ struct timespec64 simple_inode_init_ts(struct inode *inode)
19731973 return ts ;
19741974}
19751975EXPORT_SYMBOL (simple_inode_init_ts );
1976+
1977+ static inline struct dentry * get_stashed_dentry (struct dentry * stashed )
1978+ {
1979+ struct dentry * dentry ;
1980+
1981+ guard (rcu )();
1982+ dentry = READ_ONCE (stashed );
1983+ if (!dentry )
1984+ return NULL ;
1985+ if (!lockref_get_not_dead (& dentry -> d_lockref ))
1986+ return NULL ;
1987+ return dentry ;
1988+ }
1989+
1990+ static struct dentry * stash_dentry (struct dentry * * stashed , unsigned long ino ,
1991+ struct super_block * sb ,
1992+ const struct file_operations * fops ,
1993+ void * data )
1994+ {
1995+ struct dentry * dentry ;
1996+ struct inode * inode ;
1997+
1998+ dentry = d_alloc_anon (sb );
1999+ if (!dentry )
2000+ return ERR_PTR (- ENOMEM );
2001+
2002+ inode = new_inode_pseudo (sb );
2003+ if (!inode ) {
2004+ dput (dentry );
2005+ return ERR_PTR (- ENOMEM );
2006+ }
2007+
2008+ inode -> i_ino = ino ;
2009+ inode -> i_flags |= S_IMMUTABLE ;
2010+ inode -> i_mode = S_IFREG | S_IRUGO ;
2011+ inode -> i_fop = fops ;
2012+ inode -> i_private = data ;
2013+ simple_inode_init_ts (inode );
2014+
2015+ /* @data is now owned by the fs */
2016+ d_instantiate (dentry , inode );
2017+
2018+ if (cmpxchg (stashed , NULL , dentry )) {
2019+ d_delete (dentry ); /* make sure ->d_prune() does nothing */
2020+ dput (dentry );
2021+ cpu_relax ();
2022+ return ERR_PTR (- EAGAIN );
2023+ }
2024+
2025+ return dentry ;
2026+ }
2027+
2028+ /**
2029+ * path_from_stashed - create path from stashed or new dentry
2030+ * @stashed: where to retrieve or stash dentry
2031+ * @ino: inode number to use
2032+ * @mnt: mnt of the filesystems to use
2033+ * @fops: file operations to use
2034+ * @data: data to store in inode->i_private
2035+ * @path: path to create
2036+ *
2037+ * The function tries to retrieve a stashed dentry from @stashed. If the dentry
2038+ * is still valid then it will be reused. If the dentry isn't able the function
2039+ * will allocate a new dentry and inode. It will then try to update @stashed
2040+ * with the newly added dentry. If it fails -EAGAIN is returned and the caller
2041+ * my retry.
2042+ *
2043+ * Special-purpose helper for nsfs and pidfs.
2044+ *
2045+ * Return: If 0 or an error is returned the caller can be sure that @data must
2046+ * be cleaned up. If 1 or -EAGAIN is returned @data is owned by the
2047+ * filesystem.
2048+ */
2049+ int path_from_stashed (struct dentry * * stashed , unsigned long ino ,
2050+ struct vfsmount * mnt , const struct file_operations * fops ,
2051+ void * data , struct path * path )
2052+ {
2053+ struct dentry * dentry ;
2054+ int ret = 0 ;
2055+
2056+ dentry = get_stashed_dentry (* stashed );
2057+ if (dentry )
2058+ goto out_path ;
2059+
2060+ dentry = stash_dentry (stashed , ino , mnt -> mnt_sb , fops , data );
2061+ if (IS_ERR (dentry ))
2062+ return PTR_ERR (dentry );
2063+ ret = 1 ;
2064+
2065+ out_path :
2066+ path -> dentry = dentry ;
2067+ path -> mnt = mntget (mnt );
2068+ return ret ;
2069+ }
0 commit comments