aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swapfile.c
diff options
context:
space:
mode:
authorHugh Dickins <hugh.dickins@tiscali.co.uk>2009-12-14 20:58:41 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-15 11:53:15 -0500
commitefa90a981bbc891efad96db2a75b5487e00852ca (patch)
treefc64a5d5b71e84eb1eec2810fb0568a79a361827 /mm/swapfile.c
parentf29ad6a99b596b8169744d107bf088e8be9e8d0d (diff)
swap_info: change to array of pointers
The swap_info_struct is only 76 or 104 bytes, but it does seem wrong to reserve an array of about 30 of them in bss, when most people will want only one. Change swap_info[] to an array of pointers. That does need a "type" field in the structure: pack it as a char with next type and short prio (aha, char is unsigned by default on PowerPC). Use the (admittedly peculiar) name "type" throughout for this index. /proc/swaps does not take swap_lock: I wouldn't want it to, but do take care with barriers when adding a new item to the array (never removed). Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Acked-by: Rik van Riel <riel@redhat.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.c204
1 files changed, 113 insertions, 91 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index f83f1c6f6196..dc88a7e4257e 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -49,7 +49,7 @@ static const char Unused_offset[] = "Unused swap offset entry ";
49 49
50static struct swap_list_t swap_list = {-1, -1}; 50static struct swap_list_t swap_list = {-1, -1};
51 51
52static struct swap_info_struct swap_info[MAX_SWAPFILES]; 52static struct swap_info_struct *swap_info[MAX_SWAPFILES];
53 53
54static DEFINE_MUTEX(swapon_mutex); 54static DEFINE_MUTEX(swapon_mutex);
55 55
@@ -79,12 +79,11 @@ static inline unsigned short encode_swapmap(int count, bool has_cache)
79 return ret; 79 return ret;
80} 80}
81 81
82/* returnes 1 if swap entry is freed */ 82/* returns 1 if swap entry is freed */
83static int 83static int
84__try_to_reclaim_swap(struct swap_info_struct *si, unsigned long offset) 84__try_to_reclaim_swap(struct swap_info_struct *si, unsigned long offset)
85{ 85{
86 int type = si - swap_info; 86 swp_entry_t entry = swp_entry(si->type, offset);
87 swp_entry_t entry = swp_entry(type, offset);
88 struct page *page; 87 struct page *page;
89 int ret = 0; 88 int ret = 0;
90 89
@@ -120,7 +119,7 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
120 down_read(&swap_unplug_sem); 119 down_read(&swap_unplug_sem);
121 entry.val = page_private(page); 120 entry.val = page_private(page);
122 if (PageSwapCache(page)) { 121 if (PageSwapCache(page)) {
123 struct block_device *bdev = swap_info[swp_type(entry)].bdev; 122 struct block_device *bdev = swap_info[swp_type(entry)]->bdev;
124 struct backing_dev_info *bdi; 123 struct backing_dev_info *bdi;
125 124
126 /* 125 /*
@@ -467,10 +466,10 @@ swp_entry_t get_swap_page(void)
467 nr_swap_pages--; 466 nr_swap_pages--;
468 467
469 for (type = swap_list.next; type >= 0 && wrapped < 2; type = next) { 468 for (type = swap_list.next; type >= 0 && wrapped < 2; type = next) {
470 si = swap_info + type; 469 si = swap_info[type];
471 next = si->next; 470 next = si->next;
472 if (next < 0 || 471 if (next < 0 ||
473 (!wrapped && si->prio != swap_info[next].prio)) { 472 (!wrapped && si->prio != swap_info[next]->prio)) {
474 next = swap_list.head; 473 next = swap_list.head;
475 wrapped++; 474 wrapped++;
476 } 475 }
@@ -503,8 +502,8 @@ swp_entry_t get_swap_page_of_type(int type)
503 pgoff_t offset; 502 pgoff_t offset;
504 503
505 spin_lock(&swap_lock); 504 spin_lock(&swap_lock);
506 si = swap_info + type; 505 si = swap_info[type];
507 if (si->flags & SWP_WRITEOK) { 506 if (si && (si->flags & SWP_WRITEOK)) {
508 nr_swap_pages--; 507 nr_swap_pages--;
509 /* This is called for allocating swap entry, not cache */ 508 /* This is called for allocating swap entry, not cache */
510 offset = scan_swap_map(si, SWAP_MAP); 509 offset = scan_swap_map(si, SWAP_MAP);
@@ -528,7 +527,7 @@ static struct swap_info_struct * swap_info_get(swp_entry_t entry)
528 type = swp_type(entry); 527 type = swp_type(entry);
529 if (type >= nr_swapfiles) 528 if (type >= nr_swapfiles)
530 goto bad_nofile; 529 goto bad_nofile;
531 p = & swap_info[type]; 530 p = swap_info[type];
532 if (!(p->flags & SWP_USED)) 531 if (!(p->flags & SWP_USED))
533 goto bad_device; 532 goto bad_device;
534 offset = swp_offset(entry); 533 offset = swp_offset(entry);
@@ -581,8 +580,9 @@ static int swap_entry_free(struct swap_info_struct *p,
581 p->lowest_bit = offset; 580 p->lowest_bit = offset;
582 if (offset > p->highest_bit) 581 if (offset > p->highest_bit)
583 p->highest_bit = offset; 582 p->highest_bit = offset;
584 if (p->prio > swap_info[swap_list.next].prio) 583 if (swap_list.next >= 0 &&
585 swap_list.next = p - swap_info; 584 p->prio > swap_info[swap_list.next]->prio)
585 swap_list.next = p->type;
586 nr_swap_pages++; 586 nr_swap_pages++;
587 p->inuse_pages--; 587 p->inuse_pages--;
588 } 588 }
@@ -741,14 +741,14 @@ int free_swap_and_cache(swp_entry_t entry)
741int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) 741int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
742{ 742{
743 struct block_device *bdev = NULL; 743 struct block_device *bdev = NULL;
744 int i; 744 int type;
745 745
746 if (device) 746 if (device)
747 bdev = bdget(device); 747 bdev = bdget(device);
748 748
749 spin_lock(&swap_lock); 749 spin_lock(&swap_lock);
750 for (i = 0; i < nr_swapfiles; i++) { 750 for (type = 0; type < nr_swapfiles; type++) {
751 struct swap_info_struct *sis = swap_info + i; 751 struct swap_info_struct *sis = swap_info[type];
752 752
753 if (!(sis->flags & SWP_WRITEOK)) 753 if (!(sis->flags & SWP_WRITEOK))
754 continue; 754 continue;
@@ -758,7 +758,7 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
758 *bdev_p = bdgrab(sis->bdev); 758 *bdev_p = bdgrab(sis->bdev);
759 759
760 spin_unlock(&swap_lock); 760 spin_unlock(&swap_lock);
761 return i; 761 return type;
762 } 762 }
763 if (bdev == sis->bdev) { 763 if (bdev == sis->bdev) {
764 struct swap_extent *se; 764 struct swap_extent *se;
@@ -771,7 +771,7 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
771 771
772 spin_unlock(&swap_lock); 772 spin_unlock(&swap_lock);
773 bdput(bdev); 773 bdput(bdev);
774 return i; 774 return type;
775 } 775 }
776 } 776 }
777 } 777 }
@@ -792,15 +792,17 @@ unsigned int count_swap_pages(int type, int free)
792{ 792{
793 unsigned int n = 0; 793 unsigned int n = 0;
794 794
795 if (type < nr_swapfiles) { 795 spin_lock(&swap_lock);
796 spin_lock(&swap_lock); 796 if ((unsigned int)type < nr_swapfiles) {
797 if (swap_info[type].flags & SWP_WRITEOK) { 797 struct swap_info_struct *sis = swap_info[type];
798 n = swap_info[type].pages; 798
799 if (sis->flags & SWP_WRITEOK) {
800 n = sis->pages;
799 if (free) 801 if (free)
800 n -= swap_info[type].inuse_pages; 802 n -= sis->inuse_pages;
801 } 803 }
802 spin_unlock(&swap_lock);
803 } 804 }
805 spin_unlock(&swap_lock);
804 return n; 806 return n;
805} 807}
806#endif 808#endif
@@ -1024,7 +1026,7 @@ static unsigned int find_next_to_unuse(struct swap_info_struct *si,
1024 */ 1026 */
1025static int try_to_unuse(unsigned int type) 1027static int try_to_unuse(unsigned int type)
1026{ 1028{
1027 struct swap_info_struct * si = &swap_info[type]; 1029 struct swap_info_struct *si = swap_info[type];
1028 struct mm_struct *start_mm; 1030 struct mm_struct *start_mm;
1029 unsigned short *swap_map; 1031 unsigned short *swap_map;
1030 unsigned short swcount; 1032 unsigned short swcount;
@@ -1270,10 +1272,10 @@ retry:
1270static void drain_mmlist(void) 1272static void drain_mmlist(void)
1271{ 1273{
1272 struct list_head *p, *next; 1274 struct list_head *p, *next;
1273 unsigned int i; 1275 unsigned int type;
1274 1276
1275 for (i = 0; i < nr_swapfiles; i++) 1277 for (type = 0; type < nr_swapfiles; type++)
1276 if (swap_info[i].inuse_pages) 1278 if (swap_info[type]->inuse_pages)
1277 return; 1279 return;
1278 spin_lock(&mmlist_lock); 1280 spin_lock(&mmlist_lock);
1279 list_for_each_safe(p, next, &init_mm.mmlist) 1281 list_for_each_safe(p, next, &init_mm.mmlist)
@@ -1293,7 +1295,7 @@ sector_t map_swap_page(swp_entry_t entry, struct block_device **bdev)
1293 struct swap_extent *se; 1295 struct swap_extent *se;
1294 pgoff_t offset; 1296 pgoff_t offset;
1295 1297
1296 sis = swap_info + swp_type(entry); 1298 sis = swap_info[swp_type(entry)];
1297 *bdev = sis->bdev; 1299 *bdev = sis->bdev;
1298 1300
1299 offset = swp_offset(entry); 1301 offset = swp_offset(entry);
@@ -1321,17 +1323,15 @@ sector_t map_swap_page(swp_entry_t entry, struct block_device **bdev)
1321 * Get the (PAGE_SIZE) block corresponding to given offset on the swapdev 1323 * Get the (PAGE_SIZE) block corresponding to given offset on the swapdev
1322 * corresponding to given index in swap_info (swap type). 1324 * corresponding to given index in swap_info (swap type).
1323 */ 1325 */
1324sector_t swapdev_block(int swap_type, pgoff_t offset) 1326sector_t swapdev_block(int type, pgoff_t offset)
1325{ 1327{
1326 struct swap_info_struct *sis;
1327 struct block_device *bdev; 1328 struct block_device *bdev;
1328 1329
1329 if (swap_type >= nr_swapfiles) 1330 if ((unsigned int)type >= nr_swapfiles)
1330 return 0; 1331 return 0;
1331 1332 if (!(swap_info[type]->flags & SWP_WRITEOK))
1332 sis = swap_info + swap_type; 1333 return 0;
1333 return (sis->flags & SWP_WRITEOK) ? 1334 return map_swap_page(swp_entry(type, offset), &bdev);
1334 map_swap_page(swp_entry(swap_type, offset), &bdev) : 0;
1335} 1335}
1336#endif /* CONFIG_HIBERNATION */ 1336#endif /* CONFIG_HIBERNATION */
1337 1337
@@ -1547,8 +1547,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1547 mapping = victim->f_mapping; 1547 mapping = victim->f_mapping;
1548 prev = -1; 1548 prev = -1;
1549 spin_lock(&swap_lock); 1549 spin_lock(&swap_lock);
1550 for (type = swap_list.head; type >= 0; type = swap_info[type].next) { 1550 for (type = swap_list.head; type >= 0; type = swap_info[type]->next) {
1551 p = swap_info + type; 1551 p = swap_info[type];
1552 if (p->flags & SWP_WRITEOK) { 1552 if (p->flags & SWP_WRITEOK) {
1553 if (p->swap_file->f_mapping == mapping) 1553 if (p->swap_file->f_mapping == mapping)
1554 break; 1554 break;
@@ -1567,18 +1567,17 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1567 spin_unlock(&swap_lock); 1567 spin_unlock(&swap_lock);
1568 goto out_dput; 1568 goto out_dput;
1569 } 1569 }
1570 if (prev < 0) { 1570 if (prev < 0)
1571 swap_list.head = p->next; 1571 swap_list.head = p->next;
1572 } else { 1572 else
1573 swap_info[prev].next = p->next; 1573 swap_info[prev]->next = p->next;
1574 }
1575 if (type == swap_list.next) { 1574 if (type == swap_list.next) {
1576 /* just pick something that's safe... */ 1575 /* just pick something that's safe... */
1577 swap_list.next = swap_list.head; 1576 swap_list.next = swap_list.head;
1578 } 1577 }
1579 if (p->prio < 0) { 1578 if (p->prio < 0) {
1580 for (i = p->next; i >= 0; i = swap_info[i].next) 1579 for (i = p->next; i >= 0; i = swap_info[i]->next)
1581 swap_info[i].prio = p->prio--; 1580 swap_info[i]->prio = p->prio--;
1582 least_priority++; 1581 least_priority++;
1583 } 1582 }
1584 nr_swap_pages -= p->pages; 1583 nr_swap_pages -= p->pages;
@@ -1596,16 +1595,16 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1596 if (p->prio < 0) 1595 if (p->prio < 0)
1597 p->prio = --least_priority; 1596 p->prio = --least_priority;
1598 prev = -1; 1597 prev = -1;
1599 for (i = swap_list.head; i >= 0; i = swap_info[i].next) { 1598 for (i = swap_list.head; i >= 0; i = swap_info[i]->next) {
1600 if (p->prio >= swap_info[i].prio) 1599 if (p->prio >= swap_info[i]->prio)
1601 break; 1600 break;
1602 prev = i; 1601 prev = i;
1603 } 1602 }
1604 p->next = i; 1603 p->next = i;
1605 if (prev < 0) 1604 if (prev < 0)
1606 swap_list.head = swap_list.next = p - swap_info; 1605 swap_list.head = swap_list.next = type;
1607 else 1606 else
1608 swap_info[prev].next = p - swap_info; 1607 swap_info[prev]->next = type;
1609 nr_swap_pages += p->pages; 1608 nr_swap_pages += p->pages;
1610 total_swap_pages += p->pages; 1609 total_swap_pages += p->pages;
1611 p->flags |= SWP_WRITEOK; 1610 p->flags |= SWP_WRITEOK;
@@ -1665,8 +1664,8 @@ out:
1665/* iterator */ 1664/* iterator */
1666static void *swap_start(struct seq_file *swap, loff_t *pos) 1665static void *swap_start(struct seq_file *swap, loff_t *pos)
1667{ 1666{
1668 struct swap_info_struct *ptr = swap_info; 1667 struct swap_info_struct *si;
1669 int i; 1668 int type;
1670 loff_t l = *pos; 1669 loff_t l = *pos;
1671 1670
1672 mutex_lock(&swapon_mutex); 1671 mutex_lock(&swapon_mutex);
@@ -1674,11 +1673,13 @@ static void *swap_start(struct seq_file *swap, loff_t *pos)
1674 if (!l) 1673 if (!l)
1675 return SEQ_START_TOKEN; 1674 return SEQ_START_TOKEN;
1676 1675
1677 for (i = 0; i < nr_swapfiles; i++, ptr++) { 1676 for (type = 0; type < nr_swapfiles; type++) {
1678 if (!(ptr->flags & SWP_USED) || !ptr->swap_map) 1677 smp_rmb(); /* read nr_swapfiles before swap_info[type] */
1678 si = swap_info[type];
1679 if (!(si->flags & SWP_USED) || !si->swap_map)
1679 continue; 1680 continue;
1680 if (!--l) 1681 if (!--l)
1681 return ptr; 1682 return si;
1682 } 1683 }
1683 1684
1684 return NULL; 1685 return NULL;
@@ -1686,21 +1687,21 @@ static void *swap_start(struct seq_file *swap, loff_t *pos)
1686 1687
1687static void *swap_next(struct seq_file *swap, void *v, loff_t *pos) 1688static void *swap_next(struct seq_file *swap, void *v, loff_t *pos)
1688{ 1689{
1689 struct swap_info_struct *ptr; 1690 struct swap_info_struct *si = v;
1690 struct swap_info_struct *endptr = swap_info + nr_swapfiles; 1691 int type;
1691 1692
1692 if (v == SEQ_START_TOKEN) 1693 if (v == SEQ_START_TOKEN)
1693 ptr = swap_info; 1694 type = 0;
1694 else { 1695 else
1695 ptr = v; 1696 type = si->type + 1;
1696 ptr++;
1697 }
1698 1697
1699 for (; ptr < endptr; ptr++) { 1698 for (; type < nr_swapfiles; type++) {
1700 if (!(ptr->flags & SWP_USED) || !ptr->swap_map) 1699 smp_rmb(); /* read nr_swapfiles before swap_info[type] */
1700 si = swap_info[type];
1701 if (!(si->flags & SWP_USED) || !si->swap_map)
1701 continue; 1702 continue;
1702 ++*pos; 1703 ++*pos;
1703 return ptr; 1704 return si;
1704 } 1705 }
1705 1706
1706 return NULL; 1707 return NULL;
@@ -1713,24 +1714,24 @@ static void swap_stop(struct seq_file *swap, void *v)
1713 1714
1714static int swap_show(struct seq_file *swap, void *v) 1715static int swap_show(struct seq_file *swap, void *v)
1715{ 1716{
1716 struct swap_info_struct *ptr = v; 1717 struct swap_info_struct *si = v;
1717 struct file *file; 1718 struct file *file;
1718 int len; 1719 int len;
1719 1720
1720 if (ptr == SEQ_START_TOKEN) { 1721 if (si == SEQ_START_TOKEN) {
1721 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n"); 1722 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
1722 return 0; 1723 return 0;
1723 } 1724 }
1724 1725
1725 file = ptr->swap_file; 1726 file = si->swap_file;
1726 len = seq_path(swap, &file->f_path, " \t\n\\"); 1727 len = seq_path(swap, &file->f_path, " \t\n\\");
1727 seq_printf(swap, "%*s%s\t%u\t%u\t%d\n", 1728 seq_printf(swap, "%*s%s\t%u\t%u\t%d\n",
1728 len < 40 ? 40 - len : 1, " ", 1729 len < 40 ? 40 - len : 1, " ",
1729 S_ISBLK(file->f_path.dentry->d_inode->i_mode) ? 1730 S_ISBLK(file->f_path.dentry->d_inode->i_mode) ?
1730 "partition" : "file\t", 1731 "partition" : "file\t",
1731 ptr->pages << (PAGE_SHIFT - 10), 1732 si->pages << (PAGE_SHIFT - 10),
1732 ptr->inuse_pages << (PAGE_SHIFT - 10), 1733 si->inuse_pages << (PAGE_SHIFT - 10),
1733 ptr->prio); 1734 si->prio);
1734 return 0; 1735 return 0;
1735} 1736}
1736 1737
@@ -1798,23 +1799,45 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1798 1799
1799 if (!capable(CAP_SYS_ADMIN)) 1800 if (!capable(CAP_SYS_ADMIN))
1800 return -EPERM; 1801 return -EPERM;
1802
1803 p = kzalloc(sizeof(*p), GFP_KERNEL);
1804 if (!p)
1805 return -ENOMEM;
1806
1801 spin_lock(&swap_lock); 1807 spin_lock(&swap_lock);
1802 p = swap_info; 1808 for (type = 0; type < nr_swapfiles; type++) {
1803 for (type = 0 ; type < nr_swapfiles ; type++,p++) 1809 if (!(swap_info[type]->flags & SWP_USED))
1804 if (!(p->flags & SWP_USED))
1805 break; 1810 break;
1811 }
1806 error = -EPERM; 1812 error = -EPERM;
1807 if (type >= MAX_SWAPFILES) { 1813 if (type >= MAX_SWAPFILES) {
1808 spin_unlock(&swap_lock); 1814 spin_unlock(&swap_lock);
1815 kfree(p);
1809 goto out; 1816 goto out;
1810 } 1817 }
1811 if (type >= nr_swapfiles)
1812 nr_swapfiles = type+1;
1813 memset(p, 0, sizeof(*p));
1814 INIT_LIST_HEAD(&p->extent_list); 1818 INIT_LIST_HEAD(&p->extent_list);
1819 if (type >= nr_swapfiles) {
1820 p->type = type;
1821 swap_info[type] = p;
1822 /*
1823 * Write swap_info[type] before nr_swapfiles, in case a
1824 * racing procfs swap_start() or swap_next() is reading them.
1825 * (We never shrink nr_swapfiles, we never free this entry.)
1826 */
1827 smp_wmb();
1828 nr_swapfiles++;
1829 } else {
1830 kfree(p);
1831 p = swap_info[type];
1832 /*
1833 * Do not memset this entry: a racing procfs swap_next()
1834 * would be relying on p->type to remain valid.
1835 */
1836 }
1815 p->flags = SWP_USED; 1837 p->flags = SWP_USED;
1816 p->next = -1; 1838 p->next = -1;
1817 spin_unlock(&swap_lock); 1839 spin_unlock(&swap_lock);
1840
1818 name = getname(specialfile); 1841 name = getname(specialfile);
1819 error = PTR_ERR(name); 1842 error = PTR_ERR(name);
1820 if (IS_ERR(name)) { 1843 if (IS_ERR(name)) {
@@ -1834,7 +1857,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1834 1857
1835 error = -EBUSY; 1858 error = -EBUSY;
1836 for (i = 0; i < nr_swapfiles; i++) { 1859 for (i = 0; i < nr_swapfiles; i++) {
1837 struct swap_info_struct *q = &swap_info[i]; 1860 struct swap_info_struct *q = swap_info[i];
1838 1861
1839 if (i == type || !q->swap_file) 1862 if (i == type || !q->swap_file)
1840 continue; 1863 continue;
@@ -1909,6 +1932,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1909 1932
1910 p->lowest_bit = 1; 1933 p->lowest_bit = 1;
1911 p->cluster_next = 1; 1934 p->cluster_next = 1;
1935 p->cluster_nr = 0;
1912 1936
1913 /* 1937 /*
1914 * Find out how many pages are allowed for a single swap 1938 * Find out how many pages are allowed for a single swap
@@ -2015,18 +2039,16 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
2015 2039
2016 /* insert swap space into swap_list: */ 2040 /* insert swap space into swap_list: */
2017 prev = -1; 2041 prev = -1;
2018 for (i = swap_list.head; i >= 0; i = swap_info[i].next) { 2042 for (i = swap_list.head; i >= 0; i = swap_info[i]->next) {
2019 if (p->prio >= swap_info[i].prio) { 2043 if (p->prio >= swap_info[i]->prio)
2020 break; 2044 break;
2021 }
2022 prev = i; 2045 prev = i;
2023 } 2046 }
2024 p->next = i; 2047 p->next = i;
2025 if (prev < 0) { 2048 if (prev < 0)
2026 swap_list.head = swap_list.next = p - swap_info; 2049 swap_list.head = swap_list.next = type;
2027 } else { 2050 else
2028 swap_info[prev].next = p - swap_info; 2051 swap_info[prev]->next = type;
2029 }
2030 spin_unlock(&swap_lock); 2052 spin_unlock(&swap_lock);
2031 mutex_unlock(&swapon_mutex); 2053 mutex_unlock(&swapon_mutex);
2032 error = 0; 2054 error = 0;
@@ -2063,15 +2085,15 @@ out:
2063 2085
2064void si_swapinfo(struct sysinfo *val) 2086void si_swapinfo(struct sysinfo *val)
2065{ 2087{
2066 unsigned int i; 2088 unsigned int type;
2067 unsigned long nr_to_be_unused = 0; 2089 unsigned long nr_to_be_unused = 0;
2068 2090
2069 spin_lock(&swap_lock); 2091 spin_lock(&swap_lock);
2070 for (i = 0; i < nr_swapfiles; i++) { 2092 for (type = 0; type < nr_swapfiles; type++) {
2071 if (!(swap_info[i].flags & SWP_USED) || 2093 struct swap_info_struct *si = swap_info[type];
2072 (swap_info[i].flags & SWP_WRITEOK)) 2094
2073 continue; 2095 if ((si->flags & SWP_USED) && !(si->flags & SWP_WRITEOK))
2074 nr_to_be_unused += swap_info[i].inuse_pages; 2096 nr_to_be_unused += si->inuse_pages;
2075 } 2097 }
2076 val->freeswap = nr_swap_pages + nr_to_be_unused; 2098 val->freeswap = nr_swap_pages + nr_to_be_unused;
2077 val->totalswap = total_swap_pages + nr_to_be_unused; 2099 val->totalswap = total_swap_pages + nr_to_be_unused;
@@ -2104,7 +2126,7 @@ static int __swap_duplicate(swp_entry_t entry, bool cache)
2104 type = swp_type(entry); 2126 type = swp_type(entry);
2105 if (type >= nr_swapfiles) 2127 if (type >= nr_swapfiles)
2106 goto bad_file; 2128 goto bad_file;
2107 p = type + swap_info; 2129 p = swap_info[type];
2108 offset = swp_offset(entry); 2130 offset = swp_offset(entry);
2109 2131
2110 spin_lock(&swap_lock); 2132 spin_lock(&swap_lock);
@@ -2186,7 +2208,7 @@ int valid_swaphandles(swp_entry_t entry, unsigned long *offset)
2186 if (!our_page_cluster) /* no readahead */ 2208 if (!our_page_cluster) /* no readahead */
2187 return 0; 2209 return 0;
2188 2210
2189 si = &swap_info[swp_type(entry)]; 2211 si = swap_info[swp_type(entry)];
2190 target = swp_offset(entry); 2212 target = swp_offset(entry);
2191 base = (target >> our_page_cluster) << our_page_cluster; 2213 base = (target >> our_page_cluster) << our_page_cluster;
2192 end = base + (1 << our_page_cluster); 2214 end = base + (1 << our_page_cluster);