aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/namespaces.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-16 12:07:31 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:32 -0400
commitf0c3b5093addc8bfe9fe3a5b01acb7ec7969eafa (patch)
tree3bad119186fd14fa95886cfc73c6953a4dd00e74 /fs/proc/namespaces.c
parent68c61471138402e34489edc5efde4f0fc5beaa25 (diff)
[readdir] convert procfs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/proc/namespaces.c')
-rw-r--r--fs/proc/namespaces.c74
1 files changed, 18 insertions, 56 deletions
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index 54bdc6701e9f..f6abbbbfad8a 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -213,74 +213,36 @@ out:
213 return error; 213 return error;
214} 214}
215 215
216static int proc_ns_fill_cache(struct file *filp, void *dirent, 216static int proc_ns_dir_readdir(struct file *file, struct dir_context *ctx)
217 filldir_t filldir, struct task_struct *task,
218 const struct proc_ns_operations *ops)
219{ 217{
220 return proc_fill_cache(filp, dirent, filldir, 218 struct task_struct *task = get_proc_task(file_inode(file));
221 ops->name, strlen(ops->name),
222 proc_ns_instantiate, task, ops);
223}
224
225static int proc_ns_dir_readdir(struct file *filp, void *dirent,
226 filldir_t filldir)
227{
228 int i;
229 struct dentry *dentry = filp->f_path.dentry;
230 struct inode *inode = dentry->d_inode;
231 struct task_struct *task = get_proc_task(inode);
232 const struct proc_ns_operations **entry, **last; 219 const struct proc_ns_operations **entry, **last;
233 ino_t ino;
234 int ret;
235 220
236 ret = -ENOENT;
237 if (!task) 221 if (!task)
238 goto out_no_task; 222 return -ENOENT;
239 223
240 ret = 0; 224 if (!dir_emit_dots(file, ctx))
241 i = filp->f_pos; 225 goto out;
242 switch (i) { 226 if (ctx->pos >= 2 + ARRAY_SIZE(ns_entries))
243 case 0: 227 goto out;
244 ino = inode->i_ino; 228 entry = ns_entries + (ctx->pos - 2);
245 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) 229 last = &ns_entries[ARRAY_SIZE(ns_entries) - 1];
246 goto out; 230 while (entry <= last) {
247 i++; 231 const struct proc_ns_operations *ops = *entry;
248 filp->f_pos++; 232 if (!proc_fill_cache(file, ctx, ops->name, strlen(ops->name),
249 /* fall through */ 233 proc_ns_instantiate, task, ops))
250 case 1: 234 break;
251 ino = parent_ino(dentry); 235 ctx->pos++;
252 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) 236 entry++;
253 goto out;
254 i++;
255 filp->f_pos++;
256 /* fall through */
257 default:
258 i -= 2;
259 if (i >= ARRAY_SIZE(ns_entries)) {
260 ret = 1;
261 goto out;
262 }
263 entry = ns_entries + i;
264 last = &ns_entries[ARRAY_SIZE(ns_entries) - 1];
265 while (entry <= last) {
266 if (proc_ns_fill_cache(filp, dirent, filldir,
267 task, *entry) < 0)
268 goto out;
269 filp->f_pos++;
270 entry++;
271 }
272 } 237 }
273
274 ret = 1;
275out: 238out:
276 put_task_struct(task); 239 put_task_struct(task);
277out_no_task: 240 return 0;
278 return ret;
279} 241}
280 242
281const struct file_operations proc_ns_dir_operations = { 243const struct file_operations proc_ns_dir_operations = {
282 .read = generic_read_dir, 244 .read = generic_read_dir,
283 .readdir = proc_ns_dir_readdir, 245 .iterate = proc_ns_dir_readdir,
284}; 246};
285 247
286static struct dentry *proc_ns_dir_lookup(struct inode *dir, 248static struct dentry *proc_ns_dir_lookup(struct inode *dir,