X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Ffcntl.c;h=e4f26165f12a22567526a74d2f463aa6d6798547;hb=7ff1d74f5670329ac4b5959a675f8698ba95be20;hp=dc4a7007f4e742c4e30563db78b34bd21d39ab58;hpb=6a8a8e14bed179f2d415c7f4fee51233c35c10c3;p=linux-2.6-omap-h63xx.git diff --git a/fs/fcntl.c b/fs/fcntl.c index dc4a7007f4e..e4f26165f12 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -73,8 +73,8 @@ repeat: * orig_start..fdt->next_fd */ start = orig_start; - if (start < fdt->next_fd) - start = fdt->next_fd; + if (start < files->next_fd) + start = files->next_fd; newfd = start; if (start < fdt->max_fdset) { @@ -102,9 +102,8 @@ repeat: * we reacquire the fdtable pointer and use it while holding * the lock, no one can free it during that time. */ - fdt = files_fdtable(files); - if (start <= fdt->next_fd) - fdt->next_fd = newfd + 1; + if (start <= files->next_fd) + files->next_fd = newfd + 1; error = newfd; @@ -251,19 +250,22 @@ static int setfl(int fd, struct file * filp, unsigned long arg) return error; } -static void f_modown(struct file *filp, unsigned long pid, +static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, uid_t uid, uid_t euid, int force) { write_lock_irq(&filp->f_owner.lock); if (force || !filp->f_owner.pid) { - filp->f_owner.pid = pid; + put_pid(filp->f_owner.pid); + filp->f_owner.pid = get_pid(pid); + filp->f_owner.pid_type = type; filp->f_owner.uid = uid; filp->f_owner.euid = euid; } write_unlock_irq(&filp->f_owner.lock); } -int f_setown(struct file *filp, unsigned long arg, int force) +int __f_setown(struct file *filp, struct pid *pid, enum pid_type type, + int force) { int err; @@ -271,15 +273,44 @@ int f_setown(struct file *filp, unsigned long arg, int force) if (err) return err; - f_modown(filp, arg, current->uid, current->euid, force); + f_modown(filp, pid, type, current->uid, current->euid, force); return 0; } +EXPORT_SYMBOL(__f_setown); +int f_setown(struct file *filp, unsigned long arg, int force) +{ + enum pid_type type; + struct pid *pid; + int who = arg; + int result; + type = PIDTYPE_PID; + if (who < 0) { + type = PIDTYPE_PGID; + who = -who; + } + rcu_read_lock(); + pid = find_pid(who); + result = __f_setown(filp, pid, type, force); + rcu_read_unlock(); + return result; +} EXPORT_SYMBOL(f_setown); void f_delown(struct file *filp) { - f_modown(filp, 0, 0, 0, 1); + f_modown(filp, NULL, PIDTYPE_PID, 0, 0, 1); +} + +pid_t f_getown(struct file *filp) +{ + pid_t pid; + read_lock(&filp->f_owner.lock); + pid = pid_nr(filp->f_owner.pid); + if (filp->f_owner.pid_type == PIDTYPE_PGID) + pid = -pid; + read_unlock(&filp->f_owner.lock); + return pid; } static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, @@ -320,7 +351,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, * current syscall conventions, the only way * to fix this will be in libc. */ - err = filp->f_owner.pid; + err = f_getown(filp); force_successful_syscall_return(); break; case F_SETOWN: @@ -413,7 +444,7 @@ out: /* Table to convert sigio signal codes into poll band bitmaps */ -static long band_table[NSIGPOLL] = { +static const long band_table[NSIGPOLL] = { POLLIN | POLLRDNORM, /* POLL_IN */ POLLOUT | POLLWRNORM | POLLWRBAND, /* POLL_OUT */ POLLIN | POLLRDNORM | POLLMSG, /* POLL_MSG */ @@ -454,8 +485,7 @@ static void send_sigio_to_task(struct task_struct *p, /* Make sure we are called with one of the POLL_* reasons, otherwise we could leak kernel stack into userspace. */ - if ((reason & __SI_MASK) != __SI_POLL) - BUG(); + BUG_ON((reason & __SI_MASK) != __SI_POLL); if (reason - POLL_IN >= NSIGPOLL) si.si_band = ~0L; else @@ -472,24 +502,19 @@ static void send_sigio_to_task(struct task_struct *p, void send_sigio(struct fown_struct *fown, int fd, int band) { struct task_struct *p; - int pid; + enum pid_type type; + struct pid *pid; read_lock(&fown->lock); + type = fown->pid_type; pid = fown->pid; if (!pid) goto out_unlock_fown; read_lock(&tasklist_lock); - if (pid > 0) { - p = find_task_by_pid(pid); - if (p) { - send_sigio_to_task(p, fown, fd, band); - } - } else { - do_each_task_pid(-pid, PIDTYPE_PGID, p) { - send_sigio_to_task(p, fown, fd, band); - } while_each_task_pid(-pid, PIDTYPE_PGID, p); - } + do_each_pid_task(pid, type, p) { + send_sigio_to_task(p, fown, fd, band); + } while_each_pid_task(pid, type, p); read_unlock(&tasklist_lock); out_unlock_fown: read_unlock(&fown->lock); @@ -505,9 +530,12 @@ static void send_sigurg_to_task(struct task_struct *p, int send_sigurg(struct fown_struct *fown) { struct task_struct *p; - int pid, ret = 0; + enum pid_type type; + struct pid *pid; + int ret = 0; read_lock(&fown->lock); + type = fown->pid_type; pid = fown->pid; if (!pid) goto out_unlock_fown; @@ -515,16 +543,9 @@ int send_sigurg(struct fown_struct *fown) ret = 1; read_lock(&tasklist_lock); - if (pid > 0) { - p = find_task_by_pid(pid); - if (p) { - send_sigurg_to_task(p, fown); - } - } else { - do_each_task_pid(-pid, PIDTYPE_PGID, p) { - send_sigurg_to_task(p, fown); - } while_each_task_pid(-pid, PIDTYPE_PGID, p); - } + do_each_pid_task(pid, type, p) { + send_sigurg_to_task(p, fown); + } while_each_pid_task(pid, type, p); read_unlock(&tasklist_lock); out_unlock_fown: read_unlock(&fown->lock); @@ -532,7 +553,7 @@ int send_sigurg(struct fown_struct *fown) } static DEFINE_RWLOCK(fasync_lock); -static kmem_cache_t *fasync_cache; +static kmem_cache_t *fasync_cache __read_mostly; /* * fasync_helper() is used by some character device drivers (mainly mice)