[PATCH] swap: move destroy_swap_extents calls
sys_swapon's call to destroy_swap_extents on failure is made after the final swap_list_unlock, which is faintly unsafe: another sys_swapon might already be setting up that swap_info_struct. Calling it earlier, before taking swap_list_lock, is safe. sys_swapoff's call to destroy_swap_extents was safe, but likewise move it earlier, before taking the locks (once try_to_unuse has completed, nothing can be needing the swap extents). Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
e2244ec2ef
commit
4cd3bb10ff
1 changed files with 2 additions and 2 deletions
|
@ -1129,6 +1129,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
|
||||||
swap_list_unlock();
|
swap_list_unlock();
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
}
|
}
|
||||||
|
destroy_swap_extents(p);
|
||||||
down(&swapon_sem);
|
down(&swapon_sem);
|
||||||
swap_list_lock();
|
swap_list_lock();
|
||||||
drain_mmlist();
|
drain_mmlist();
|
||||||
|
@ -1139,7 +1140,6 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
|
||||||
swap_map = p->swap_map;
|
swap_map = p->swap_map;
|
||||||
p->swap_map = NULL;
|
p->swap_map = NULL;
|
||||||
p->flags = 0;
|
p->flags = 0;
|
||||||
destroy_swap_extents(p);
|
|
||||||
swap_device_unlock(p);
|
swap_device_unlock(p);
|
||||||
swap_list_unlock();
|
swap_list_unlock();
|
||||||
up(&swapon_sem);
|
up(&swapon_sem);
|
||||||
|
@ -1531,6 +1531,7 @@ bad_swap:
|
||||||
set_blocksize(bdev, p->old_block_size);
|
set_blocksize(bdev, p->old_block_size);
|
||||||
bd_release(bdev);
|
bd_release(bdev);
|
||||||
}
|
}
|
||||||
|
destroy_swap_extents(p);
|
||||||
bad_swap_2:
|
bad_swap_2:
|
||||||
swap_list_lock();
|
swap_list_lock();
|
||||||
swap_map = p->swap_map;
|
swap_map = p->swap_map;
|
||||||
|
@ -1540,7 +1541,6 @@ bad_swap_2:
|
||||||
if (!(swap_flags & SWAP_FLAG_PREFER))
|
if (!(swap_flags & SWAP_FLAG_PREFER))
|
||||||
++least_priority;
|
++least_priority;
|
||||||
swap_list_unlock();
|
swap_list_unlock();
|
||||||
destroy_swap_extents(p);
|
|
||||||
vfree(swap_map);
|
vfree(swap_map);
|
||||||
if (swap_file)
|
if (swap_file)
|
||||||
filp_close(swap_file, NULL);
|
filp_close(swap_file, NULL);
|
||||||
|
|
Loading…
Reference in a new issue