Commit 4cd3bb10 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

[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: default avatarHugh Dickins <hugh@veritas.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e2244ec2
...@@ -1129,6 +1129,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile) ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment