tree:
https://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git
debugfs_namespaces
head: aa77168aed303d914b4c11a2edaddbca3f1feda1
commit: 738289244f9f67ce3281dfece66c6e2f728b6501 [1/3] debugfs: add ns entry
config: i386-tinyconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-13) 7.4.0
reproduce:
git checkout 738289244f9f67ce3281dfece66c6e2f728b6501
# save the attached .config to linux build tree
make ARCH=i386
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp(a)intel.com>
All error/warnings (new ones prefixed by >>):
> fs/nsfs.c:19:30: error: conflicting type qualifiers for
'ns_file_operations'
const struct file_operations ns_file_operations =
{
^~~~~~~~~~~~~~~~~~
In file included from fs/nsfs.c:12:0:
include/linux/nsfs.h:6:31: note: previous declaration of 'ns_file_operations'
was here
extern struct file_operations ns_file_operations;
^~~~~~~~~~~~~~~~~~
fs/nsfs.c: In function 'ns_ioctl':
> fs/nsfs.c:196:7: error: 'NS_GET_USERNS' undeclared (first
use in this function); did you mean 'F_GET_SEALS'?
case NS_GET_USERNS:
^~~~~~~~~~~~~
F_GET_SEALS
fs/nsfs.c:196:7: note: each undeclared identifier is reported only once for each
function it appears in
> fs/nsfs.c:198:7: error: 'NS_GET_PARENT' undeclared (first
use in this function); did you mean 'NS_GET_USERNS'?
case
NS_GET_PARENT:
^~~~~~~~~~~~~
NS_GET_USERNS
> fs/nsfs.c:202:7: error: 'NS_GET_NSTYPE' undeclared (first
use in this function); did you mean 'NS_GET_USERNS'?
case
NS_GET_NSTYPE:
^~~~~~~~~~~~~
NS_GET_USERNS
> fs/nsfs.c:204:7: error: 'NS_GET_OWNER_UID' undeclared
(first use in this function); did you mean 'F_GETOWNER_UIDS'?
case
NS_GET_OWNER_UID:
^~~~~~~~~~~~~~~~
F_GETOWNER_UIDS
fs/nsfs.c: In function 'proc_ns_fget':
> fs/nsfs.c:244:15: error: implicit declaration of function
'debugfs_real_fops' [-Werror=implicit-function-declaration]
real_fops
= debugfs_real_fops(file);
^~~~~~~~~~~~~~~~~
> fs/nsfs.c:244:13: warning: assignment makes pointer from integer
without a cast [-Wint-conversion]
real_fops = debugfs_real_fops(file);
^
cc1: some warnings being treated as errors
vim +/ns_file_operations +19 fs/nsfs.c
16
17 static long ns_ioctl(struct file *filp, unsigned int ioctl,
18 unsigned long arg);
19 const struct file_operations ns_file_operations = {
20 .llseek = no_llseek,
21 .unlocked_ioctl = ns_ioctl,
22 };
23
24 static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
25 {
26 struct inode *inode = d_inode(dentry);
27 const struct proc_ns_operations *ns_ops = dentry->d_fsdata;
28
29 return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
30 ns_ops->name, inode->i_ino);
31 }
32
33 static void ns_prune_dentry(struct dentry *dentry)
34 {
35 struct inode *inode = d_inode(dentry);
36 if (inode) {
37 struct ns_common *ns = inode->i_private;
38 atomic_long_set(&ns->stashed, 0);
39 }
40 }
41
42 const struct dentry_operations ns_dentry_operations =
43 {
44 .d_prune = ns_prune_dentry,
45 .d_delete = always_delete_dentry,
46 .d_dname = ns_dname,
47 };
48
49 static void nsfs_evict(struct inode *inode)
50 {
51 struct ns_common *ns = inode->i_private;
52 clear_inode(inode);
53 ns->ops->put(ns);
54 }
55
56 static void *__ns_get_path(struct path *path, struct ns_common *ns)
57 {
58 struct vfsmount *mnt = nsfs_mnt;
59 struct dentry *dentry;
60 struct inode *inode;
61 unsigned long d;
62
63 rcu_read_lock();
64 d = atomic_long_read(&ns->stashed);
65 if (!d)
66 goto slow;
67 dentry = (struct dentry *)d;
68 if (!lockref_get_not_dead(&dentry->d_lockref))
69 goto slow;
70 rcu_read_unlock();
71 ns->ops->put(ns);
72 got_it:
73 path->mnt = mntget(mnt);
74 path->dentry = dentry;
75 return NULL;
76 slow:
77 rcu_read_unlock();
78 inode = new_inode_pseudo(mnt->mnt_sb);
79 if (!inode) {
80 ns->ops->put(ns);
81 return ERR_PTR(-ENOMEM);
82 }
83 inode->i_ino = ns->inum;
84 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
85 inode->i_flags |= S_IMMUTABLE;
86 inode->i_mode = S_IFREG | S_IRUGO;
87 inode->i_fop = &ns_file_operations;
88 inode->i_private = ns;
89
90 dentry = d_alloc_anon(mnt->mnt_sb);
91 if (!dentry) {
92 iput(inode);
93 return ERR_PTR(-ENOMEM);
94 }
95 d_instantiate(dentry, inode);
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 ERR_PTR(-EAGAIN);
103 }
104 goto got_it;
105 }
106
107 void *ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb,
108 void *private_data)
109 {
110 void *ret;
111
112 do {
113 struct ns_common *ns = ns_get_cb(private_data);
114 if (!ns)
115 return ERR_PTR(-ENOENT);
116
117 ret = __ns_get_path(path, ns);
118 } while (ret == ERR_PTR(-EAGAIN));
119
120 return ret;
121 }
122
123 struct ns_get_path_task_args {
124 const struct proc_ns_operations *ns_ops;
125 struct task_struct *task;
126 };
127
128 static struct ns_common *ns_get_path_task(void *private_data)
129 {
130 struct ns_get_path_task_args *args = private_data;
131
132 return args->ns_ops->get(args->task);
133 }
134
135 void *ns_get_path(struct path *path, struct task_struct *task,
136 const struct proc_ns_operations *ns_ops)
137 {
138 struct ns_get_path_task_args args = {
139 .ns_ops = ns_ops,
140 .task = task,
141 };
142
143 return ns_get_path_cb(path, ns_get_path_task, &args);
144 }
145
146 int open_related_ns(struct ns_common *ns,
147 struct ns_common *(*get_ns)(struct ns_common *ns))
148 {
149 struct path path = {};
150 struct file *f;
151 void *err;
152 int fd;
153
154 fd = get_unused_fd_flags(O_CLOEXEC);
155 if (fd < 0)
156 return fd;
157
158 do {
159 struct ns_common *relative;
160
161 relative = get_ns(ns);
162 if (IS_ERR(relative)) {
163 put_unused_fd(fd);
164 return PTR_ERR(relative);
165 }
166
167 err = __ns_get_path(&path, relative);
168 } while (err == ERR_PTR(-EAGAIN));
169
170 if (IS_ERR(err)) {
171 put_unused_fd(fd);
172 return PTR_ERR(err);
173 }
174
175 f = dentry_open(&path, O_RDONLY, current_cred());
176 path_put(&path);
177 if (IS_ERR(f)) {
178 put_unused_fd(fd);
179 fd = PTR_ERR(f);
180 } else
181 fd_install(fd, f);
182
183 return fd;
184 }
185 EXPORT_SYMBOL_GPL(open_related_ns);
186
187 static long ns_ioctl(struct file *filp, unsigned int ioctl,
188 unsigned long arg)
189 {
190 struct user_namespace *user_ns;
191 struct ns_common *ns = get_proc_ns(file_inode(filp));
192 uid_t __user *argp;
193 uid_t uid;
194
195 switch (ioctl) {
196 case NS_GET_USERNS:
197 return open_related_ns(ns,
ns_get_owner);
198 case NS_GET_PARENT:
199 if
(!ns->ops->get_parent)
200 return -EINVAL;
201 return open_related_ns(ns, ns->ops->get_parent);
202 case NS_GET_NSTYPE:
203 return ns->ops->type;
204 case NS_GET_OWNER_UID:
205 if (ns->ops->type !=
CLONE_NEWUSER)
206 return -EINVAL;
207 user_ns = container_of(ns, struct user_namespace, ns);
208 argp = (uid_t __user *) arg;
209 uid = from_kuid_munged(current_user_ns(), user_ns->owner);
210 return put_user(uid, argp);
211 default:
212 return -ENOTTY;
213 }
214 }
215
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation