X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Flinux%2Ffile.h;h=a59001e9ea58bb2cd91c999d6b0f9dba6ac06f7e;hb=a2f44b27303a5353859d77a3e96a1d3f33f56ab7;hp=a029c045a302a6a9b8f37f292683f226467db1e7;hpb=cace1c4618b6c6442b7dc973e935e7f3268e4aa7;p=linux-2.6.git diff --git a/include/linux/file.h b/include/linux/file.h index a029c045a..a59001e9e 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,47 @@ */ #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 { - 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 struct kmem_cache *filp_cachep; + extern void FASTCALL(__fput(struct file *)); extern void FASTCALL(fput(struct file *)); @@ -48,24 +74,24 @@ 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); - -extern struct file ** alloc_fd_array(int); -extern void free_fd_array(struct file **, int); - -extern fd_set *alloc_fdset(int); -extern void free_fdset(fd_set *, int); +struct kmem_cache; 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 < files->max_fds) - file = files->fd[fd]; + if (fd < fdt->max_fds) + file = rcu_dereference(fdt->fd[fd]); return file; } @@ -80,7 +106,8 @@ struct task_struct; struct files_struct *get_files_struct(struct task_struct *); void FASTCALL(put_files_struct(struct files_struct *fs)); +void reset_files_struct(struct task_struct *, struct files_struct *); -extern int dupfd(struct file *file, unsigned int start); +extern struct kmem_cache *files_cachep; #endif /* __LINUX_FILE_H */