Tidy up dupfd() a little
Subsystems (2)
PATCH 1/1 Tidy up dupfd() a little
Walter Harms pointed out the locking was rather obtuse in dupfd. This patch makes it much clearer.
fs/fcntl.c +15 -23
@@ -75,8 +75,8 @@ static int expand_files(struct files_str/* * locate_fd finds a free file descriptor in the open_fds fdset, -* expanding the fd arrays if necessary. The files write lock will be -* held on exit to ensure that the fd can be entered atomically. +* expanding the fd arrays if necessary. Must be called with the +* file_lock held for write. */ static int locate_fd(struct files_struct *files,
@@ -86,8 +86,6 @@ static int locate_fd(struct files_structint error;int start; -write_lock (&files->file_lock); - error = -EINVAL ;if (orig_start >= current->rlim[RLIMIT_NOFILE ].rlim_cur) goto out;
@@ -131,30 +129,24 @@ out:return error; } -static inline void allocate_fd (struct files_struct *files, -struct file *file,int fd) -{ -FD_SET (fd, files->open_fds); -FD_CLR (fd, files->close_on_exec); -write_unlock (&files->file_lock); -fd_install (fd, file); -} -static int dupfd (struct file *file,int start) {struct files_struct * files = current->files; -int ret; +int fd; - ret =locate_fd (files, file, start); -if (ret <0 ) - goto out_putf; -allocate_fd (files, file, ret); -return ret; +write_lock (&files->file_lock); + fd =locate_fd (files, file, start); +if (fd >=0 ) { +FD_SET (fd, files->open_fds); +FD_CLR (fd, files->close_on_exec); +write_unlock (&files->file_lock); +fd_install (fd, file); + }else { +write_unlock (&files->file_lock); +fput (file); + } -out_putf: -write_unlock (&files->file_lock); -fput (file); -return ret; +return fd; }asmlinkage long sys_dup2 (unsigned int oldfd,unsigned int newfd)
Signature · 3 lines
"It's not Hollywood. War is real, war is primarily not about defeat or victory, it is about death. I've seen thousands and thousands of dead bodies. Do you think I want to have an academic debate on this subject?" -- Robert Fisk