Messages in this thread Patch in this message | | | Date | Sat, 30 Oct 1999 19:21:12 +0400 | From | Savochkin Andrey Vladimirovich <> | Subject | [PATCH] FD array expansion problem |
| |
Hi,
I've spotted a bug in the dynamic fd array expansion code. Here is the patch which - fixes wrong parameters of expand_fdset() and expand_fd_array() calls in expand_files() and get_unused_fd(); and - moves expand_files() function from sched.h to fs/fcntl.c.
Best wishes Andrey V. Savochkin
--- ./fs/fcntl.c.expandfd Sat Oct 30 18:48:27 1999 +++ ./fs/fcntl.c Sat Oct 30 18:48:27 1999 @@ -12,6 +12,39 @@ extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg); +/* Expand files. + * `nr' is the number of the last fd. + * Return <0 on error; 0 nothing done; 1 files expanded, + * we may have blocked. + * + * Should be called with the files->file_lock spinlock held for write. + */ +static inline int expand_files(struct files_struct *files, int nr) +{ + int err, expand = 0; +#ifdef FDSET_DEBUG + printk (KERN_ERR __FUNCTION__ " %d: nr = %d\n", current->pid, nr); +#endif + + if (nr >= files->max_fdset) { + expand = 1; + if ((err = expand_fdset(files, nr + 1))) + goto out; + } + if (nr >= files->max_fds) { + expand = 1; + if ((err = expand_fd_array(files, nr + 1))) + goto out; + } + err = expand; + out: +#ifdef FDSET_DEBUG + if (err) + printk (KERN_ERR __FUNCTION__ " %d: return %d\n", current->pid, err); +#endif + return err; +} + /* * locate_fd finds a free file descriptor in the open_fds fdset, * expanding the fd arrays if necessary. The files write lock will be --- ./fs/file.c.expandfd Sat Oct 30 18:48:27 1999 +++ ./fs/file.c Sat Oct 30 18:48:27 1999 @@ -53,8 +53,9 @@ } /* - * Expand the fd array in the files_struct. Called with the files - * spinlock held for write. + * Expand the fd array in the files_struct. + * `nr' is the desired array size. + * Called with the files spinlock held for write. */ int expand_fd_array(struct files_struct *files, int nr) --- ./fs/open.c.expandfd Sat Oct 30 18:48:27 1999 +++ ./fs/open.c Sat Oct 30 18:48:27 1999 @@ -702,7 +702,7 @@ /* Do we need to expand the fdset array? */ if (fd >= current->files->max_fdset) { - error = expand_fdset(files, 0); + error = expand_fdset(files, fd + 1); if (!error) { error = -EMFILE; goto repeat; @@ -714,7 +714,7 @@ * Check whether we need to expand the fd array. */ if (fd >= files->max_fds) { - error = expand_fd_array(files, 0); + error = expand_fd_array(files, fd + 1); if (!error) { error = -EMFILE; goto repeat; --- ./include/linux/sched.h.expandfd Sat Oct 30 18:48:27 1999 +++ ./include/linux/sched.h Sat Oct 30 18:48:27 1999 @@ -657,37 +657,6 @@ extern int expand_fdset(struct files_struct *, int nr); extern void free_fdset(fd_set *, int); -/* Expand files. Return <0 on error; 0 nothing done; 1 files expanded, - * we may have blocked. - * - * Should be called with the files->file_lock spinlock held for write. - */ -static inline int expand_files(struct files_struct *files, int nr) -{ - int err, expand = 0; -#ifdef FDSET_DEBUG - printk (KERN_ERR __FUNCTION__ " %d: nr = %d\n", current->pid, nr); -#endif - - if (nr >= files->max_fdset) { - expand = 1; - if ((err = expand_fdset(files, nr))) - goto out; - } - if (nr >= files->max_fds) { - expand = 1; - if ((err = expand_fd_array(files, nr))) - goto out; - } - err = expand; - out: -#ifdef FDSET_DEBUG - if (err) - printk (KERN_ERR __FUNCTION__ " %d: return %d\n", current->pid, err); -#endif - return err; -} - extern int copy_thread(int, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); extern void flush_thread(void); extern void exit_thread(void); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |