提交 40531542 编写于 作者: C Cesar Eduardo Barros 提交者: Linus Torvalds

sys_swapon: separate final enabling of the swapfile

The block in sys_swapon which does the final adjustments to the
swap_info_struct and to swap_list is the same as the block which
re-inserts it again at sys_swapoff on failure of try_to_unuse(). Move
this code to a separate function, and use it both in sys_swapon and
sys_swapoff.
Signed-off-by: NCesar Eduardo Barros <cesarb@cesarb.net>
Tested-by: NEric B Munson <emunson@mgebm.net>
Acked-by: NEric B Munson <emunson@mgebm.net>
Reviewed-by: NPekka Enberg <penberg@kernel.org>
Reviewed-by: NKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 c6a2b64b
...@@ -1550,6 +1550,36 @@ static int setup_swap_extents(struct swap_info_struct *sis, sector_t *span) ...@@ -1550,6 +1550,36 @@ static int setup_swap_extents(struct swap_info_struct *sis, sector_t *span)
goto out; goto out;
} }
static void enable_swap_info(struct swap_info_struct *p, int prio,
unsigned char *swap_map)
{
int i, prev;
spin_lock(&swap_lock);
if (prio >= 0)
p->prio = prio;
else
p->prio = --least_priority;
p->swap_map = swap_map;
p->flags |= SWP_WRITEOK;
nr_swap_pages += p->pages;
total_swap_pages += p->pages;
/* insert swap space into swap_list: */
prev = -1;
for (i = swap_list.head; i >= 0; i = swap_info[i]->next) {
if (p->prio >= swap_info[i]->prio)
break;
prev = i;
}
p->next = i;
if (prev < 0)
swap_list.head = swap_list.next = p->type;
else
swap_info[prev]->next = p->type;
spin_unlock(&swap_lock);
}
SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
{ {
struct swap_info_struct *p = NULL; struct swap_info_struct *p = NULL;
...@@ -1621,26 +1651,14 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) ...@@ -1621,26 +1651,14 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
current->flags &= ~PF_OOM_ORIGIN; current->flags &= ~PF_OOM_ORIGIN;
if (err) { if (err) {
/*
* reading p->prio and p->swap_map outside the lock is
* safe here because only sys_swapon and sys_swapoff
* change them, and there can be no other sys_swapon or
* sys_swapoff for this swap_info_struct at this point.
*/
/* re-insert swap space back into swap_list */ /* re-insert swap space back into swap_list */
spin_lock(&swap_lock); enable_swap_info(p, p->prio, p->swap_map);
if (p->prio < 0)
p->prio = --least_priority;
p->flags |= SWP_WRITEOK;
nr_swap_pages += p->pages;
total_swap_pages += p->pages;
prev = -1;
for (i = swap_list.head; i >= 0; i = swap_info[i]->next) {
if (p->prio >= swap_info[i]->prio)
break;
prev = i;
}
p->next = i;
if (prev < 0)
swap_list.head = swap_list.next = type;
else
swap_info[prev]->next = type;
spin_unlock(&swap_lock);
goto out_dput; goto out_dput;
} }
...@@ -2037,7 +2055,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) ...@@ -2037,7 +2055,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
char *name; char *name;
struct file *swap_file = NULL; struct file *swap_file = NULL;
struct address_space *mapping; struct address_space *mapping;
int i, prev; int i;
int prio;
int error; int error;
union swap_header *swap_header; union swap_header *swap_header;
int nr_extents; int nr_extents;
...@@ -2134,30 +2153,11 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) ...@@ -2134,30 +2153,11 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
} }
mutex_lock(&swapon_mutex); mutex_lock(&swapon_mutex);
spin_lock(&swap_lock); prio = -1;
if (swap_flags & SWAP_FLAG_PREFER) if (swap_flags & SWAP_FLAG_PREFER)
p->prio = prio =
(swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT; (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT;
else enable_swap_info(p, prio, swap_map);
p->prio = --least_priority;
p->swap_map = swap_map;
p->flags |= SWP_WRITEOK;
nr_swap_pages += p->pages;
total_swap_pages += p->pages;
/* insert swap space into swap_list: */
prev = -1;
for (i = swap_list.head; i >= 0; i = swap_info[i]->next) {
if (p->prio >= swap_info[i]->prio)
break;
prev = i;
}
p->next = i;
if (prev < 0)
swap_list.head = swap_list.next = p->type;
else
swap_info[prev]->next = p->type;
spin_unlock(&swap_lock);
printk(KERN_INFO "Adding %uk swap on %s. " printk(KERN_INFO "Adding %uk swap on %s. "
"Priority:%d extents:%d across:%lluk %s%s\n", "Priority:%d extents:%d across:%lluk %s%s\n",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册