diff options
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r-- | mm/swapfile.c | 146 |
1 files changed, 65 insertions, 81 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index c46c83d6aab0..85ff603385c3 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -1456,7 +1456,6 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) | |||
1456 | int i, prev; | 1456 | int i, prev; |
1457 | int error; | 1457 | int error; |
1458 | union swap_header *swap_header = NULL; | 1458 | union swap_header *swap_header = NULL; |
1459 | int swap_header_version; | ||
1460 | unsigned int nr_good_pages = 0; | 1459 | unsigned int nr_good_pages = 0; |
1461 | int nr_extents = 0; | 1460 | int nr_extents = 0; |
1462 | sector_t span; | 1461 | sector_t span; |
@@ -1553,101 +1552,86 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) | |||
1553 | error = PTR_ERR(page); | 1552 | error = PTR_ERR(page); |
1554 | goto bad_swap; | 1553 | goto bad_swap; |
1555 | } | 1554 | } |
1556 | kmap(page); | 1555 | swap_header = kmap(page); |
1557 | swap_header = page_address(page); | ||
1558 | 1556 | ||
1559 | if (!memcmp("SWAP-SPACE",swap_header->magic.magic,10)) | 1557 | if (memcmp("SWAPSPACE2", swap_header->magic.magic, 10)) { |
1560 | swap_header_version = 1; | ||
1561 | else if (!memcmp("SWAPSPACE2",swap_header->magic.magic,10)) | ||
1562 | swap_header_version = 2; | ||
1563 | else { | ||
1564 | printk(KERN_ERR "Unable to find swap-space signature\n"); | 1558 | printk(KERN_ERR "Unable to find swap-space signature\n"); |
1565 | error = -EINVAL; | 1559 | error = -EINVAL; |
1566 | goto bad_swap; | 1560 | goto bad_swap; |
1567 | } | 1561 | } |
1568 | 1562 | ||
1569 | switch (swap_header_version) { | 1563 | /* swap partition endianess hack... */ |
1570 | case 1: | 1564 | if (swab32(swap_header->info.version) == 1) { |
1571 | printk(KERN_ERR "version 0 swap is no longer supported. " | 1565 | swab32s(&swap_header->info.version); |
1572 | "Use mkswap -v1 %s\n", name); | 1566 | swab32s(&swap_header->info.last_page); |
1567 | swab32s(&swap_header->info.nr_badpages); | ||
1568 | for (i = 0; i < swap_header->info.nr_badpages; i++) | ||
1569 | swab32s(&swap_header->info.badpages[i]); | ||
1570 | } | ||
1571 | /* Check the swap header's sub-version */ | ||
1572 | if (swap_header->info.version != 1) { | ||
1573 | printk(KERN_WARNING | ||
1574 | "Unable to handle swap header version %d\n", | ||
1575 | swap_header->info.version); | ||
1573 | error = -EINVAL; | 1576 | error = -EINVAL; |
1574 | goto bad_swap; | 1577 | goto bad_swap; |
1575 | case 2: | 1578 | } |
1576 | /* swap partition endianess hack... */ | ||
1577 | if (swab32(swap_header->info.version) == 1) { | ||
1578 | swab32s(&swap_header->info.version); | ||
1579 | swab32s(&swap_header->info.last_page); | ||
1580 | swab32s(&swap_header->info.nr_badpages); | ||
1581 | for (i = 0; i < swap_header->info.nr_badpages; i++) | ||
1582 | swab32s(&swap_header->info.badpages[i]); | ||
1583 | } | ||
1584 | /* Check the swap header's sub-version and the size of | ||
1585 | the swap file and bad block lists */ | ||
1586 | if (swap_header->info.version != 1) { | ||
1587 | printk(KERN_WARNING | ||
1588 | "Unable to handle swap header version %d\n", | ||
1589 | swap_header->info.version); | ||
1590 | error = -EINVAL; | ||
1591 | goto bad_swap; | ||
1592 | } | ||
1593 | 1579 | ||
1594 | p->lowest_bit = 1; | 1580 | p->lowest_bit = 1; |
1595 | p->cluster_next = 1; | 1581 | p->cluster_next = 1; |
1596 | 1582 | ||
1597 | /* | 1583 | /* |
1598 | * Find out how many pages are allowed for a single swap | 1584 | * Find out how many pages are allowed for a single swap |
1599 | * device. There are two limiting factors: 1) the number of | 1585 | * device. There are two limiting factors: 1) the number of |
1600 | * bits for the swap offset in the swp_entry_t type and | 1586 | * bits for the swap offset in the swp_entry_t type and |
1601 | * 2) the number of bits in the a swap pte as defined by | 1587 | * 2) the number of bits in the a swap pte as defined by |
1602 | * the different architectures. In order to find the | 1588 | * the different architectures. In order to find the |
1603 | * largest possible bit mask a swap entry with swap type 0 | 1589 | * largest possible bit mask a swap entry with swap type 0 |
1604 | * and swap offset ~0UL is created, encoded to a swap pte, | 1590 | * and swap offset ~0UL is created, encoded to a swap pte, |
1605 | * decoded to a swp_entry_t again and finally the swap | 1591 | * decoded to a swp_entry_t again and finally the swap |
1606 | * offset is extracted. This will mask all the bits from | 1592 | * offset is extracted. This will mask all the bits from |
1607 | * the initial ~0UL mask that can't be encoded in either | 1593 | * the initial ~0UL mask that can't be encoded in either |
1608 | * the swp_entry_t or the architecture definition of a | 1594 | * the swp_entry_t or the architecture definition of a |
1609 | * swap pte. | 1595 | * swap pte. |
1610 | */ | 1596 | */ |
1611 | maxpages = swp_offset(pte_to_swp_entry(swp_entry_to_pte(swp_entry(0,~0UL)))) - 1; | 1597 | maxpages = swp_offset(pte_to_swp_entry( |
1612 | if (maxpages > swap_header->info.last_page) | 1598 | swp_entry_to_pte(swp_entry(0, ~0UL)))) - 1; |
1613 | maxpages = swap_header->info.last_page; | 1599 | if (maxpages > swap_header->info.last_page) |
1614 | p->highest_bit = maxpages - 1; | 1600 | maxpages = swap_header->info.last_page; |
1601 | p->highest_bit = maxpages - 1; | ||
1615 | 1602 | ||
1616 | error = -EINVAL; | 1603 | error = -EINVAL; |
1617 | if (!maxpages) | 1604 | if (!maxpages) |
1618 | goto bad_swap; | 1605 | goto bad_swap; |
1619 | if (swapfilepages && maxpages > swapfilepages) { | 1606 | if (swapfilepages && maxpages > swapfilepages) { |
1620 | printk(KERN_WARNING | 1607 | printk(KERN_WARNING |
1621 | "Swap area shorter than signature indicates\n"); | 1608 | "Swap area shorter than signature indicates\n"); |
1622 | goto bad_swap; | 1609 | goto bad_swap; |
1623 | } | 1610 | } |
1624 | if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode)) | 1611 | if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode)) |
1625 | goto bad_swap; | 1612 | goto bad_swap; |
1626 | if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) | 1613 | if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) |
1627 | goto bad_swap; | 1614 | goto bad_swap; |
1628 | 1615 | ||
1629 | /* OK, set up the swap map and apply the bad block list */ | 1616 | /* OK, set up the swap map and apply the bad block list */ |
1630 | swap_map = vmalloc(maxpages * sizeof(short)); | 1617 | swap_map = vmalloc(maxpages * sizeof(short)); |
1631 | if (!swap_map) { | 1618 | if (!swap_map) { |
1632 | error = -ENOMEM; | 1619 | error = -ENOMEM; |
1633 | goto bad_swap; | 1620 | goto bad_swap; |
1634 | } | 1621 | } |
1635 | 1622 | ||
1636 | error = 0; | 1623 | memset(swap_map, 0, maxpages * sizeof(short)); |
1637 | memset(swap_map, 0, maxpages * sizeof(short)); | 1624 | for (i = 0; i < swap_header->info.nr_badpages; i++) { |
1638 | for (i = 0; i < swap_header->info.nr_badpages; i++) { | 1625 | int page_nr = swap_header->info.badpages[i]; |
1639 | int page_nr = swap_header->info.badpages[i]; | 1626 | if (page_nr <= 0 || page_nr >= swap_header->info.last_page) { |
1640 | if (page_nr <= 0 || page_nr >= swap_header->info.last_page) | 1627 | error = -EINVAL; |
1641 | error = -EINVAL; | ||
1642 | else | ||
1643 | swap_map[page_nr] = SWAP_MAP_BAD; | ||
1644 | } | ||
1645 | nr_good_pages = swap_header->info.last_page - | ||
1646 | swap_header->info.nr_badpages - | ||
1647 | 1 /* header page */; | ||
1648 | if (error) | ||
1649 | goto bad_swap; | 1628 | goto bad_swap; |
1629 | } | ||
1630 | swap_map[page_nr] = SWAP_MAP_BAD; | ||
1650 | } | 1631 | } |
1632 | nr_good_pages = swap_header->info.last_page - | ||
1633 | swap_header->info.nr_badpages - | ||
1634 | 1 /* header page */; | ||
1651 | 1635 | ||
1652 | if (nr_good_pages) { | 1636 | if (nr_good_pages) { |
1653 | swap_map[0] = SWAP_MAP_BAD; | 1637 | swap_map[0] = SWAP_MAP_BAD; |