X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=include%2Flinux%2Ffile.h;fp=include%2Flinux%2Ffile.h;h=19a856f02f186ca475d647710c886ebce77e6f10;hp=5206beb9a80e562df9377e37a2cad4cb0b8e016f;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hpb=cee37fe97739d85991964371c1f3a745c00dd236 diff --git a/include/linux/file.h b/include/linux/file.h index 5206beb9a..19a856f02 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include /* * The default fd array needs to be at least BITS_PER_LONG, @@ -16,23 +18,52 @@ */ #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]; +}; + +/* + * More than this number of fds: we use a separately allocated fd_set + */ +#define EMBEDDED_FD_SET_SIZE (BITS_PER_BYTE * sizeof(struct embedded_fd_set)) + +struct fdtable { + unsigned int max_fds; + int max_fdset; + struct file ** fd; /* current fd array */ + fd_set *close_on_exec; + fd_set *open_fds; + struct rcu_head rcu; + struct files_struct *free_files; + struct fdtable *next; +}; + /* * Open file table structure */ struct files_struct { - atomic_t count; - spinlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */ - int max_fds; - int max_fdset; - int next_fd; - struct file ** fd; /* current fd array */ - fd_set *close_on_exec; - fd_set *open_fds; - fd_set close_on_exec_init; - fd_set open_fds_init; - struct file * fd_array[NR_OPEN_DEFAULT]; + /* + * 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 void FASTCALL(__fput(struct file *)); extern void FASTCALL(fput(struct file *)); @@ -48,9 +79,7 @@ extern void FASTCALL(set_close_on_exec(unsigned int fd, int flag)); extern void put_filp(struct file *); extern int get_unused_fd(void); extern void FASTCALL(put_unused_fd(unsigned int fd)); -struct kmem_cache_s; -extern void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags); -extern void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags); +struct kmem_cache; extern struct file ** alloc_fd_array(int); extern void free_fd_array(struct file **, int); @@ -59,13 +88,16 @@ extern fd_set *alloc_fdset(int); extern void free_fdset(fd_set *, int); extern int expand_files(struct files_struct *, int nr); +extern void free_fdtable(struct fdtable *fdt); +extern void __init files_defer_init(void); 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 < files->max_fds) - file = files->fd[fd]; + if (fd < fdt->max_fds) + file = rcu_dereference(fdt->fd[fd]); return file; } @@ -81,4 +113,6 @@ struct task_struct; struct files_struct *get_files_struct(struct task_struct *); void FASTCALL(put_files_struct(struct files_struct *fs)); +extern int dupfd(struct file *file, unsigned int start); + #endif /* __LINUX_FILE_H */