|
@@ -62,6 +62,7 @@
|
|
#include <linux/namespace.h>
|
|
#include <linux/namespace.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/smp_lock.h>
|
|
#include <linux/smp_lock.h>
|
|
|
|
+#include <linux/rcupdate.h>
|
|
#include <linux/kallsyms.h>
|
|
#include <linux/kallsyms.h>
|
|
#include <linux/mount.h>
|
|
#include <linux/mount.h>
|
|
#include <linux/security.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);
|
|
files = get_files_struct(task);
|
|
if (files) {
|
|
if (files) {
|
|
- spin_lock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_lock();
|
|
file = fcheck_files(files, fd);
|
|
file = fcheck_files(files, fd);
|
|
if (file) {
|
|
if (file) {
|
|
*mnt = mntget(file->f_vfsmnt);
|
|
*mnt = mntget(file->f_vfsmnt);
|
|
*dentry = dget(file->f_dentry);
|
|
*dentry = dget(file->f_dentry);
|
|
- spin_unlock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
put_files_struct(files);
|
|
put_files_struct(files);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
- spin_unlock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
put_files_struct(files);
|
|
put_files_struct(files);
|
|
}
|
|
}
|
|
return -ENOENT;
|
|
return -ENOENT;
|
|
@@ -1062,7 +1063,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
|
|
files = get_files_struct(p);
|
|
files = get_files_struct(p);
|
|
if (!files)
|
|
if (!files)
|
|
goto out;
|
|
goto out;
|
|
- spin_lock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_lock();
|
|
fdt = files_fdtable(files);
|
|
fdt = files_fdtable(files);
|
|
for (fd = filp->f_pos-2;
|
|
for (fd = filp->f_pos-2;
|
|
fd < fdt->max_fds;
|
|
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))
|
|
if (!fcheck_files(files, fd))
|
|
continue;
|
|
continue;
|
|
- spin_unlock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
|
|
|
|
j = NUMBUF;
|
|
j = NUMBUF;
|
|
i = fd;
|
|
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);
|
|
ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
|
|
if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
|
|
if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
|
|
- spin_lock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_lock();
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- spin_lock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_lock();
|
|
}
|
|
}
|
|
- spin_unlock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
put_files_struct(files);
|
|
put_files_struct(files);
|
|
}
|
|
}
|
|
out:
|
|
out:
|
|
@@ -1263,9 +1264,9 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
|
|
|
|
|
|
files = get_files_struct(task);
|
|
files = get_files_struct(task);
|
|
if (files) {
|
|
if (files) {
|
|
- spin_lock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_lock();
|
|
if (fcheck_files(files, fd)) {
|
|
if (fcheck_files(files, fd)) {
|
|
- spin_unlock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
put_files_struct(files);
|
|
put_files_struct(files);
|
|
if (task_dumpable(task)) {
|
|
if (task_dumpable(task)) {
|
|
inode->i_uid = task->euid;
|
|
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);
|
|
security_task_to_inode(task, inode);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
- spin_unlock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
put_files_struct(files);
|
|
put_files_struct(files);
|
|
}
|
|
}
|
|
d_drop(dentry);
|
|
d_drop(dentry);
|
|
@@ -1369,7 +1370,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
|
|
if (!files)
|
|
if (!files)
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
inode->i_mode = S_IFLNK;
|
|
inode->i_mode = S_IFLNK;
|
|
- spin_lock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_lock();
|
|
file = fcheck_files(files, fd);
|
|
file = fcheck_files(files, fd);
|
|
if (!file)
|
|
if (!file)
|
|
goto out_unlock2;
|
|
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;
|
|
inode->i_mode |= S_IRUSR | S_IXUSR;
|
|
if (file->f_mode & 2)
|
|
if (file->f_mode & 2)
|
|
inode->i_mode |= S_IWUSR | S_IXUSR;
|
|
inode->i_mode |= S_IWUSR | S_IXUSR;
|
|
- spin_unlock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
put_files_struct(files);
|
|
put_files_struct(files);
|
|
inode->i_op = &proc_pid_link_inode_operations;
|
|
inode->i_op = &proc_pid_link_inode_operations;
|
|
inode->i_size = 64;
|
|
inode->i_size = 64;
|
|
@@ -1387,7 +1388,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
out_unlock2:
|
|
out_unlock2:
|
|
- spin_unlock(&files->file_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
put_files_struct(files);
|
|
put_files_struct(files);
|
|
out_unlock:
|
|
out_unlock:
|
|
iput(inode);
|
|
iput(inode);
|