@@ -27,7 +27,8 @@ static const struct file_operations ns_file_operations = {
27
27
static char * ns_dname (struct dentry * dentry , char * buffer , int buflen )
28
28
{
29
29
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 ;
31
32
32
33
return dynamic_dname (buffer , buflen , "%s:[%lu]" ,
33
34
ns_ops -> name , inode -> i_ino );
@@ -38,7 +39,7 @@ static void ns_prune_dentry(struct dentry *dentry)
38
39
struct inode * inode = d_inode (dentry );
39
40
if (inode ) {
40
41
struct ns_common * ns = inode -> i_private ;
41
- atomic_long_set ( & ns -> stashed , 0 );
42
+ WRITE_ONCE ( ns -> stashed , NULL );
42
43
}
43
44
}
44
45
@@ -56,54 +57,6 @@ static void nsfs_evict(struct inode *inode)
56
57
ns -> ops -> put (ns );
57
58
}
58
59
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
-
107
60
int ns_get_path_cb (struct path * path , ns_get_path_helper_t * ns_get_cb ,
108
61
void * private_data )
109
62
{
@@ -113,10 +66,16 @@ int ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb,
113
66
struct ns_common * ns = ns_get_cb (private_data );
114
67
if (!ns )
115
68
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 );
117
73
} while (ret == - EAGAIN );
118
74
119
- return ret ;
75
+ if (ret < 0 )
76
+ return ret ;
77
+
78
+ return 0 ;
120
79
}
121
80
122
81
struct ns_get_path_task_args {
@@ -163,10 +122,13 @@ int open_related_ns(struct ns_common *ns,
163
122
return PTR_ERR (relative );
164
123
}
165
124
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 );
167
129
} while (err == - EAGAIN );
168
130
169
- if (err ) {
131
+ if (err < 0 ) {
170
132
put_unused_fd (fd );
171
133
return err ;
172
134
}
@@ -249,7 +211,8 @@ bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino)
249
211
static int nsfs_show_path (struct seq_file * seq , struct dentry * dentry )
250
212
{
251
213
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 ;
253
216
254
217
seq_printf (seq , "%s:[%lu]" , ns_ops -> name , inode -> i_ino );
255
218
return 0 ;
0 commit comments