From: Hugh Dickins Date: Sat, 3 Sep 2005 22:54:33 +0000 (-0700) Subject: [PATCH] swap: move destroy_swap_extents calls X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=4cd3bb10ff0b21b77b5a4cd13b4bd36694e054c4;p=openwrt%2Fstaging%2Fblogic.git [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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/mm/swapfile.c b/mm/swapfile.c index 5ac5333f37a0..4b39e9501d44 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1129,6 +1129,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile) swap_list_unlock(); goto out_dput; } + destroy_swap_extents(p); down(&swapon_sem); swap_list_lock(); drain_mmlist(); @@ -1139,7 +1140,6 @@ asmlinkage long sys_swapoff(const char __user * specialfile) swap_map = p->swap_map; p->swap_map = NULL; p->flags = 0; - destroy_swap_extents(p); swap_device_unlock(p); swap_list_unlock(); up(&swapon_sem); @@ -1531,6 +1531,7 @@ bad_swap: set_blocksize(bdev, p->old_block_size); bd_release(bdev); } + destroy_swap_extents(p); bad_swap_2: swap_list_lock(); swap_map = p->swap_map; @@ -1540,7 +1541,6 @@ bad_swap_2: if (!(swap_flags & SWAP_FLAG_PREFER)) ++least_priority; swap_list_unlock(); - destroy_swap_extents(p); vfree(swap_map); if (swap_file) filp_close(swap_file, NULL);