@@ -27,7 +27,8 @@ static const struct file_operations ns_file_operations = {
2727static char * ns_dname (struct dentry * dentry , char * buffer , int buflen )
2828{
2929 struct inode * inode = d_inode (dentry );
30- const struct proc_ns_operations * ns_ops = dentry -> d_fsdata ;
30+ struct ns_common * ns = inode -> i_private ;
31+ const struct proc_ns_operations * ns_ops = ns -> ops ;
3132
3233 return dynamic_dname (buffer , buflen , "%s:[%lu]" ,
3334 ns_ops -> name , inode -> i_ino );
@@ -38,7 +39,7 @@ static void ns_prune_dentry(struct dentry *dentry)
3839 struct inode * inode = d_inode (dentry );
3940 if (inode ) {
4041 struct ns_common * ns = inode -> i_private ;
41- atomic_long_set ( & ns -> stashed , 0 );
42+ WRITE_ONCE ( ns -> stashed , NULL );
4243 }
4344}
4445
@@ -56,54 +57,6 @@ static void nsfs_evict(struct inode *inode)
5657 ns -> ops -> put (ns );
5758}
5859
59- static int __ns_get_path (struct path * path , struct ns_common * ns )
60- {
61- struct vfsmount * mnt = nsfs_mnt ;
62- struct dentry * dentry ;
63- struct inode * inode ;
64- unsigned long d ;
65-
66- rcu_read_lock ();
67- d = atomic_long_read (& ns -> stashed );
68- if (!d )
69- goto slow ;
70- dentry = (struct dentry * )d ;
71- if (!lockref_get_not_dead (& dentry -> d_lockref ))
72- goto slow ;
73- rcu_read_unlock ();
74- ns -> ops -> put (ns );
75- got_it :
76- path -> mnt = mntget (mnt );
77- path -> dentry = dentry ;
78- return 0 ;
79- slow :
80- rcu_read_unlock ();
81- inode = new_inode_pseudo (mnt -> mnt_sb );
82- if (!inode ) {
83- ns -> ops -> put (ns );
84- return - ENOMEM ;
85- }
86- inode -> i_ino = ns -> inum ;
87- simple_inode_init_ts (inode );
88- inode -> i_flags |= S_IMMUTABLE ;
89- inode -> i_mode = S_IFREG | S_IRUGO ;
90- inode -> i_fop = & ns_file_operations ;
91- inode -> i_private = ns ;
92-
93- dentry = d_make_root (inode ); /* not the normal use, but... */
94- if (!dentry )
95- return - ENOMEM ;
96- dentry -> d_fsdata = (void * )ns -> ops ;
97- d = atomic_long_cmpxchg (& ns -> stashed , 0 , (unsigned long )dentry );
98- if (d ) {
99- d_delete (dentry ); /* make sure ->d_prune() does nothing */
100- dput (dentry );
101- cpu_relax ();
102- return - EAGAIN ;
103- }
104- goto got_it ;
105- }
106-
10760int ns_get_path_cb (struct path * path , ns_get_path_helper_t * ns_get_cb ,
10861 void * private_data )
10962{
@@ -113,10 +66,16 @@ int ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb,
11366 struct ns_common * ns = ns_get_cb (private_data );
11467 if (!ns )
11568 return - ENOENT ;
116- ret = __ns_get_path (path , ns );
69+ ret = path_from_stashed (& ns -> stashed , ns -> inum , nsfs_mnt ,
70+ & ns_file_operations , ns , path );
71+ if (ret <= 0 && ret != - EAGAIN )
72+ ns -> ops -> put (ns );
11773 } while (ret == - EAGAIN );
11874
119- return ret ;
75+ if (ret < 0 )
76+ return ret ;
77+
78+ return 0 ;
12079}
12180
12281struct ns_get_path_task_args {
@@ -163,10 +122,13 @@ int open_related_ns(struct ns_common *ns,
163122 return PTR_ERR (relative );
164123 }
165124
166- err = __ns_get_path (& path , relative );
125+ err = path_from_stashed (& relative -> stashed , relative -> inum , nsfs_mnt ,
126+ & ns_file_operations , relative , & path );
127+ if (err <= 0 && err != - EAGAIN )
128+ relative -> ops -> put (relative );
167129 } while (err == - EAGAIN );
168130
169- if (err ) {
131+ if (err < 0 ) {
170132 put_unused_fd (fd );
171133 return err ;
172134 }
@@ -249,7 +211,8 @@ bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino)
249211static int nsfs_show_path (struct seq_file * seq , struct dentry * dentry )
250212{
251213 struct inode * inode = d_inode (dentry );
252- const struct proc_ns_operations * ns_ops = dentry -> d_fsdata ;
214+ const struct ns_common * ns = inode -> i_private ;
215+ const struct proc_ns_operations * ns_ops = ns -> ops ;
253216
254217 seq_printf (seq , "%s:[%lu]" , ns_ops -> name , inode -> i_ino );
255218 return 0 ;
0 commit comments