mirror of
https://github.com/a52xq-dev/kernel.git
synced 2026-10-18 21:58:11 +07:00
proc: use down_read_killable mmap_sem for /proc/pid/map_files
[ Upstream commit cd9e2bb8271c971d9f37c722be2616c7f8ba0664 ] Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation. It seems ->d_revalidate() could return any error (except ECHILD) to abort validation and pass error as result of lookup sequence. [akpm@linux-foundation.org: fix proc_map_files_lookup() return value, per Andrei] Link: http://lkml.kernel.org/r/156007493995.3335.9595044802115356911.stgit@buzz Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Reviewed-by: Roman Gushchin <guro@fb.com> Reviewed-by: Cyrill Gorcunov <gorcunov@gmail.com> Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Matthew Wilcox <willy@infradead.org> Cc: Michal Koutný <mkoutny@suse.com> Cc: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
3d617da8a9
commit
6ecdcbcd30
1 changed files with 22 additions and 6 deletions
|
|
@ -1960,9 +1960,12 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
|
|||
goto out;
|
||||
|
||||
if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) {
|
||||
down_read(&mm->mmap_sem);
|
||||
exact_vma_exists = !!find_exact_vma(mm, vm_start, vm_end);
|
||||
up_read(&mm->mmap_sem);
|
||||
status = down_read_killable(&mm->mmap_sem);
|
||||
if (!status) {
|
||||
exact_vma_exists = !!find_exact_vma(mm, vm_start,
|
||||
vm_end);
|
||||
up_read(&mm->mmap_sem);
|
||||
}
|
||||
}
|
||||
|
||||
mmput(mm);
|
||||
|
|
@ -2008,8 +2011,11 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
|
|||
if (rc)
|
||||
goto out_mmput;
|
||||
|
||||
rc = down_read_killable(&mm->mmap_sem);
|
||||
if (rc)
|
||||
goto out_mmput;
|
||||
|
||||
rc = -ENOENT;
|
||||
down_read(&mm->mmap_sem);
|
||||
vma = find_exact_vma(mm, vm_start, vm_end);
|
||||
if (vma && vma->vm_file) {
|
||||
*path = vma->vm_file->f_path;
|
||||
|
|
@ -2105,7 +2111,11 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
|
|||
if (!mm)
|
||||
goto out_put_task;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
result = ERR_PTR(-EINTR);
|
||||
if (down_read_killable(&mm->mmap_sem))
|
||||
goto out_put_mm;
|
||||
|
||||
result = ERR_PTR(-ENOENT);
|
||||
vma = find_exact_vma(mm, vm_start, vm_end);
|
||||
if (!vma)
|
||||
goto out_no_vma;
|
||||
|
|
@ -2116,6 +2126,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
|
|||
|
||||
out_no_vma:
|
||||
up_read(&mm->mmap_sem);
|
||||
out_put_mm:
|
||||
mmput(mm);
|
||||
out_put_task:
|
||||
put_task_struct(task);
|
||||
|
|
@ -2157,7 +2168,12 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
|
|||
mm = get_task_mm(task);
|
||||
if (!mm)
|
||||
goto out_put_task;
|
||||
down_read(&mm->mmap_sem);
|
||||
|
||||
ret = down_read_killable(&mm->mmap_sem);
|
||||
if (ret) {
|
||||
mmput(mm);
|
||||
goto out_put_task;
|
||||
}
|
||||
|
||||
nr_files = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue