summary refs log tree commit diff
path: root/fs/file.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-08-21 22:32:06 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-26 21:09:59 -0400
commitc3c073f808b22dfae15ef8412b6f7b998644139a (patch)
tree3369bcbe414738d90e6ccfe257f6ce3e72f6a5ae /fs/file.c
parentad47bd7252bf402fe7dba92f5240b5ed16832ae7 (diff)
downloadlinux-c3c073f808b22dfae15ef8412b6f7b998644139a.tar.gz
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.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/file.c b/fs/file.c
index 967bd0dadbe5..e6e418122587 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -979,3 +979,24 @@ int f_dupfd(unsigned int from, struct file *file, unsigned flags)
 	}
 	return err;
 }
+
+int iterate_fd(struct files_struct *files, unsigned n,
+		int (*f)(const void *, struct file *, unsigned),
+		const void *p)
+{
+	struct fdtable *fdt;
+	struct file *file;
+	int res = 0;
+	if (!files)
+		return 0;
+	spin_lock(&files->file_lock);
+	fdt = files_fdtable(files);
+	while (!res && n < fdt->max_fds) {
+		file = rcu_dereference_check_fdtable(files, fdt->fd[n++]);
+		if (file)
+			res = f(p, file, n);
+	}
+	spin_unlock(&files->file_lock);
+	return res;
+}
+EXPORT_SYMBOL(iterate_fd);