diff options
Diffstat (limited to 'fs/file.c')
-rw-r--r-- | fs/file.c | 42 |
1 files changed, 25 insertions, 17 deletions
@@ -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: | |||
237 | int expand_files(struct files_struct *files, int nr) | 243 | int 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; |