aboutsummaryrefslogtreecommitdiffstats
path: root/fs/file.c
diff options
context:
space:
mode:
authorDipankar Sarma <dipankar@in.ibm.com>2005-09-09 16:04:10 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:55 -0400
commitbadf16621c1f9d1ac753be056fce11b43d6e0be5 (patch)
tree3fdf833fdf2e3d3a439090743539680449ec3428 /fs/file.c
parentc0dfb2905126e9e94edebbce8d3e05001301f52d (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.c42
1 files changed, 25 insertions, 17 deletions
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;