aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorDipankar Sarma <dipankar@in.ibm.com>2005-09-09 16:04:14 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:55 -0400
commitb835996f628eadb55c5fb222ba46fe9395bf73c7 (patch)
treed63d80585d197e1ffc299af4a0034049790fb197 /fs/proc
parentab2af1f5005069321c5d130f09cce577b03f43ef (diff)
[PATCH] files: lock-free fd look-up
With the use of RCU in files structure, the look-up of files using fds can now be lock-free. The lookup is protected by rcu_read_lock()/rcu_read_unlock(). This patch changes the readers to use lock-free lookup. Signed-off-by: Maneesh Soni <maneesh@in.ibm.com> Signed-off-by: Ravikiran Thirumalai <kiran_th@gmail.com> Signed-off-by: Dipankar Sarma <dipankar@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/base.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index d0087a0b024b..23db452ab428 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -62,6 +62,7 @@
62#include <linux/namespace.h> 62#include <linux/namespace.h>
63#include <linux/mm.h> 63#include <linux/mm.h>
64#include <linux/smp_lock.h> 64#include <linux/smp_lock.h>
65#include <linux/rcupdate.h>
65#include <linux/kallsyms.h> 66#include <linux/kallsyms.h>
66#include <linux/mount.h> 67#include <linux/mount.h>
67#include <linux/security.h> 68#include <linux/security.h>
@@ -283,16 +284,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
283 284
284 files = get_files_struct(task); 285 files = get_files_struct(task);
285 if (files) { 286 if (files) {
286 spin_lock(&files->file_lock); 287 rcu_read_lock();
287 file = fcheck_files(files, fd); 288 file = fcheck_files(files, fd);
288 if (file) { 289 if (file) {
289 *mnt = mntget(file->f_vfsmnt); 290 *mnt = mntget(file->f_vfsmnt);
290 *dentry = dget(file->f_dentry); 291 *dentry = dget(file->f_dentry);
291 spin_unlock(&files->file_lock); 292 rcu_read_unlock();
292 put_files_struct(files); 293 put_files_struct(files);
293 return 0; 294 return 0;
294 } 295 }
295 spin_unlock(&files->file_lock); 296 rcu_read_unlock();
296 put_files_struct(files); 297 put_files_struct(files);
297 } 298 }
298 return -ENOENT; 299 return -ENOENT;
@@ -1062,7 +1063,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1062 files = get_files_struct(p); 1063 files = get_files_struct(p);
1063 if (!files) 1064 if (!files)
1064 goto out; 1065 goto out;
1065 spin_lock(&files->file_lock); 1066 rcu_read_lock();
1066 fdt = files_fdtable(files); 1067 fdt = files_fdtable(files);
1067 for (fd = filp->f_pos-2; 1068 for (fd = filp->f_pos-2;
1068 fd < fdt->max_fds; 1069 fd < fdt->max_fds;
@@ -1071,7 +1072,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1071 1072
1072 if (!fcheck_files(files, fd)) 1073 if (!fcheck_files(files, fd))
1073 continue; 1074 continue;
1074 spin_unlock(&files->file_lock); 1075 rcu_read_unlock();
1075 1076
1076 j = NUMBUF; 1077 j = NUMBUF;
1077 i = fd; 1078 i = fd;
@@ -1083,12 +1084,12 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1083 1084
1084 ino = fake_ino(tid, PROC_TID_FD_DIR + fd); 1085 ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
1085 if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) { 1086 if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
1086 spin_lock(&files->file_lock); 1087 rcu_read_lock();
1087 break; 1088 break;
1088 } 1089 }
1089 spin_lock(&files->file_lock); 1090 rcu_read_lock();
1090 } 1091 }
1091 spin_unlock(&files->file_lock); 1092 rcu_read_unlock();
1092 put_files_struct(files); 1093 put_files_struct(files);
1093 } 1094 }
1094out: 1095out:
@@ -1263,9 +1264,9 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1263 1264
1264 files = get_files_struct(task); 1265 files = get_files_struct(task);
1265 if (files) { 1266 if (files) {
1266 spin_lock(&files->file_lock); 1267 rcu_read_lock();
1267 if (fcheck_files(files, fd)) { 1268 if (fcheck_files(files, fd)) {
1268 spin_unlock(&files->file_lock); 1269 rcu_read_unlock();
1269 put_files_struct(files); 1270 put_files_struct(files);
1270 if (task_dumpable(task)) { 1271 if (task_dumpable(task)) {
1271 inode->i_uid = task->euid; 1272 inode->i_uid = task->euid;
@@ -1277,7 +1278,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1277 security_task_to_inode(task, inode); 1278 security_task_to_inode(task, inode);
1278 return 1; 1279 return 1;
1279 } 1280 }
1280 spin_unlock(&files->file_lock); 1281 rcu_read_unlock();
1281 put_files_struct(files); 1282 put_files_struct(files);
1282 } 1283 }
1283 d_drop(dentry); 1284 d_drop(dentry);
@@ -1369,7 +1370,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1369 if (!files) 1370 if (!files)
1370 goto out_unlock; 1371 goto out_unlock;
1371 inode->i_mode = S_IFLNK; 1372 inode->i_mode = S_IFLNK;
1372 spin_lock(&files->file_lock); 1373 rcu_read_lock();
1373 file = fcheck_files(files, fd); 1374 file = fcheck_files(files, fd);
1374 if (!file) 1375 if (!file)
1375 goto out_unlock2; 1376 goto out_unlock2;
@@ -1377,7 +1378,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1377 inode->i_mode |= S_IRUSR | S_IXUSR; 1378 inode->i_mode |= S_IRUSR | S_IXUSR;
1378 if (file->f_mode & 2) 1379 if (file->f_mode & 2)
1379 inode->i_mode |= S_IWUSR | S_IXUSR; 1380 inode->i_mode |= S_IWUSR | S_IXUSR;
1380 spin_unlock(&files->file_lock); 1381 rcu_read_unlock();
1381 put_files_struct(files); 1382 put_files_struct(files);
1382 inode->i_op = &proc_pid_link_inode_operations; 1383 inode->i_op = &proc_pid_link_inode_operations;
1383 inode->i_size = 64; 1384 inode->i_size = 64;
@@ -1387,7 +1388,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1387 return NULL; 1388 return NULL;
1388 1389
1389out_unlock2: 1390out_unlock2:
1390 spin_unlock(&files->file_lock); 1391 rcu_read_unlock();
1391 put_files_struct(files); 1392 put_files_struct(files);
1392out_unlock: 1393out_unlock:
1393 iput(inode); 1394 iput(inode);