From 1fd36adcd98c14d2fd97f545293c488775cb2823 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 16 Feb 2012 17:49:54 +0000 Subject: Replace the fd_sets in struct fdtable with an array of unsigned longs Replace the fd_sets in struct fdtable with an array of unsigned longs and then use the standard non-atomic bit operations rather than the FD_* macros. This: (1) Removes the abuses of struct fd_set: (a) Since we don't want to allocate a full fd_set the vast majority of the time, we actually, in effect, just allocate a just-big-enough array of unsigned longs and cast it to an fd_set type - so why bother with the fd_set at all? (b) Some places outside of the core fdtable handling code (such as SELinux) want to look inside the array of unsigned longs hidden inside the fd_set struct for more efficient iteration over the entire set. (2) Eliminates the use of FD_*() macros in the kernel completely. (3) Permits the __FD_*() macros to be deleted entirely where not exposed to userspace. Signed-off-by: David Howells Link: http://lkml.kernel.org/r/20120216174954.23314.48147.stgit@warthog.procyon.org.uk Signed-off-by: H. Peter Anvin Cc: Al Viro --- include/linux/fdtable.h | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 7675da2c18f7..158a41eed314 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -21,51 +21,43 @@ */ #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 __rcu **fd; /* current fd array */ - fd_set *close_on_exec; - fd_set *open_fds; + unsigned long *close_on_exec; + unsigned long *open_fds; struct rcu_head rcu; struct fdtable *next; }; static inline void __set_close_on_exec(int fd, struct fdtable *fdt) { - FD_SET(fd, fdt->close_on_exec); + __set_bit(fd, fdt->close_on_exec); } static inline void __clear_close_on_exec(int fd, struct fdtable *fdt) { - FD_CLR(fd, fdt->close_on_exec); + __clear_bit(fd, fdt->close_on_exec); } static inline bool close_on_exec(int fd, const struct fdtable *fdt) { - return FD_ISSET(fd, fdt->close_on_exec); + return test_bit(fd, fdt->close_on_exec); } static inline void __set_open_fd(int fd, struct fdtable *fdt) { - FD_SET(fd, fdt->open_fds); + __set_bit(fd, fdt->open_fds); } static inline void __clear_open_fd(int fd, struct fdtable *fdt) { - FD_CLR(fd, fdt->open_fds); + __clear_bit(fd, fdt->open_fds); } static inline bool fd_is_open(int fd, const struct fdtable *fdt) { - return FD_ISSET(fd, fdt->open_fds); + return test_bit(fd, fdt->open_fds); } /* @@ -83,8 +75,8 @@ struct files_struct { */ 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; + unsigned long close_on_exec_init[1]; + unsigned long open_fds_init[1]; struct file __rcu * fd_array[NR_OPEN_DEFAULT]; }; -- cgit v1.2.3-71-gd317