[PATCH] files: lock-free fd look-up
[linux-2.6.git] / fs / proc / base.c
index d0087a0b024be49d86a1ec0ee47df2259d711c7c..23db452ab428c9896a96aad29217100e67aeb78a 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/namespace.h>
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
+#include <linux/rcupdate.h>
 #include <linux/kallsyms.h>
 #include <linux/mount.h>
 #include <linux/security.h>
@@ -283,16 +284,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
 
        files = get_files_struct(task);
        if (files) {
-               spin_lock(&files->file_lock);
+               rcu_read_lock();
                file = fcheck_files(files, fd);
                if (file) {
                        *mnt = mntget(file->f_vfsmnt);
                        *dentry = dget(file->f_dentry);
-                       spin_unlock(&files->file_lock);
+                       rcu_read_unlock();
                        put_files_struct(files);
                        return 0;
                }
-               spin_unlock(&files->file_lock);
+               rcu_read_unlock();
                put_files_struct(files);
        }
        return -ENOENT;
@@ -1062,7 +1063,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
                        files = get_files_struct(p);
                        if (!files)
                                goto out;
-                       spin_lock(&files->file_lock);
+                       rcu_read_lock();
                        fdt = files_fdtable(files);
                        for (fd = filp->f_pos-2;
                             fd < fdt->max_fds;
@@ -1071,7 +1072,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
 
                                if (!fcheck_files(files, fd))
                                        continue;
-                               spin_unlock(&files->file_lock);
+                               rcu_read_unlock();
 
                                j = NUMBUF;
                                i = fd;
@@ -1083,12 +1084,12 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
 
                                ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
                                if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
-                                       spin_lock(&files->file_lock);
+                                       rcu_read_lock();
                                        break;
                                }
-                               spin_lock(&files->file_lock);
+                               rcu_read_lock();
                        }
-                       spin_unlock(&files->file_lock);
+                       rcu_read_unlock();
                        put_files_struct(files);
        }
 out:
@@ -1263,9 +1264,9 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
 
        files = get_files_struct(task);
        if (files) {
-               spin_lock(&files->file_lock);
+               rcu_read_lock();
                if (fcheck_files(files, fd)) {
-                       spin_unlock(&files->file_lock);
+                       rcu_read_unlock();
                        put_files_struct(files);
                        if (task_dumpable(task)) {
                                inode->i_uid = task->euid;
@@ -1277,7 +1278,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
                        security_task_to_inode(task, inode);
                        return 1;
                }
-               spin_unlock(&files->file_lock);
+               rcu_read_unlock();
                put_files_struct(files);
        }
        d_drop(dentry);
@@ -1369,7 +1370,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
        if (!files)
                goto out_unlock;
        inode->i_mode = S_IFLNK;
-       spin_lock(&files->file_lock);
+       rcu_read_lock();
        file = fcheck_files(files, fd);
        if (!file)
                goto out_unlock2;
@@ -1377,7 +1378,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
                inode->i_mode |= S_IRUSR | S_IXUSR;
        if (file->f_mode & 2)
                inode->i_mode |= S_IWUSR | S_IXUSR;
-       spin_unlock(&files->file_lock);
+       rcu_read_unlock();
        put_files_struct(files);
        inode->i_op = &proc_pid_link_inode_operations;
        inode->i_size = 64;
@@ -1387,7 +1388,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
        return NULL;
 
 out_unlock2:
-       spin_unlock(&files->file_lock);
+       rcu_read_unlock();
        put_files_struct(files);
 out_unlock:
        iput(inode);