X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Ffcntl.c;h=330a7d7825915f591fa89ca74d8e63fa4efe07f4;hb=82638844d9a8581bbf33201cc209a14876eca167;hp=8685263ccc4a7aa51d6666136c285687393bfabb;hpb=4c5cdb1e1f2a502069f57a60b5c6b97b8106c73c;p=pandora-kernel.git diff --git a/fs/fcntl.c b/fs/fcntl.c index 8685263ccc4a..330a7d782591 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -9,9 +9,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -24,7 +24,7 @@ #include #include -void fastcall set_close_on_exec(unsigned int fd, int flag) +void set_close_on_exec(unsigned int fd, int flag) { struct files_struct *files = current->files; struct fdtable *fdt; @@ -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 @@ repeat: 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; } @@ -238,7 +226,6 @@ static int setfl(int fd, struct file * filp, unsigned long arg) if (error) return error; - lock_kernel(); if ((arg ^ filp->f_flags) & FASYNC) { if (filp->f_op && filp->f_op->fasync) { error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0); @@ -249,7 +236,6 @@ static int setfl(int fd, struct file * filp, unsigned long arg) filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); out: - unlock_kernel(); return error; } @@ -309,7 +295,7 @@ pid_t f_getown(struct file *filp) { pid_t pid; read_lock(&filp->f_owner.lock); - pid = pid_nr_ns(filp->f_owner.pid, current->nsproxy->pid_ns); + pid = pid_vnr(filp->f_owner.pid); if (filp->f_owner.pid_type == PIDTYPE_PGID) pid = -pid; read_unlock(&filp->f_owner.lock);