summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2005-09-04 02:54:33 +0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 11:05:40 +0400
commit4cd3bb10ff0b21b77b5a4cd13b4bd36694e054c4 (patch)
treee2a76a229b2c030a7d4aec1155e505fd4c087067
parente2244ec2efa4ee1edf391d0001d314933e2b2974 (diff)
downloadlinux-4cd3bb10ff0b21b77b5a4cd13b4bd36694e054c4.tar.xz
[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>
-rw-r--r--mm/swapfile.c4
1 files changed, 2 insertions, 2 deletions
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);