aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c8
-rw-r--r--fs/fcntl.c47
-rw-r--r--fs/file.c42
-rw-r--r--fs/locks.c8
-rw-r--r--fs/open.c41
-rw-r--r--fs/proc/array.c5
-rw-r--r--fs/proc/base.c4
-rw-r--r--fs/select.c12
8 files changed, 104 insertions, 63 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 222ab1c572d8..14dd03907ccb 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -798,6 +798,7 @@ no_thread_group:
798static inline void flush_old_files(struct files_struct * files) 798static inline void flush_old_files(struct files_struct * files)
799{ 799{
800 long j = -1; 800 long j = -1;
801 struct fdtable *fdt;
801 802
802 spin_lock(&files->file_lock); 803 spin_lock(&files->file_lock);
803 for (;;) { 804 for (;;) {
@@ -805,12 +806,13 @@ static inline void flush_old_files(struct files_struct * files)
805 806
806 j++; 807 j++;
807 i = j * __NFDBITS; 808 i = j * __NFDBITS;
808 if (i >= files->max_fds || i >= files->max_fdset) 809 fdt = files_fdtable(files);
810 if (i >= fdt->max_fds || i >= fdt->max_fdset)
809 break; 811 break;
810 set = files->close_on_exec->fds_bits[j]; 812 set = fdt->close_on_exec->fds_bits[j];
811 if (!set) 813 if (!set)
812 continue; 814 continue;
813 files->close_on_exec->fds_bits[j] = 0; 815 fdt->close_on_exec->fds_bits[j] = 0;
814 spin_unlock(&files->file_lock); 816 spin_unlock(&files->file_lock);
815 for ( ; set ; i++,set >>= 1) { 817 for ( ; set ; i++,set >>= 1) {
816 if (set & 1) { 818 if (set & 1) {
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 6fbc9d8fcc36..bfecc6238083 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -24,20 +24,24 @@
24void fastcall set_close_on_exec(unsigned int fd, int flag) 24void fastcall set_close_on_exec(unsigned int fd, int flag)
25{ 25{
26 struct files_struct *files = current->files; 26 struct files_struct *files = current->files;
27 struct fdtable *fdt;
27 spin_lock(&files->file_lock); 28 spin_lock(&files->file_lock);
29 fdt = files_fdtable(files);
28 if (flag) 30 if (flag)
29 FD_SET(fd, files->close_on_exec); 31 FD_SET(fd, fdt->close_on_exec);
30 else 32 else
31 FD_CLR(fd, files->close_on_exec); 33 FD_CLR(fd, fdt->close_on_exec);
32 spin_unlock(&files->file_lock); 34 spin_unlock(&files->file_lock);
33} 35}
34 36
35static inline int get_close_on_exec(unsigned int fd) 37static inline int get_close_on_exec(unsigned int fd)
36{ 38{
37 struct files_struct *files = current->files; 39 struct files_struct *files = current->files;
40 struct fdtable *fdt;
38 int res; 41 int res;
39 spin_lock(&files->file_lock); 42 spin_lock(&files->file_lock);
40 res = FD_ISSET(fd, files->close_on_exec); 43 fdt = files_fdtable(files);
44 res = FD_ISSET(fd, fdt->close_on_exec);
41 spin_unlock(&files->file_lock); 45 spin_unlock(&files->file_lock);
42 return res; 46 return res;
43} 47}
@@ -54,24 +58,26 @@ static int locate_fd(struct files_struct *files,
54 unsigned int newfd; 58 unsigned int newfd;
55 unsigned int start; 59 unsigned int start;
56 int error; 60 int error;
61 struct fdtable *fdt;
57 62
58 error = -EINVAL; 63 error = -EINVAL;
59 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) 64 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
60 goto out; 65 goto out;
61 66
67 fdt = files_fdtable(files);
62repeat: 68repeat:
63 /* 69 /*
64 * Someone might have closed fd's in the range 70 * Someone might have closed fd's in the range
65 * orig_start..files->next_fd 71 * orig_start..fdt->next_fd
66 */ 72 */
67 start = orig_start; 73 start = orig_start;
68 if (start < files->next_fd) 74 if (start < fdt->next_fd)
69 start = files->next_fd; 75 start = fdt->next_fd;
70 76
71 newfd = start; 77 newfd = start;
72 if (start < files->max_fdset) { 78 if (start < fdt->max_fdset) {
73 newfd = find_next_zero_bit(files->open_fds->fds_bits, 79 newfd = find_next_zero_bit(fdt->open_fds->fds_bits,
74 files->max_fdset, start); 80 fdt->max_fdset, start);
75 } 81 }
76 82
77 error = -EMFILE; 83 error = -EMFILE;
@@ -89,8 +95,8 @@ repeat:
89 if (error) 95 if (error)
90 goto repeat; 96 goto repeat;
91 97
92 if (start <= files->next_fd) 98 if (start <= fdt->next_fd)
93 files->next_fd = newfd + 1; 99 fdt->next_fd = newfd + 1;
94 100
95 error = newfd; 101 error = newfd;
96 102
@@ -101,13 +107,16 @@ out:
101static int dupfd(struct file *file, unsigned int start) 107static int dupfd(struct file *file, unsigned int start)
102{ 108{
103 struct files_struct * files = current->files; 109 struct files_struct * files = current->files;
110 struct fdtable *fdt;
104 int fd; 111 int fd;
105 112
106 spin_lock(&files->file_lock); 113 spin_lock(&files->file_lock);
107 fd = locate_fd(files, file, start); 114 fd = locate_fd(files, file, start);
108 if (fd >= 0) { 115 if (fd >= 0) {
109 FD_SET(fd, files->open_fds); 116 /* locate_fd() may have expanded fdtable, load the ptr */
110 FD_CLR(fd, files->close_on_exec); 117 fdt = files_fdtable(files);
118 FD_SET(fd, fdt->open_fds);
119 FD_CLR(fd, fdt->close_on_exec);
111 spin_unlock(&files->file_lock); 120 spin_unlock(&files->file_lock);
112 fd_install(fd, file); 121 fd_install(fd, file);
113 } else { 122 } else {
@@ -123,6 +132,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
123 int err = -EBADF; 132 int err = -EBADF;
124 struct file * file, *tofree; 133 struct file * file, *tofree;
125 struct files_struct * files = current->files; 134 struct files_struct * files = current->files;
135 struct fdtable *fdt;
126 136
127 spin_lock(&files->file_lock); 137 spin_lock(&files->file_lock);
128 if (!(file = fcheck(oldfd))) 138 if (!(file = fcheck(oldfd)))
@@ -148,13 +158,14 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
148 158
149 /* Yes. It's a race. In user space. Nothing sane to do */ 159 /* Yes. It's a race. In user space. Nothing sane to do */
150 err = -EBUSY; 160 err = -EBUSY;
151 tofree = files->fd[newfd]; 161 fdt = files_fdtable(files);
152 if (!tofree && FD_ISSET(newfd, files->open_fds)) 162 tofree = fdt->fd[newfd];
163 if (!tofree && FD_ISSET(newfd, fdt->open_fds))
153 goto out_fput; 164 goto out_fput;
154 165
155 files->fd[newfd] = file; 166 fdt->fd[newfd] = file;
156 FD_SET(newfd, files->open_fds); 167 FD_SET(newfd, fdt->open_fds);
157 FD_CLR(newfd, files->close_on_exec); 168 FD_CLR(newfd, fdt->close_on_exec);
158 spin_unlock(&files->file_lock); 169 spin_unlock(&files->file_lock);
159 170
160 if (tofree) 171 if (tofree)
diff --git a/fs/file.c b/fs/file.c
index 92b5f25985d2..f5926ce73f37 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -59,13 +59,15 @@ static int expand_fd_array(struct files_struct *files, int nr)
59{ 59{
60 struct file **new_fds; 60 struct file **new_fds;
61 int error, nfds; 61 int error, nfds;
62 struct fdtable *fdt;
62 63
63 64
64 error = -EMFILE; 65 error = -EMFILE;
65 if (files->max_fds >= NR_OPEN || nr >= NR_OPEN) 66 fdt = files_fdtable(files);
67 if (fdt->max_fds >= NR_OPEN || nr >= NR_OPEN)
66 goto out; 68 goto out;
67 69
68 nfds = files->max_fds; 70 nfds = fdt->max_fds;
69 spin_unlock(&files->file_lock); 71 spin_unlock(&files->file_lock);
70 72
71 /* 73 /*
@@ -95,13 +97,14 @@ static int expand_fd_array(struct files_struct *files, int nr)
95 goto out; 97 goto out;
96 98
97 /* Copy the existing array and install the new pointer */ 99 /* Copy the existing array and install the new pointer */
100 fdt = files_fdtable(files);
98 101
99 if (nfds > files->max_fds) { 102 if (nfds > fdt->max_fds) {
100 struct file **old_fds; 103 struct file **old_fds;
101 int i; 104 int i;
102 105
103 old_fds = xchg(&files->fd, new_fds); 106 old_fds = xchg(&fdt->fd, new_fds);
104 i = xchg(&files->max_fds, nfds); 107 i = xchg(&fdt->max_fds, nfds);
105 108
106 /* Don't copy/clear the array if we are creating a new 109 /* Don't copy/clear the array if we are creating a new
107 fd array for fork() */ 110 fd array for fork() */
@@ -164,12 +167,14 @@ static int expand_fdset(struct files_struct *files, int nr)
164{ 167{
165 fd_set *new_openset = NULL, *new_execset = NULL; 168 fd_set *new_openset = NULL, *new_execset = NULL;
166 int error, nfds = 0; 169 int error, nfds = 0;
170 struct fdtable *fdt;
167 171
168 error = -EMFILE; 172 error = -EMFILE;
169 if (files->max_fdset >= NR_OPEN || nr >= NR_OPEN) 173 fdt = files_fdtable(files);
174 if (fdt->max_fdset >= NR_OPEN || nr >= NR_OPEN)
170 goto out; 175 goto out;
171 176
172 nfds = files->max_fdset; 177 nfds = fdt->max_fdset;
173 spin_unlock(&files->file_lock); 178 spin_unlock(&files->file_lock);
174 179
175 /* Expand to the max in easy steps */ 180 /* Expand to the max in easy steps */
@@ -193,24 +198,25 @@ static int expand_fdset(struct files_struct *files, int nr)
193 error = 0; 198 error = 0;
194 199
195 /* Copy the existing tables and install the new pointers */ 200 /* Copy the existing tables and install the new pointers */
196 if (nfds > files->max_fdset) { 201 fdt = files_fdtable(files);
197 int i = files->max_fdset / (sizeof(unsigned long) * 8); 202 if (nfds > fdt->max_fdset) {
198 int count = (nfds - files->max_fdset) / 8; 203 int i = fdt->max_fdset / (sizeof(unsigned long) * 8);
204 int count = (nfds - fdt->max_fdset) / 8;
199 205
200 /* 206 /*
201 * Don't copy the entire array if the current fdset is 207 * Don't copy the entire array if the current fdset is
202 * not yet initialised. 208 * not yet initialised.
203 */ 209 */
204 if (i) { 210 if (i) {
205 memcpy (new_openset, files->open_fds, files->max_fdset/8); 211 memcpy (new_openset, fdt->open_fds, fdt->max_fdset/8);
206 memcpy (new_execset, files->close_on_exec, files->max_fdset/8); 212 memcpy (new_execset, fdt->close_on_exec, fdt->max_fdset/8);
207 memset (&new_openset->fds_bits[i], 0, count); 213 memset (&new_openset->fds_bits[i], 0, count);
208 memset (&new_execset->fds_bits[i], 0, count); 214 memset (&new_execset->fds_bits[i], 0, count);
209 } 215 }
210 216
211 nfds = xchg(&files->max_fdset, nfds); 217 nfds = xchg(&fdt->max_fdset, nfds);
212 new_openset = xchg(&files->open_fds, new_openset); 218 new_openset = xchg(&fdt->open_fds, new_openset);
213 new_execset = xchg(&files->close_on_exec, new_execset); 219 new_execset = xchg(&fdt->close_on_exec, new_execset);
214 spin_unlock(&files->file_lock); 220 spin_unlock(&files->file_lock);
215 free_fdset (new_openset, nfds); 221 free_fdset (new_openset, nfds);
216 free_fdset (new_execset, nfds); 222 free_fdset (new_execset, nfds);
@@ -237,13 +243,15 @@ out:
237int expand_files(struct files_struct *files, int nr) 243int expand_files(struct files_struct *files, int nr)
238{ 244{
239 int err, expand = 0; 245 int err, expand = 0;
246 struct fdtable *fdt;
240 247
241 if (nr >= files->max_fdset) { 248 fdt = files_fdtable(files);
249 if (nr >= fdt->max_fdset) {
242 expand = 1; 250 expand = 1;
243 if ((err = expand_fdset(files, nr))) 251 if ((err = expand_fdset(files, nr)))
244 goto out; 252 goto out;
245 } 253 }
246 if (nr >= files->max_fds) { 254 if (nr >= fdt->max_fds) {
247 expand = 1; 255 expand = 1;
248 if ((err = expand_fd_array(files, nr))) 256 if ((err = expand_fd_array(files, nr)))
249 goto out; 257 goto out;
diff --git a/fs/locks.c b/fs/locks.c
index 11956b6179ff..c2c09b4798d6 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2198,21 +2198,23 @@ void steal_locks(fl_owner_t from)
2198{ 2198{
2199 struct files_struct *files = current->files; 2199 struct files_struct *files = current->files;
2200 int i, j; 2200 int i, j;
2201 struct fdtable *fdt;
2201 2202
2202 if (from == files) 2203 if (from == files)
2203 return; 2204 return;
2204 2205
2205 lock_kernel(); 2206 lock_kernel();
2206 j = 0; 2207 j = 0;
2208 fdt = files_fdtable(files);
2207 for (;;) { 2209 for (;;) {
2208 unsigned long set; 2210 unsigned long set;
2209 i = j * __NFDBITS; 2211 i = j * __NFDBITS;
2210 if (i >= files->max_fdset || i >= files->max_fds) 2212 if (i >= fdt->max_fdset || i >= fdt->max_fds)
2211 break; 2213 break;
2212 set = files->open_fds->fds_bits[j++]; 2214 set = fdt->open_fds->fds_bits[j++];
2213 while (set) { 2215 while (set) {
2214 if (set & 1) { 2216 if (set & 1) {
2215 struct file *file = files->fd[i]; 2217 struct file *file = fdt->fd[i];
2216 if (file) 2218 if (file)
2217 __steal_locks(file, from); 2219 __steal_locks(file, from);
2218 } 2220 }
diff --git a/fs/open.c b/fs/open.c
index 4ee2dcc31c28..b6542516a0ca 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -842,14 +842,16 @@ int get_unused_fd(void)
842{ 842{
843 struct files_struct * files = current->files; 843 struct files_struct * files = current->files;
844 int fd, error; 844 int fd, error;
845 struct fdtable *fdt;
845 846
846 error = -EMFILE; 847 error = -EMFILE;
847 spin_lock(&files->file_lock); 848 spin_lock(&files->file_lock);
848 849
849repeat: 850repeat:
850 fd = find_next_zero_bit(files->open_fds->fds_bits, 851 fdt = files_fdtable(files);
851 files->max_fdset, 852 fd = find_next_zero_bit(fdt->open_fds->fds_bits,
852 files->next_fd); 853 fdt->max_fdset,
854 fdt->next_fd);
853 855
854 /* 856 /*
855 * N.B. For clone tasks sharing a files structure, this test 857 * N.B. For clone tasks sharing a files structure, this test
@@ -872,14 +874,14 @@ repeat:
872 goto repeat; 874 goto repeat;
873 } 875 }
874 876
875 FD_SET(fd, files->open_fds); 877 FD_SET(fd, fdt->open_fds);
876 FD_CLR(fd, files->close_on_exec); 878 FD_CLR(fd, fdt->close_on_exec);
877 files->next_fd = fd + 1; 879 fdt->next_fd = fd + 1;
878#if 1 880#if 1
879 /* Sanity check */ 881 /* Sanity check */
880 if (files->fd[fd] != NULL) { 882 if (fdt->fd[fd] != NULL) {
881 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); 883 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
882 files->fd[fd] = NULL; 884 fdt->fd[fd] = NULL;
883 } 885 }
884#endif 886#endif
885 error = fd; 887 error = fd;
@@ -893,9 +895,10 @@ EXPORT_SYMBOL(get_unused_fd);
893 895
894static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) 896static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
895{ 897{
896 __FD_CLR(fd, files->open_fds); 898 struct fdtable *fdt = files_fdtable(files);
897 if (fd < files->next_fd) 899 __FD_CLR(fd, fdt->open_fds);
898 files->next_fd = fd; 900 if (fd < fdt->next_fd)
901 fdt->next_fd = fd;
899} 902}
900 903
901void fastcall put_unused_fd(unsigned int fd) 904void fastcall put_unused_fd(unsigned int fd)
@@ -924,10 +927,12 @@ EXPORT_SYMBOL(put_unused_fd);
924void fastcall fd_install(unsigned int fd, struct file * file) 927void fastcall fd_install(unsigned int fd, struct file * file)
925{ 928{
926 struct files_struct *files = current->files; 929 struct files_struct *files = current->files;
930 struct fdtable *fdt;
927 spin_lock(&files->file_lock); 931 spin_lock(&files->file_lock);
928 if (unlikely(files->fd[fd] != NULL)) 932 fdt = files_fdtable(files);
933 if (unlikely(fdt->fd[fd] != NULL))
929 BUG(); 934 BUG();
930 files->fd[fd] = file; 935 fdt->fd[fd] = file;
931 spin_unlock(&files->file_lock); 936 spin_unlock(&files->file_lock);
932} 937}
933 938
@@ -1010,15 +1015,17 @@ asmlinkage long sys_close(unsigned int fd)
1010{ 1015{
1011 struct file * filp; 1016 struct file * filp;
1012 struct files_struct *files = current->files; 1017 struct files_struct *files = current->files;
1018 struct fdtable *fdt;
1013 1019
1014 spin_lock(&files->file_lock); 1020 spin_lock(&files->file_lock);
1015 if (fd >= files->max_fds) 1021 fdt = files_fdtable(files);
1022 if (fd >= fdt->max_fds)
1016 goto out_unlock; 1023 goto out_unlock;
1017 filp = files->fd[fd]; 1024 filp = fdt->fd[fd];
1018 if (!filp) 1025 if (!filp)
1019 goto out_unlock; 1026 goto out_unlock;
1020 files->fd[fd] = NULL; 1027 fdt->fd[fd] = NULL;
1021 FD_CLR(fd, files->close_on_exec); 1028 FD_CLR(fd, fdt->close_on_exec);
1022 __put_unused_fd(files, fd); 1029 __put_unused_fd(files, fd);
1023 spin_unlock(&files->file_lock); 1030 spin_unlock(&files->file_lock);
1024 return filp_close(filp, files); 1031 return filp_close(filp, files);
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 37668fe998ad..d88d518d30f6 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -159,6 +159,7 @@ static inline char * task_state(struct task_struct *p, char *buffer)
159{ 159{
160 struct group_info *group_info; 160 struct group_info *group_info;
161 int g; 161 int g;
162 struct fdtable *fdt = NULL;
162 163
163 read_lock(&tasklist_lock); 164 read_lock(&tasklist_lock);
164 buffer += sprintf(buffer, 165 buffer += sprintf(buffer,
@@ -179,10 +180,12 @@ static inline char * task_state(struct task_struct *p, char *buffer)
179 p->gid, p->egid, p->sgid, p->fsgid); 180 p->gid, p->egid, p->sgid, p->fsgid);
180 read_unlock(&tasklist_lock); 181 read_unlock(&tasklist_lock);
181 task_lock(p); 182 task_lock(p);
183 if (p->files)
184 fdt = files_fdtable(p->files);
182 buffer += sprintf(buffer, 185 buffer += sprintf(buffer,
183 "FDSize:\t%d\n" 186 "FDSize:\t%d\n"
184 "Groups:\t", 187 "Groups:\t",
185 p->files ? p->files->max_fds : 0); 188 fdt ? fdt->max_fds : 0);
186 189
187 group_info = p->group_info; 190 group_info = p->group_info;
188 get_group_info(group_info); 191 get_group_info(group_info);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 84751f3f52d5..d0087a0b024b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1039,6 +1039,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1039 int retval; 1039 int retval;
1040 char buf[NUMBUF]; 1040 char buf[NUMBUF];
1041 struct files_struct * files; 1041 struct files_struct * files;
1042 struct fdtable *fdt;
1042 1043
1043 retval = -ENOENT; 1044 retval = -ENOENT;
1044 if (!pid_alive(p)) 1045 if (!pid_alive(p))
@@ -1062,8 +1063,9 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1062 if (!files) 1063 if (!files)
1063 goto out; 1064 goto out;
1064 spin_lock(&files->file_lock); 1065 spin_lock(&files->file_lock);
1066 fdt = files_fdtable(files);
1065 for (fd = filp->f_pos-2; 1067 for (fd = filp->f_pos-2;
1066 fd < files->max_fds; 1068 fd < fdt->max_fds;
1067 fd++, filp->f_pos++) { 1069 fd++, filp->f_pos++) {
1068 unsigned int i,j; 1070 unsigned int i,j;
1069 1071
diff --git a/fs/select.c b/fs/select.c
index b80e7eb0ac0d..2e56325c73c4 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -132,11 +132,13 @@ static int max_select_fd(unsigned long n, fd_set_bits *fds)
132 unsigned long *open_fds; 132 unsigned long *open_fds;
133 unsigned long set; 133 unsigned long set;
134 int max; 134 int max;
135 struct fdtable *fdt;
135 136
136 /* handle last in-complete long-word first */ 137 /* handle last in-complete long-word first */
137 set = ~(~0UL << (n & (__NFDBITS-1))); 138 set = ~(~0UL << (n & (__NFDBITS-1)));
138 n /= __NFDBITS; 139 n /= __NFDBITS;
139 open_fds = current->files->open_fds->fds_bits+n; 140 fdt = files_fdtable(current->files);
141 open_fds = fdt->open_fds->fds_bits+n;
140 max = 0; 142 max = 0;
141 if (set) { 143 if (set) {
142 set &= BITS(fds, n); 144 set &= BITS(fds, n);
@@ -299,6 +301,7 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
299 char *bits; 301 char *bits;
300 long timeout; 302 long timeout;
301 int ret, size, max_fdset; 303 int ret, size, max_fdset;
304 struct fdtable *fdt;
302 305
303 timeout = MAX_SCHEDULE_TIMEOUT; 306 timeout = MAX_SCHEDULE_TIMEOUT;
304 if (tvp) { 307 if (tvp) {
@@ -326,7 +329,8 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
326 goto out_nofds; 329 goto out_nofds;
327 330
328 /* max_fdset can increase, so grab it once to avoid race */ 331 /* max_fdset can increase, so grab it once to avoid race */
329 max_fdset = current->files->max_fdset; 332 fdt = files_fdtable(current->files);
333 max_fdset = fdt->max_fdset;
330 if (n > max_fdset) 334 if (n > max_fdset)
331 n = max_fdset; 335 n = max_fdset;
332 336
@@ -464,9 +468,11 @@ asmlinkage long sys_poll(struct pollfd __user * ufds, unsigned int nfds, long ti
464 unsigned int i; 468 unsigned int i;
465 struct poll_list *head; 469 struct poll_list *head;
466 struct poll_list *walk; 470 struct poll_list *walk;
471 struct fdtable *fdt;
467 472
468 /* Do a sanity check on nfds ... */ 473 /* Do a sanity check on nfds ... */
469 if (nfds > current->files->max_fdset && nfds > OPEN_MAX) 474 fdt = files_fdtable(current->files);
475 if (nfds > fdt->max_fdset && nfds > OPEN_MAX)
470 return -EINVAL; 476 return -EINVAL;
471 477
472 if (timeout) { 478 if (timeout) {