Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40531542 authored by Cesar Eduardo Barros's avatar Cesar Eduardo Barros Committed by Linus Torvalds
Browse files

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: default avatarCesar Eduardo Barros <cesarb@cesarb.net>
Tested-by: default avatarEric B Munson <emunson@mgebm.net>
Acked-by: default avatarEric B Munson <emunson@mgebm.net>
Reviewed-by: default avatarPekka Enberg <penberg@kernel.org>
Reviewed-by: default avatarKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c6a2b64b
Loading
Loading
Loading
Loading
+42 −42
Original line number Diff line number Diff line
@@ -1550,6 +1550,36 @@ bad_bmap:
	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)
{
	struct swap_info_struct *p = NULL;
@@ -1621,26 +1651,14 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
	current->flags &= ~PF_OOM_ORIGIN;

	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 */
		spin_lock(&swap_lock);
		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);
		enable_swap_info(p, p->prio, p->swap_map);
		goto out_dput;
	}

@@ -2037,7 +2055,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
	char *name;
	struct file *swap_file = NULL;
	struct address_space *mapping;
	int i, prev;
	int i;
	int prio;
	int error;
	union swap_header *swap_header;
	int nr_extents;
@@ -2134,30 +2153,11 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
	}

	mutex_lock(&swapon_mutex);
	spin_lock(&swap_lock);
	prio = -1;
	if (swap_flags & SWAP_FLAG_PREFER)
		p->prio =
		prio =
		  (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT;
	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);
	enable_swap_info(p, prio, swap_map);

	printk(KERN_INFO "Adding %uk swap on %s.  "
			"Priority:%d extents:%d across:%lluk %s%s\n",