diff options
| author | Vadim Lobanov <vlobanov@speakeasy.net> | 2006-09-29 05:01:43 -0400 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-29 12:18:25 -0400 | 
| commit | 74d392aaabfc890cc1f0e80fc5ff13e5d3bcf4c9 (patch) | |
| tree | e70c15452798ac7745d9f9f0f8bb732286d77784 | |
| parent | 3706baa8b1ba0d71d52fd0c656752a6495f6364a (diff) | |
[PATCH] Clean up expand_fdtable() and expand_files()
Perform a code cleanup against the expand_fdtable() and expand_files()
functions inside fs/file.c.  It aims to make the flow of code within these
functions simpler and easier to understand, via added comments and modest
refactoring.
Signed-off-by: Vadim Lobanov <vlobanov@speakeasy.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | fs/file.c | 76 | 
1 files changed, 35 insertions, 41 deletions
| @@ -288,71 +288,65 @@ out: | |||
| 288 | } | 288 | } | 
| 289 | 289 | ||
| 290 | /* | 290 | /* | 
| 291 | * Expands the file descriptor table - it will allocate a new fdtable and | 291 | * Expand the file descriptor table. | 
| 292 | * both fd array and fdset. It is expected to be called with the | 292 | * This function will allocate a new fdtable and both fd array and fdset, of | 
| 293 | * files_lock held. | 293 | * the given size. | 
| 294 | * Return <0 error code on error; 1 on successful completion. | ||
| 295 | * The files->file_lock should be held on entry, and will be held on exit. | ||
| 294 | */ | 296 | */ | 
| 295 | static int expand_fdtable(struct files_struct *files, int nr) | 297 | static int expand_fdtable(struct files_struct *files, int nr) | 
| 296 | __releases(files->file_lock) | 298 | __releases(files->file_lock) | 
| 297 | __acquires(files->file_lock) | 299 | __acquires(files->file_lock) | 
| 298 | { | 300 | { | 
| 299 | int error = 0; | 301 | struct fdtable *new_fdt, *cur_fdt; | 
| 300 | struct fdtable *fdt; | ||
| 301 | struct fdtable *nfdt = NULL; | ||
| 302 | 302 | ||
| 303 | spin_unlock(&files->file_lock); | 303 | spin_unlock(&files->file_lock); | 
| 304 | nfdt = alloc_fdtable(nr); | 304 | new_fdt = alloc_fdtable(nr); | 
| 305 | if (!nfdt) { | ||
| 306 | error = -ENOMEM; | ||
| 307 | spin_lock(&files->file_lock); | ||
| 308 | goto out; | ||
| 309 | } | ||
| 310 | |||
| 311 | spin_lock(&files->file_lock); | 305 | spin_lock(&files->file_lock); | 
| 312 | fdt = files_fdtable(files); | 306 | if (!new_fdt) | 
| 307 | return -ENOMEM; | ||
| 313 | /* | 308 | /* | 
| 314 | * Check again since another task may have expanded the | 309 | * Check again since another task may have expanded the fd table while | 
| 315 | * fd table while we dropped the lock | 310 | * we dropped the lock | 
| 316 | */ | 311 | */ | 
| 317 | if (nr >= fdt->max_fds || nr >= fdt->max_fdset) { | 312 | cur_fdt = files_fdtable(files); | 
| 318 | copy_fdtable(nfdt, fdt); | 313 | if (nr >= cur_fdt->max_fds || nr >= cur_fdt->max_fdset) { | 
| 314 | /* Continue as planned */ | ||
| 315 | copy_fdtable(new_fdt, cur_fdt); | ||
| 316 | rcu_assign_pointer(files->fdt, new_fdt); | ||
| 317 | free_fdtable(cur_fdt); | ||
| 319 | } else { | 318 | } else { | 
| 320 | /* Somebody expanded while we dropped file_lock */ | 319 | /* Somebody else expanded, so undo our attempt */ | 
| 321 | spin_unlock(&files->file_lock); | 320 | spin_unlock(&files->file_lock); | 
| 322 | __free_fdtable(nfdt); | 321 | __free_fdtable(new_fdt); | 
| 323 | spin_lock(&files->file_lock); | 322 | spin_lock(&files->file_lock); | 
| 324 | goto out; | ||
| 325 | } | 323 | } | 
| 326 | rcu_assign_pointer(files->fdt, nfdt); | 324 | return 1; | 
| 327 | free_fdtable(fdt); | ||
| 328 | out: | ||
| 329 | return error; | ||
| 330 | } | 325 | } | 
| 331 | 326 | ||
| 332 | /* | 327 | /* | 
| 333 | * Expand files. | 328 | * Expand files. | 
| 334 | * Return <0 on error; 0 nothing done; 1 files expanded, we may have blocked. | 329 | * This function will expand the file structures, if the requested size exceeds | 
| 335 | * Should be called with the files->file_lock spinlock held for write. | 330 | * the current capacity and there is room for expansion. | 
| 331 | * Return <0 error code on error; 0 when nothing done; 1 when files were | ||
| 332 | * expanded and execution may have blocked. | ||
| 333 | * The files->file_lock should be held on entry, and will be held on exit. | ||
| 336 | */ | 334 | */ | 
| 337 | int expand_files(struct files_struct *files, int nr) | 335 | int expand_files(struct files_struct *files, int nr) | 
| 338 | { | 336 | { | 
| 339 | int err, expand = 0; | ||
| 340 | struct fdtable *fdt; | 337 | struct fdtable *fdt; | 
| 341 | 338 | ||
| 342 | fdt = files_fdtable(files); | 339 | fdt = files_fdtable(files); | 
| 343 | if (nr >= fdt->max_fdset || nr >= fdt->max_fds) { | 340 | /* Do we need to expand? */ | 
| 344 | if (fdt->max_fdset >= NR_OPEN || | 341 | if (nr < fdt->max_fdset && nr < fdt->max_fds) | 
| 345 | fdt->max_fds >= NR_OPEN || nr >= NR_OPEN) { | 342 | return 0; | 
| 346 | err = -EMFILE; | 343 | /* Can we expand? */ | 
| 347 | goto out; | 344 | if (fdt->max_fdset >= NR_OPEN || fdt->max_fds >= NR_OPEN || | 
| 348 | } | 345 | nr >= NR_OPEN) | 
| 349 | expand = 1; | 346 | return -EMFILE; | 
| 350 | if ((err = expand_fdtable(files, nr))) | 347 | |
| 351 | goto out; | 348 | /* All good, so we try */ | 
| 352 | } | 349 | return expand_fdtable(files, nr); | 
| 353 | err = expand; | ||
| 354 | out: | ||
| 355 | return err; | ||
| 356 | } | 350 | } | 
| 357 | 351 | ||
| 358 | static void __devinit fdtable_defer_list_init(int cpu) | 352 | static void __devinit fdtable_defer_list_init(int cpu) | 
