aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swapfile.c
diff options
context:
space:
mode:
authorCesar Eduardo Barros <cesarb@cesarb.net>2011-03-22 19:33:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-22 20:44:08 -0400
commit40531542e2832419566c997af0808513f6f2815d (patch)
tree06e0bb32e53447f58a1821af1c4e960edbd97b0d /mm/swapfile.c
parentc6a2b64ba5d09a1e281e85988ffd650655fa0f39 (diff)
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: Cesar Eduardo Barros <cesarb@cesarb.net> Tested-by: Eric B Munson <emunson@mgebm.net> Acked-by: Eric B Munson <emunson@mgebm.net> Reviewed-by: Pekka Enberg <penberg@kernel.org> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r--mm/swapfile.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 465d972f4c7c..7243044c4139 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1550,6 +1550,36 @@ bad_bmap:
1550 goto out; 1550 goto out;
1551} 1551}
1552 1552
1553static void enable_swap_info(struct swap_info_struct *p, int prio,
1554 unsigned char *swap_map)
1555{
1556 int i, prev;
1557
1558 spin_lock(&swap_lock);
1559 if (prio >= 0)
1560 p->prio = prio;
1561 else
1562 p->prio = --least_priority;
1563 p->swap_map = swap_map;
1564 p->flags |= SWP_WRITEOK;
1565 nr_swap_pages += p->pages;
1566 total_swap_pages += p->pages;
1567
1568 /* insert swap space into swap_list: */
1569 prev = -1;
1570 for (i = swap_list.head; i >= 0; i = swap_info[i]->next) {
1571 if (p->prio >= swap_info[i]->prio)
1572 break;
1573 prev = i;
1574 }
1575 p->next = i;
1576 if (prev < 0)
1577 swap_list.head = swap_list.next = p->type;
1578 else
1579 swap_info[prev]->next = p->type;
1580 spin_unlock(&swap_lock);
1581}
1582
1553SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) 1583SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1554{ 1584{
1555 struct swap_info_struct *p = NULL; 1585 struct swap_info_struct *p = NULL;
@@ -1621,26 +1651,14 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1621 current->flags &= ~PF_OOM_ORIGIN; 1651 current->flags &= ~PF_OOM_ORIGIN;
1622 1652
1623 if (err) { 1653 if (err) {
1654 /*
1655 * reading p->prio and p->swap_map outside the lock is
1656 * safe here because only sys_swapon and sys_swapoff
1657 * change them, and there can be no other sys_swapon or
1658 * sys_swapoff for this swap_info_struct at this point.
1659 */
1624 /* re-insert swap space back into swap_list */ 1660 /* re-insert swap space back into swap_list */
1625 spin_lock(&swap_lock); 1661 enable_swap_info(p, p->prio, p->swap_map);
1626 if (p->prio < 0)
1627 p->prio = --least_priority;
1628 p->flags |= SWP_WRITEOK;
1629 nr_swap_pages += p->pages;
1630 total_swap_pages += p->pages;
1631
1632 prev = -1;
1633 for (i = swap_list.head; i >= 0; i = swap_info[i]->next) {
1634 if (p->prio >= swap_info[i]->prio)
1635 break;
1636 prev = i;
1637 }
1638 p->next = i;
1639 if (prev < 0)
1640 swap_list.head = swap_list.next = type;
1641 else
1642 swap_info[prev]->next = type;
1643 spin_unlock(&swap_lock);
1644 goto out_dput; 1662 goto out_dput;
1645 } 1663 }
1646 1664
@@ -2037,7 +2055,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
2037 char *name; 2055 char *name;
2038 struct file *swap_file = NULL; 2056 struct file *swap_file = NULL;
2039 struct address_space *mapping; 2057 struct address_space *mapping;
2040 int i, prev; 2058 int i;
2059 int prio;
2041 int error; 2060 int error;
2042 union swap_header *swap_header; 2061 union swap_header *swap_header;
2043 int nr_extents; 2062 int nr_extents;
@@ -2134,30 +2153,11 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
2134 } 2153 }
2135 2154
2136 mutex_lock(&swapon_mutex); 2155 mutex_lock(&swapon_mutex);
2137 spin_lock(&swap_lock); 2156 prio = -1;
2138 if (swap_flags & SWAP_FLAG_PREFER) 2157 if (swap_flags & SWAP_FLAG_PREFER)
2139 p->prio = 2158 prio =
2140 (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT; 2159 (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT;
2141 else 2160 enable_swap_info(p, prio, swap_map);
2142 p->prio = --least_priority;
2143 p->swap_map = swap_map;
2144 p->flags |= SWP_WRITEOK;
2145 nr_swap_pages += p->pages;
2146 total_swap_pages += p->pages;
2147
2148 /* insert swap space into swap_list: */
2149 prev = -1;
2150 for (i = swap_list.head; i >= 0; i = swap_info[i]->next) {
2151 if (p->prio >= swap_info[i]->prio)
2152 break;
2153 prev = i;
2154 }
2155 p->next = i;
2156 if (prev < 0)
2157 swap_list.head = swap_list.next = p->type;
2158 else
2159 swap_info[prev]->next = p->type;
2160 spin_unlock(&swap_lock);
2161 2161
2162 printk(KERN_INFO "Adding %uk swap on %s. " 2162 printk(KERN_INFO "Adding %uk swap on %s. "
2163 "Priority:%d extents:%d across:%lluk %s%s\n", 2163 "Priority:%d extents:%d across:%lluk %s%s\n",