diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-08-21 22:32:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-26 21:09:59 -0400 |
commit | c3c073f808b22dfae15ef8412b6f7b998644139a (patch) | |
tree | 3369bcbe414738d90e6ccfe257f6ce3e72f6a5ae /fs/file.c | |
parent | ad47bd7252bf402fe7dba92f5240b5ed16832ae7 (diff) |
new helper: iterate_fd()
iterates through the opened files in given descriptor table,
calling a supplied function; we stop once non-zero is returned.
Callback gets struct file *, descriptor number and const void *
argument passed to iterator. It is called with files->file_lock
held, so it is not allowed to block.
tty_io, netprio_cgroup and selinux flush_unauthorized_files()
converted to its use.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/file.c')
-rw-r--r-- | fs/file.c | 21 |
1 files changed, 21 insertions, 0 deletions
@@ -979,3 +979,24 @@ int f_dupfd(unsigned int from, struct file *file, unsigned flags) | |||
979 | } | 979 | } |
980 | return err; | 980 | return err; |
981 | } | 981 | } |
982 | |||
983 | int iterate_fd(struct files_struct *files, unsigned n, | ||
984 | int (*f)(const void *, struct file *, unsigned), | ||
985 | const void *p) | ||
986 | { | ||
987 | struct fdtable *fdt; | ||
988 | struct file *file; | ||
989 | int res = 0; | ||
990 | if (!files) | ||
991 | return 0; | ||
992 | spin_lock(&files->file_lock); | ||
993 | fdt = files_fdtable(files); | ||
994 | while (!res && n < fdt->max_fds) { | ||
995 | file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); | ||
996 | if (file) | ||
997 | res = f(p, file, n); | ||
998 | } | ||
999 | spin_unlock(&files->file_lock); | ||
1000 | return res; | ||
1001 | } | ||
1002 | EXPORT_SYMBOL(iterate_fd); | ||