From 6222452a6a0eb51c9f3c1b4f6cd4c618fe4a65a2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 23 Apr 2008 20:38:10 -0400 Subject: [PATCH] --- yaml --- r: 93487 b: refs/heads/master c: f8f95702f0c4529b0f59488f4509608f0c160e77 h: refs/heads/master i: 93485: 09c02a9110e764c5b5c179e6873564562db1ef4a 93483: 8a916c67d22e092bfcd1311c938a035bc3c1df13 93479: 957fb0f66680133ed15c8acbcedf1419b209bd66 93471: 1e87f011f2d0f63bb2be9b0a221d3ed43f39a425 v: v3 --- [refs] | 2 +- trunk/fs/fcntl.c | 40 ++++++++++++++-------------------------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/[refs] b/[refs] index c76df76583b8..60d22d9d2c0a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3b1253880b7a9e6db54b943b2d40bcf2202f58ab +refs/heads/master: f8f95702f0c4529b0f59488f4509608f0c160e77 diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index e632da761fc1..3f3ac630ccde 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -55,14 +55,16 @@ static int get_close_on_exec(unsigned int fd) * file_lock held for write. */ -static int locate_fd(struct files_struct *files, - struct file *file, unsigned int orig_start) +static int locate_fd(unsigned int orig_start, int cloexec) { + struct files_struct *files = current->files; unsigned int newfd; unsigned int start; int error; struct fdtable *fdt; + spin_lock(&files->file_lock); + error = -EINVAL; if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) goto out; @@ -97,42 +99,28 @@ static int locate_fd(struct files_struct *files, if (error) goto repeat; - /* - * We reacquired files_lock, so we are safe as long as - * we reacquire the fdtable pointer and use it while holding - * the lock, no one can free it during that time. - */ if (start <= files->next_fd) files->next_fd = newfd + 1; + FD_SET(newfd, fdt->open_fds); + if (cloexec) + FD_SET(newfd, fdt->close_on_exec); + else + FD_CLR(newfd, fdt->close_on_exec); error = newfd; - + out: + spin_unlock(&files->file_lock); return error; } static int dupfd(struct file *file, unsigned int start, int cloexec) { - struct files_struct * files = current->files; - struct fdtable *fdt; - int fd; - - spin_lock(&files->file_lock); - fd = locate_fd(files, file, start); - if (fd >= 0) { - /* locate_fd() may have expanded fdtable, load the ptr */ - fdt = files_fdtable(files); - FD_SET(fd, fdt->open_fds); - if (cloexec) - FD_SET(fd, fdt->close_on_exec); - else - FD_CLR(fd, fdt->close_on_exec); - spin_unlock(&files->file_lock); + int fd = locate_fd(start, cloexec); + if (fd >= 0) fd_install(fd, file); - } else { - spin_unlock(&files->file_lock); + else fput(file); - } return fd; }