summaryrefslogtreecommitdiffstats
path: root/include/linux/fdtable.h
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-04-24 07:44:08 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-05-01 13:08:16 -0400
commit9f3acc3140444a900ab280de942291959f0f615d (patch)
tree0d7f3f9698071ff90fb9a127a4c6e86e1c37c945 /include/linux/fdtable.h
parenta2dcb44c3c5a8151d2d9f6ac8ad0789efcdbe184 (diff)
[PATCH] split linux/file.h
Initial splitoff of the low-level stuff; taken to fdtable.h Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux/fdtable.h')
-rw-r--r--include/linux/fdtable.h99
1 files changed, 99 insertions, 0 deletions
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
new file mode 100644
index 00000000000..a118f3c0b24
--- /dev/null
+++ b/include/linux/fdtable.h
@@ -0,0 +1,99 @@
+/*
+ * descriptor table internals; you almost certainly want file.h instead.
+ */
+
+#ifndef __LINUX_FDTABLE_H
+#define __LINUX_FDTABLE_H
+
+#include <asm/atomic.h>
+#include <linux/posix_types.h>
+#include <linux/compiler.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/types.h>
+
+/*
+ * The default fd array needs to be at least BITS_PER_LONG,
+ * as this is the granularity returned by copy_fdset().
+ */
+#define NR_OPEN_DEFAULT BITS_PER_LONG
+
+/*
+ * The embedded_fd_set is a small fd_set,
+ * suitable for most tasks (which open <= BITS_PER_LONG files)
+ */
+struct embedded_fd_set {
+ unsigned long fds_bits[1];
+};
+
+struct fdtable {
+ unsigned int max_fds;
+ struct file ** fd; /* current fd array */
+ fd_set *close_on_exec;
+ fd_set *open_fds;
+ struct rcu_head rcu;
+ struct fdtable *next;
+};
+
+/*
+ * Open file table structure
+ */
+struct files_struct {
+ /*
+ * read mostly part
+ */
+ atomic_t count;
+ struct fdtable *fdt;
+ struct fdtable fdtab;
+ /*
+ * written part on a separate cache line in SMP
+ */
+ spinlock_t file_lock ____cacheline_aligned_in_smp;
+ int next_fd;
+ struct embedded_fd_set close_on_exec_init;
+ struct embedded_fd_set open_fds_init;
+ struct file * fd_array[NR_OPEN_DEFAULT];
+};
+
+#define files_fdtable(files) (rcu_dereference((files)->fdt))
+
+extern struct kmem_cache *filp_cachep;
+
+struct file_operations;
+struct vfsmount;
+struct dentry;
+
+extern int expand_files(struct files_struct *, int nr);
+extern void free_fdtable_rcu(struct rcu_head *rcu);
+extern void __init files_defer_init(void);
+
+static inline void free_fdtable(struct fdtable *fdt)
+{
+ call_rcu(&fdt->rcu, free_fdtable_rcu);
+}
+
+static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
+{
+ struct file * file = NULL;
+ struct fdtable *fdt = files_fdtable(files);
+
+ if (fd < fdt->max_fds)
+ file = rcu_dereference(fdt->fd[fd]);
+ return file;
+}
+
+/*
+ * Check whether the specified fd has an open file.
+ */
+#define fcheck(fd) fcheck_files(current->files, fd)
+
+struct task_struct;
+
+struct files_struct *get_files_struct(struct task_struct *);
+void put_files_struct(struct files_struct *fs);
+void reset_files_struct(struct files_struct *);
+int unshare_files(struct files_struct **);
+
+extern struct kmem_cache *files_cachep;
+
+#endif /* __LINUX_FDTABLE_H */