diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-02 14:23:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-02 14:23:14 -0400 |
commit | b66e1f11ebc429569a3784aaf64123633d9e3ed1 (patch) | |
tree | d49f96acc682aaf29416921428110da5fd78fea4 /fs | |
parent | 1be1d6b7f3f6e3a87f872dd5e7a867d03d8a6851 (diff) | |
parent | 5c598b3428c372a1209597cee99a70da20625876 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
[PATCH] fix sysctl_nr_open bugs
[PATCH] sanitize anon_inode_getfd()
[PATCH] split linux/file.h
[PATCH] make osf_select() use core_sys_select()
[PATCH] remove horrors with irix tty ioctls handling
[PATCH] fix file and descriptor handling in perfmon
Diffstat (limited to 'fs')
-rw-r--r-- | fs/anon_inodes.c | 13 | ||||
-rw-r--r-- | fs/compat.c | 1 | ||||
-rw-r--r-- | fs/dnotify.c | 2 | ||||
-rw-r--r-- | fs/eventfd.c | 15 | ||||
-rw-r--r-- | fs/eventpoll.c | 23 | ||||
-rw-r--r-- | fs/exec.c | 1 | ||||
-rw-r--r-- | fs/fcntl.c | 1 | ||||
-rw-r--r-- | fs/file.c | 23 | ||||
-rw-r--r-- | fs/file_table.c | 1 | ||||
-rw-r--r-- | fs/locks.c | 1 | ||||
-rw-r--r-- | fs/open.c | 1 | ||||
-rw-r--r-- | fs/proc/array.c | 1 | ||||
-rw-r--r-- | fs/proc/base.c | 1 | ||||
-rw-r--r-- | fs/select.c | 3 | ||||
-rw-r--r-- | fs/signalfd.c | 17 | ||||
-rw-r--r-- | fs/timerfd.c | 11 |
16 files changed, 55 insertions, 60 deletions
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index f42be069e085..977ef208c051 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -57,9 +57,6 @@ static struct dentry_operations anon_inodefs_dentry_operations = { | |||
57 | * anonymous inode, and a dentry that describe the "class" | 57 | * anonymous inode, and a dentry that describe the "class" |
58 | * of the file | 58 | * of the file |
59 | * | 59 | * |
60 | * @pfd: [out] pointer to the file descriptor | ||
61 | * @dpinode: [out] pointer to the inode | ||
62 | * @pfile: [out] pointer to the file struct | ||
63 | * @name: [in] name of the "class" of the new file | 60 | * @name: [in] name of the "class" of the new file |
64 | * @fops [in] file operations for the new file | 61 | * @fops [in] file operations for the new file |
65 | * @priv [in] private data for the new file (will be file's private_data) | 62 | * @priv [in] private data for the new file (will be file's private_data) |
@@ -68,10 +65,9 @@ static struct dentry_operations anon_inodefs_dentry_operations = { | |||
68 | * that do not need to have a full-fledged inode in order to operate correctly. | 65 | * that do not need to have a full-fledged inode in order to operate correctly. |
69 | * All the files created with anon_inode_getfd() will share a single inode, | 66 | * All the files created with anon_inode_getfd() will share a single inode, |
70 | * hence saving memory and avoiding code duplication for the file/inode/dentry | 67 | * hence saving memory and avoiding code duplication for the file/inode/dentry |
71 | * setup. | 68 | * setup. Returns new descriptor or -error. |
72 | */ | 69 | */ |
73 | int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, | 70 | int anon_inode_getfd(const char *name, const struct file_operations *fops, |
74 | const char *name, const struct file_operations *fops, | ||
75 | void *priv) | 71 | void *priv) |
76 | { | 72 | { |
77 | struct qstr this; | 73 | struct qstr this; |
@@ -125,10 +121,7 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, | |||
125 | 121 | ||
126 | fd_install(fd, file); | 122 | fd_install(fd, file); |
127 | 123 | ||
128 | *pfd = fd; | 124 | return fd; |
129 | *pinode = anon_inode_inode; | ||
130 | *pfile = file; | ||
131 | return 0; | ||
132 | 125 | ||
133 | err_dput: | 126 | err_dput: |
134 | dput(dentry); | 127 | dput(dentry); |
diff --git a/fs/compat.c b/fs/compat.c index 139dc93c092d..332a869d2c53 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/fcntl.h> | 24 | #include <linux/fcntl.h> |
25 | #include <linux/namei.h> | 25 | #include <linux/namei.h> |
26 | #include <linux/file.h> | 26 | #include <linux/file.h> |
27 | #include <linux/fdtable.h> | ||
27 | #include <linux/vfs.h> | 28 | #include <linux/vfs.h> |
28 | #include <linux/ioctl.h> | 29 | #include <linux/ioctl.h> |
29 | #include <linux/init.h> | 30 | #include <linux/init.h> |
diff --git a/fs/dnotify.c b/fs/dnotify.c index eaecc4cfe540..676073b8dda5 100644 --- a/fs/dnotify.c +++ b/fs/dnotify.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/file.h> | 23 | #include <linux/fdtable.h> |
24 | 24 | ||
25 | int dir_notify_enable __read_mostly = 1; | 25 | int dir_notify_enable __read_mostly = 1; |
26 | 26 | ||
diff --git a/fs/eventfd.c b/fs/eventfd.c index a9f130cd50ac..343942deeec1 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c | |||
@@ -200,10 +200,8 @@ struct file *eventfd_fget(int fd) | |||
200 | 200 | ||
201 | asmlinkage long sys_eventfd(unsigned int count) | 201 | asmlinkage long sys_eventfd(unsigned int count) |
202 | { | 202 | { |
203 | int error, fd; | 203 | int fd; |
204 | struct eventfd_ctx *ctx; | 204 | struct eventfd_ctx *ctx; |
205 | struct file *file; | ||
206 | struct inode *inode; | ||
207 | 205 | ||
208 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); | 206 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
209 | if (!ctx) | 207 | if (!ctx) |
@@ -216,12 +214,9 @@ asmlinkage long sys_eventfd(unsigned int count) | |||
216 | * When we call this, the initialization must be complete, since | 214 | * When we call this, the initialization must be complete, since |
217 | * anon_inode_getfd() will install the fd. | 215 | * anon_inode_getfd() will install the fd. |
218 | */ | 216 | */ |
219 | error = anon_inode_getfd(&fd, &inode, &file, "[eventfd]", | 217 | fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx); |
220 | &eventfd_fops, ctx); | 218 | if (fd < 0) |
221 | if (!error) | 219 | kfree(ctx); |
222 | return fd; | 220 | return fd; |
223 | |||
224 | kfree(ctx); | ||
225 | return error; | ||
226 | } | 221 | } |
227 | 222 | ||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 221086fef174..990c01d2d66b 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -1050,8 +1050,6 @@ asmlinkage long sys_epoll_create(int size) | |||
1050 | { | 1050 | { |
1051 | int error, fd = -1; | 1051 | int error, fd = -1; |
1052 | struct eventpoll *ep; | 1052 | struct eventpoll *ep; |
1053 | struct inode *inode; | ||
1054 | struct file *file; | ||
1055 | 1053 | ||
1056 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n", | 1054 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n", |
1057 | current, size)); | 1055 | current, size)); |
@@ -1061,29 +1059,24 @@ asmlinkage long sys_epoll_create(int size) | |||
1061 | * structure ( "struct eventpoll" ). | 1059 | * structure ( "struct eventpoll" ). |
1062 | */ | 1060 | */ |
1063 | error = -EINVAL; | 1061 | error = -EINVAL; |
1064 | if (size <= 0 || (error = ep_alloc(&ep)) != 0) | 1062 | if (size <= 0 || (error = ep_alloc(&ep)) < 0) { |
1063 | fd = error; | ||
1065 | goto error_return; | 1064 | goto error_return; |
1065 | } | ||
1066 | 1066 | ||
1067 | /* | 1067 | /* |
1068 | * Creates all the items needed to setup an eventpoll file. That is, | 1068 | * Creates all the items needed to setup an eventpoll file. That is, |
1069 | * a file structure, and inode and a free file descriptor. | 1069 | * a file structure and a free file descriptor. |
1070 | */ | 1070 | */ |
1071 | error = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]", | 1071 | fd = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep); |
1072 | &eventpoll_fops, ep); | 1072 | if (fd < 0) |
1073 | if (error) | 1073 | ep_free(ep); |
1074 | goto error_free; | ||
1075 | 1074 | ||
1075 | error_return: | ||
1076 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", | 1076 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", |
1077 | current, size, fd)); | 1077 | current, size, fd)); |
1078 | 1078 | ||
1079 | return fd; | 1079 | return fd; |
1080 | |||
1081 | error_free: | ||
1082 | ep_free(ep); | ||
1083 | error_return: | ||
1084 | DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", | ||
1085 | current, size, error)); | ||
1086 | return error; | ||
1087 | } | 1080 | } |
1088 | 1081 | ||
1089 | /* | 1082 | /* |
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/file.h> | 26 | #include <linux/file.h> |
27 | #include <linux/fdtable.h> | ||
27 | #include <linux/mman.h> | 28 | #include <linux/mman.h> |
28 | #include <linux/a.out.h> | 29 | #include <linux/a.out.h> |
29 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 3f3ac630ccde..bfd776509a72 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
11 | #include <linux/file.h> | 11 | #include <linux/file.h> |
12 | #include <linux/fdtable.h> | ||
12 | #include <linux/capability.h> | 13 | #include <linux/capability.h> |
13 | #include <linux/dnotify.h> | 14 | #include <linux/dnotify.h> |
14 | #include <linux/smp_lock.h> | 15 | #include <linux/smp_lock.h> |
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/vmalloc.h> | 13 | #include <linux/vmalloc.h> |
14 | #include <linux/file.h> | 14 | #include <linux/file.h> |
15 | #include <linux/fdtable.h> | ||
15 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
16 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
17 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
@@ -149,8 +150,16 @@ static struct fdtable * alloc_fdtable(unsigned int nr) | |||
149 | nr /= (1024 / sizeof(struct file *)); | 150 | nr /= (1024 / sizeof(struct file *)); |
150 | nr = roundup_pow_of_two(nr + 1); | 151 | nr = roundup_pow_of_two(nr + 1); |
151 | nr *= (1024 / sizeof(struct file *)); | 152 | nr *= (1024 / sizeof(struct file *)); |
152 | if (nr > sysctl_nr_open) | 153 | /* |
153 | nr = sysctl_nr_open; | 154 | * Note that this can drive nr *below* what we had passed if sysctl_nr_open |
155 | * had been set lower between the check in expand_files() and here. Deal | ||
156 | * with that in caller, it's cheaper that way. | ||
157 | * | ||
158 | * We make sure that nr remains a multiple of BITS_PER_LONG - otherwise | ||
159 | * bitmaps handling below becomes unpleasant, to put it mildly... | ||
160 | */ | ||
161 | if (unlikely(nr > sysctl_nr_open)) | ||
162 | nr = ((sysctl_nr_open - 1) | (BITS_PER_LONG - 1)) + 1; | ||
154 | 163 | ||
155 | fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL); | 164 | fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL); |
156 | if (!fdt) | 165 | if (!fdt) |
@@ -199,6 +208,16 @@ static int expand_fdtable(struct files_struct *files, int nr) | |||
199 | if (!new_fdt) | 208 | if (!new_fdt) |
200 | return -ENOMEM; | 209 | return -ENOMEM; |
201 | /* | 210 | /* |
211 | * extremely unlikely race - sysctl_nr_open decreased between the check in | ||
212 | * caller and alloc_fdtable(). Cheaper to catch it here... | ||
213 | */ | ||
214 | if (unlikely(new_fdt->max_fds <= nr)) { | ||
215 | free_fdarr(new_fdt); | ||
216 | free_fdset(new_fdt); | ||
217 | kfree(new_fdt); | ||
218 | return -EMFILE; | ||
219 | } | ||
220 | /* | ||
202 | * Check again since another task may have expanded the fd table while | 221 | * Check again since another task may have expanded the fd table while |
203 | * we dropped the lock | 222 | * we dropped the lock |
204 | */ | 223 | */ |
diff --git a/fs/file_table.c b/fs/file_table.c index 7a0a9b872251..83084225b4c3 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/string.h> | 8 | #include <linux/string.h> |
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/file.h> | 10 | #include <linux/file.h> |
11 | #include <linux/fdtable.h> | ||
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
diff --git a/fs/locks.c b/fs/locks.c index 44d9a6a7ec50..663c069b59b3 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -116,6 +116,7 @@ | |||
116 | 116 | ||
117 | #include <linux/capability.h> | 117 | #include <linux/capability.h> |
118 | #include <linux/file.h> | 118 | #include <linux/file.h> |
119 | #include <linux/fdtable.h> | ||
119 | #include <linux/fs.h> | 120 | #include <linux/fs.h> |
120 | #include <linux/init.h> | 121 | #include <linux/init.h> |
121 | #include <linux/module.h> | 122 | #include <linux/module.h> |
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/file.h> | 9 | #include <linux/file.h> |
10 | #include <linux/fdtable.h> | ||
10 | #include <linux/quotaops.h> | 11 | #include <linux/quotaops.h> |
11 | #include <linux/fsnotify.h> | 12 | #include <linux/fsnotify.h> |
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
diff --git a/fs/proc/array.c b/fs/proc/array.c index c135cbdd9127..dca997a93bff 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #include <linux/signal.h> | 73 | #include <linux/signal.h> |
74 | #include <linux/highmem.h> | 74 | #include <linux/highmem.h> |
75 | #include <linux/file.h> | 75 | #include <linux/file.h> |
76 | #include <linux/fdtable.h> | ||
76 | #include <linux/times.h> | 77 | #include <linux/times.h> |
77 | #include <linux/cpuset.h> | 78 | #include <linux/cpuset.h> |
78 | #include <linux/rcupdate.h> | 79 | #include <linux/rcupdate.h> |
diff --git a/fs/proc/base.c b/fs/proc/base.c index fcf02f2deeba..808cbdc193d3 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/init.h> | 56 | #include <linux/init.h> |
57 | #include <linux/capability.h> | 57 | #include <linux/capability.h> |
58 | #include <linux/file.h> | 58 | #include <linux/file.h> |
59 | #include <linux/fdtable.h> | ||
59 | #include <linux/string.h> | 60 | #include <linux/string.h> |
60 | #include <linux/seq_file.h> | 61 | #include <linux/seq_file.h> |
61 | #include <linux/namei.h> | 62 | #include <linux/namei.h> |
diff --git a/fs/select.c b/fs/select.c index 2c292146e246..8dda969614a9 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/poll.h> | 21 | #include <linux/poll.h> |
22 | #include <linux/personality.h> /* for STICKY_TIMEOUTS */ | 22 | #include <linux/personality.h> /* for STICKY_TIMEOUTS */ |
23 | #include <linux/file.h> | 23 | #include <linux/file.h> |
24 | #include <linux/fdtable.h> | ||
24 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
25 | #include <linux/rcupdate.h> | 26 | #include <linux/rcupdate.h> |
26 | 27 | ||
@@ -298,7 +299,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout) | |||
298 | #define MAX_SELECT_SECONDS \ | 299 | #define MAX_SELECT_SECONDS \ |
299 | ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) | 300 | ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) |
300 | 301 | ||
301 | static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | 302 | int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, |
302 | fd_set __user *exp, s64 *timeout) | 303 | fd_set __user *exp, s64 *timeout) |
303 | { | 304 | { |
304 | fd_set_bits fds; | 305 | fd_set_bits fds; |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 8ead0db35933..619725644c75 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -207,11 +207,8 @@ static const struct file_operations signalfd_fops = { | |||
207 | 207 | ||
208 | asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask) | 208 | asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask) |
209 | { | 209 | { |
210 | int error; | ||
211 | sigset_t sigmask; | 210 | sigset_t sigmask; |
212 | struct signalfd_ctx *ctx; | 211 | struct signalfd_ctx *ctx; |
213 | struct file *file; | ||
214 | struct inode *inode; | ||
215 | 212 | ||
216 | if (sizemask != sizeof(sigset_t) || | 213 | if (sizemask != sizeof(sigset_t) || |
217 | copy_from_user(&sigmask, user_mask, sizeof(sigmask))) | 214 | copy_from_user(&sigmask, user_mask, sizeof(sigmask))) |
@@ -230,12 +227,11 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas | |||
230 | * When we call this, the initialization must be complete, since | 227 | * When we call this, the initialization must be complete, since |
231 | * anon_inode_getfd() will install the fd. | 228 | * anon_inode_getfd() will install the fd. |
232 | */ | 229 | */ |
233 | error = anon_inode_getfd(&ufd, &inode, &file, "[signalfd]", | 230 | ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx); |
234 | &signalfd_fops, ctx); | 231 | if (ufd < 0) |
235 | if (error) | 232 | kfree(ctx); |
236 | goto err_fdalloc; | ||
237 | } else { | 233 | } else { |
238 | file = fget(ufd); | 234 | struct file *file = fget(ufd); |
239 | if (!file) | 235 | if (!file) |
240 | return -EBADF; | 236 | return -EBADF; |
241 | ctx = file->private_data; | 237 | ctx = file->private_data; |
@@ -252,9 +248,4 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas | |||
252 | } | 248 | } |
253 | 249 | ||
254 | return ufd; | 250 | return ufd; |
255 | |||
256 | err_fdalloc: | ||
257 | kfree(ctx); | ||
258 | return error; | ||
259 | } | 251 | } |
260 | |||
diff --git a/fs/timerfd.c b/fs/timerfd.c index 5400524e9cb1..d87d354ec424 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
@@ -181,10 +181,8 @@ static struct file *timerfd_fget(int fd) | |||
181 | 181 | ||
182 | asmlinkage long sys_timerfd_create(int clockid, int flags) | 182 | asmlinkage long sys_timerfd_create(int clockid, int flags) |
183 | { | 183 | { |
184 | int error, ufd; | 184 | int ufd; |
185 | struct timerfd_ctx *ctx; | 185 | struct timerfd_ctx *ctx; |
186 | struct file *file; | ||
187 | struct inode *inode; | ||
188 | 186 | ||
189 | if (flags) | 187 | if (flags) |
190 | return -EINVAL; | 188 | return -EINVAL; |
@@ -200,12 +198,9 @@ asmlinkage long sys_timerfd_create(int clockid, int flags) | |||
200 | ctx->clockid = clockid; | 198 | ctx->clockid = clockid; |
201 | hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); | 199 | hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); |
202 | 200 | ||
203 | error = anon_inode_getfd(&ufd, &inode, &file, "[timerfd]", | 201 | ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx); |
204 | &timerfd_fops, ctx); | 202 | if (ufd < 0) |
205 | if (error) { | ||
206 | kfree(ctx); | 203 | kfree(ctx); |
207 | return error; | ||
208 | } | ||
209 | 204 | ||
210 | return ufd; | 205 | return ufd; |
211 | } | 206 | } |