diff options
author | David Howells <dhowells@redhat.com> | 2012-02-16 12:49:54 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2012-02-19 13:30:57 -0500 |
commit | 1fd36adcd98c14d2fd97f545293c488775cb2823 (patch) | |
tree | c13ab1934a15aebe0d81601d910ce5a3c6fa2c6f /include/linux/fdtable.h | |
parent | 1dce27c5aa6770e9d195f2bb7db1db3d4dde5591 (diff) |
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 <dhowells@redhat.com>
Link: http://lkml.kernel.org/r/20120216174954.23314.48147.stgit@warthog.procyon.org.uk
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux/fdtable.h')
-rw-r--r-- | include/linux/fdtable.h | 28 |
1 files changed, 10 insertions, 18 deletions
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 @@ | |||
21 | */ | 21 | */ |
22 | #define NR_OPEN_DEFAULT BITS_PER_LONG | 22 | #define NR_OPEN_DEFAULT BITS_PER_LONG |
23 | 23 | ||
24 | /* | ||
25 | * The embedded_fd_set is a small fd_set, | ||
26 | * suitable for most tasks (which open <= BITS_PER_LONG files) | ||
27 | */ | ||
28 | struct embedded_fd_set { | ||
29 | unsigned long fds_bits[1]; | ||
30 | }; | ||
31 | |||
32 | struct fdtable { | 24 | struct fdtable { |
33 | unsigned int max_fds; | 25 | unsigned int max_fds; |
34 | struct file __rcu **fd; /* current fd array */ | 26 | struct file __rcu **fd; /* current fd array */ |
35 | fd_set *close_on_exec; | 27 | unsigned long *close_on_exec; |
36 | fd_set *open_fds; | 28 | unsigned long *open_fds; |
37 | struct rcu_head rcu; | 29 | struct rcu_head rcu; |
38 | struct fdtable *next; | 30 | struct fdtable *next; |
39 | }; | 31 | }; |
40 | 32 | ||
41 | static inline void __set_close_on_exec(int fd, struct fdtable *fdt) | 33 | static inline void __set_close_on_exec(int fd, struct fdtable *fdt) |
42 | { | 34 | { |
43 | FD_SET(fd, fdt->close_on_exec); | 35 | __set_bit(fd, fdt->close_on_exec); |
44 | } | 36 | } |
45 | 37 | ||
46 | static inline void __clear_close_on_exec(int fd, struct fdtable *fdt) | 38 | static inline void __clear_close_on_exec(int fd, struct fdtable *fdt) |
47 | { | 39 | { |
48 | FD_CLR(fd, fdt->close_on_exec); | 40 | __clear_bit(fd, fdt->close_on_exec); |
49 | } | 41 | } |
50 | 42 | ||
51 | static inline bool close_on_exec(int fd, const struct fdtable *fdt) | 43 | static inline bool close_on_exec(int fd, const struct fdtable *fdt) |
52 | { | 44 | { |
53 | return FD_ISSET(fd, fdt->close_on_exec); | 45 | return test_bit(fd, fdt->close_on_exec); |
54 | } | 46 | } |
55 | 47 | ||
56 | static inline void __set_open_fd(int fd, struct fdtable *fdt) | 48 | static inline void __set_open_fd(int fd, struct fdtable *fdt) |
57 | { | 49 | { |
58 | FD_SET(fd, fdt->open_fds); | 50 | __set_bit(fd, fdt->open_fds); |
59 | } | 51 | } |
60 | 52 | ||
61 | static inline void __clear_open_fd(int fd, struct fdtable *fdt) | 53 | static inline void __clear_open_fd(int fd, struct fdtable *fdt) |
62 | { | 54 | { |
63 | FD_CLR(fd, fdt->open_fds); | 55 | __clear_bit(fd, fdt->open_fds); |
64 | } | 56 | } |
65 | 57 | ||
66 | static inline bool fd_is_open(int fd, const struct fdtable *fdt) | 58 | static inline bool fd_is_open(int fd, const struct fdtable *fdt) |
67 | { | 59 | { |
68 | return FD_ISSET(fd, fdt->open_fds); | 60 | return test_bit(fd, fdt->open_fds); |
69 | } | 61 | } |
70 | 62 | ||
71 | /* | 63 | /* |
@@ -83,8 +75,8 @@ struct files_struct { | |||
83 | */ | 75 | */ |
84 | spinlock_t file_lock ____cacheline_aligned_in_smp; | 76 | spinlock_t file_lock ____cacheline_aligned_in_smp; |
85 | int next_fd; | 77 | int next_fd; |
86 | struct embedded_fd_set close_on_exec_init; | 78 | unsigned long close_on_exec_init[1]; |
87 | struct embedded_fd_set open_fds_init; | 79 | unsigned long open_fds_init[1]; |
88 | struct file __rcu * fd_array[NR_OPEN_DEFAULT]; | 80 | struct file __rcu * fd_array[NR_OPEN_DEFAULT]; |
89 | }; | 81 | }; |
90 | 82 | ||