diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index a3a3eecef689..6cc77dc3f3ff 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 | |||
297 | 297 | ||
298 | files = get_files_struct(task); | 298 | files = get_files_struct(task); |
299 | if (files) { | 299 | if (files) { |
300 | rcu_read_lock(); | 300 | /* |
301 | * We are not taking a ref to the file structure, so we must | ||
302 | * hold ->file_lock. | ||
303 | */ | ||
304 | spin_lock(&files->file_lock); | ||
301 | file = fcheck_files(files, fd); | 305 | file = fcheck_files(files, fd); |
302 | if (file) { | 306 | if (file) { |
303 | *mnt = mntget(file->f_vfsmnt); | 307 | *mnt = mntget(file->f_vfsmnt); |
304 | *dentry = dget(file->f_dentry); | 308 | *dentry = dget(file->f_dentry); |
305 | rcu_read_unlock(); | 309 | spin_unlock(&files->file_lock); |
306 | put_files_struct(files); | 310 | put_files_struct(files); |
307 | return 0; | 311 | return 0; |
308 | } | 312 | } |
309 | rcu_read_unlock(); | 313 | spin_unlock(&files->file_lock); |
310 | put_files_struct(files); | 314 | put_files_struct(files); |
311 | } | 315 | } |
312 | return -ENOENT; | 316 | return -ENOENT; |
@@ -1523,7 +1527,12 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1523 | if (!files) | 1527 | if (!files) |
1524 | goto out_unlock; | 1528 | goto out_unlock; |
1525 | inode->i_mode = S_IFLNK; | 1529 | inode->i_mode = S_IFLNK; |
1526 | rcu_read_lock(); | 1530 | |
1531 | /* | ||
1532 | * We are not taking a ref to the file structure, so we must | ||
1533 | * hold ->file_lock. | ||
1534 | */ | ||
1535 | spin_lock(&files->file_lock); | ||
1527 | file = fcheck_files(files, fd); | 1536 | file = fcheck_files(files, fd); |
1528 | if (!file) | 1537 | if (!file) |
1529 | goto out_unlock2; | 1538 | goto out_unlock2; |
@@ -1531,7 +1540,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1531 | inode->i_mode |= S_IRUSR | S_IXUSR; | 1540 | inode->i_mode |= S_IRUSR | S_IXUSR; |
1532 | if (file->f_mode & 2) | 1541 | if (file->f_mode & 2) |
1533 | inode->i_mode |= S_IWUSR | S_IXUSR; | 1542 | inode->i_mode |= S_IWUSR | S_IXUSR; |
1534 | rcu_read_unlock(); | 1543 | spin_unlock(&files->file_lock); |
1535 | put_files_struct(files); | 1544 | put_files_struct(files); |
1536 | inode->i_op = &proc_pid_link_inode_operations; | 1545 | inode->i_op = &proc_pid_link_inode_operations; |
1537 | inode->i_size = 64; | 1546 | inode->i_size = 64; |
@@ -1541,7 +1550,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1541 | return NULL; | 1550 | return NULL; |
1542 | 1551 | ||
1543 | out_unlock2: | 1552 | out_unlock2: |
1544 | rcu_read_unlock(); | 1553 | spin_unlock(&files->file_lock); |
1545 | put_files_struct(files); | 1554 | put_files_struct(files); |
1546 | out_unlock: | 1555 | out_unlock: |
1547 | iput(inode); | 1556 | iput(inode); |