aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tty_io.c8
-rw-r--r--fs/locks.c9
-rw-r--r--fs/proc/base.c21
3 files changed, 28 insertions, 10 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 841f0bd..f07637a 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2723,7 +2723,11 @@ static void __do_SAK(void *arg)
}
task_lock(p);
if (p->files) {
- rcu_read_lock();
+ /*
+ * We don't take a ref to the file, so we must
+ * hold ->file_lock instead.
+ */
+ spin_lock(&p->files->file_lock);
fdt = files_fdtable(p->files);
for (i=0; i < fdt->max_fds; i++) {
filp = fcheck_files(p->files, i);
@@ -2738,7 +2742,7 @@ static void __do_SAK(void *arg)
break;
}
}
- rcu_read_unlock();
+ spin_unlock(&p->files->file_lock);
}
task_unlock(p);
} while_each_thread(g, p);
diff --git a/fs/locks.c b/fs/locks.c
index dda83d6..efad7988 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2230,7 +2230,12 @@ void steal_locks(fl_owner_t from)
lock_kernel();
j = 0;
- rcu_read_lock();
+
+ /*
+ * We are not taking a ref to the file structures, so
+ * we need to acquire ->file_lock.
+ */
+ spin_lock(&files->file_lock);
fdt = files_fdtable(files);
for (;;) {
unsigned long set;
@@ -2248,7 +2253,7 @@ void steal_locks(fl_owner_t from)
set >>= 1;
}
}
- rcu_read_unlock();
+ spin_unlock(&files->file_lock);
unlock_kernel();
}
EXPORT_SYMBOL(steal_locks);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a3a3eec..6cc77dc 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -297,16 +297,20 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
files = get_files_struct(task);
if (files) {
- rcu_read_lock();
+ /*
+ * We are not taking a ref to the file structure, so we must
+ * hold ->file_lock.
+ */
+ spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (file) {
*mnt = mntget(file->f_vfsmnt);
*dentry = dget(file->f_dentry);
- rcu_read_unlock();
+ spin_unlock(&files->file_lock);
put_files_struct(files);
return 0;
}
- rcu_read_unlock();
+ spin_unlock(&files->file_lock);
put_files_struct(files);
}
return -ENOENT;
@@ -1523,7 +1527,12 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
if (!files)
goto out_unlock;
inode->i_mode = S_IFLNK;
- rcu_read_lock();
+
+ /*
+ * We are not taking a ref to the file structure, so we must
+ * hold ->file_lock.
+ */
+ spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (!file)
goto out_unlock2;
@@ -1531,7 +1540,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;
- rcu_read_unlock();
+ spin_unlock(&files->file_lock);
put_files_struct(files);
inode->i_op = &proc_pid_link_inode_operations;
inode->i_size = 64;
@@ -1541,7 +1550,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
return NULL;
out_unlock2:
- rcu_read_unlock();
+ spin_unlock(&files->file_lock);
put_files_struct(files);
out_unlock:
iput(inode);