[PATCH] files: lock-free fd look-up
[linux-2.6.git] / fs / select.c
index 2e56325c73c47933e10be4d695831639c84744a1..f10a10317d5494e0eb4995d9c016113a093f34ee 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
 #include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/rcupdate.h>
 
 #include <asm/uaccess.h>
 
@@ -185,9 +186,9 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
        int retval, i;
        long __timeout = *timeout;
 
-       spin_lock(&current->files->file_lock);
+       rcu_read_lock();
        retval = max_select_fd(n, fds);
-       spin_unlock(&current->files->file_lock);
+       rcu_read_unlock();
 
        if (retval < 0)
                return retval;
@@ -329,8 +330,10 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
                goto out_nofds;
 
        /* max_fdset can increase, so grab it once to avoid race */
+       rcu_read_lock();
        fdt = files_fdtable(current->files);
        max_fdset = fdt->max_fdset;
+       rcu_read_unlock();
        if (n > max_fdset)
                n = max_fdset;
 
@@ -469,10 +472,14 @@ asmlinkage long sys_poll(struct pollfd __user * ufds, unsigned int nfds, long ti
        struct poll_list *head;
        struct poll_list *walk;
        struct fdtable *fdt;
+       int max_fdset;
 
        /* Do a sanity check on nfds ... */
+       rcu_read_lock();
        fdt = files_fdtable(current->files);
-       if (nfds > fdt->max_fdset && nfds > OPEN_MAX)
+       max_fdset = fdt->max_fdset;
+       rcu_read_unlock();
+       if (nfds > max_fdset && nfds > OPEN_MAX)
                return -EINVAL;
 
        if (timeout) {