diff options
author | Dipankar Sarma <dipankar@in.ibm.com> | 2005-09-09 16:04:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 16:57:55 -0400 |
commit | badf16621c1f9d1ac753be056fce11b43d6e0be5 (patch) | |
tree | 3fdf833fdf2e3d3a439090743539680449ec3428 /fs/file.c | |
parent | c0dfb2905126e9e94edebbce8d3e05001301f52d (diff) |
[PATCH] files: break up files struct
In order for the RCU to work, the file table array, sets and their sizes must
be updated atomically. Instead of ensuring this through too many memory
barriers, we put the arrays and their sizes in a separate structure. This
patch takes the first step of putting the file table elements in a separate
structure fdtable that is embedded withing files_struct. It also changes all
the users to refer to the file table using files_fdtable() macro. Subsequent
applciation of RCU becomes easier after this.
Signed-off-by: Dipankar Sarma <dipankar@in.ibm.com>
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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; |