diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/base.c | 29 |
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 | } |
1094 | out: | 1095 | out: |
@@ -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 | ||
1389 | out_unlock2: | 1390 | out_unlock2: |
1390 | spin_unlock(&files->file_lock); | 1391 | rcu_read_unlock(); |
1391 | put_files_struct(files); | 1392 | put_files_struct(files); |
1392 | out_unlock: | 1393 | out_unlock: |
1393 | iput(inode); | 1394 | iput(inode); |