aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/swapfile.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 187a21f8b7bd..4a986127f15e 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1760,11 +1760,11 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1760 unsigned int type; 1760 unsigned int type;
1761 int i, prev; 1761 int i, prev;
1762 int error; 1762 int error;
1763 union swap_header *swap_header = NULL; 1763 union swap_header *swap_header;
1764 unsigned int nr_good_pages = 0; 1764 unsigned int nr_good_pages;
1765 int nr_extents = 0; 1765 int nr_extents = 0;
1766 sector_t span; 1766 sector_t span;
1767 unsigned long maxpages = 1; 1767 unsigned long maxpages;
1768 unsigned long swapfilepages; 1768 unsigned long swapfilepages;
1769 unsigned char *swap_map = NULL; 1769 unsigned char *swap_map = NULL;
1770 struct page *page = NULL; 1770 struct page *page = NULL;
@@ -1923,9 +1923,13 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1923 * swap pte. 1923 * swap pte.
1924 */ 1924 */
1925 maxpages = swp_offset(pte_to_swp_entry( 1925 maxpages = swp_offset(pte_to_swp_entry(
1926 swp_entry_to_pte(swp_entry(0, ~0UL)))) - 1; 1926 swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1;
1927 if (maxpages > swap_header->info.last_page) 1927 if (maxpages > swap_header->info.last_page) {
1928 maxpages = swap_header->info.last_page; 1928 maxpages = swap_header->info.last_page + 1;
1929 /* p->max is an unsigned int: don't overflow it */
1930 if ((unsigned int)maxpages == 0)
1931 maxpages = UINT_MAX;
1932 }
1929 p->highest_bit = maxpages - 1; 1933 p->highest_bit = maxpages - 1;
1930 1934
1931 error = -EINVAL; 1935 error = -EINVAL;
@@ -1949,23 +1953,24 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1949 } 1953 }
1950 1954
1951 memset(swap_map, 0, maxpages); 1955 memset(swap_map, 0, maxpages);
1956 nr_good_pages = maxpages - 1; /* omit header page */
1957
1952 for (i = 0; i < swap_header->info.nr_badpages; i++) { 1958 for (i = 0; i < swap_header->info.nr_badpages; i++) {
1953 int page_nr = swap_header->info.badpages[i]; 1959 unsigned int page_nr = swap_header->info.badpages[i];
1954 if (page_nr <= 0 || page_nr >= swap_header->info.last_page) { 1960 if (page_nr == 0 || page_nr > swap_header->info.last_page) {
1955 error = -EINVAL; 1961 error = -EINVAL;
1956 goto bad_swap; 1962 goto bad_swap;
1957 } 1963 }
1958 swap_map[page_nr] = SWAP_MAP_BAD; 1964 if (page_nr < maxpages) {
1965 swap_map[page_nr] = SWAP_MAP_BAD;
1966 nr_good_pages--;
1967 }
1959 } 1968 }
1960 1969
1961 error = swap_cgroup_swapon(type, maxpages); 1970 error = swap_cgroup_swapon(type, maxpages);
1962 if (error) 1971 if (error)
1963 goto bad_swap; 1972 goto bad_swap;
1964 1973
1965 nr_good_pages = swap_header->info.last_page -
1966 swap_header->info.nr_badpages -
1967 1 /* header page */;
1968
1969 if (nr_good_pages) { 1974 if (nr_good_pages) {
1970 swap_map[0] = SWAP_MAP_BAD; 1975 swap_map[0] = SWAP_MAP_BAD;
1971 p->max = maxpages; 1976 p->max = maxpages;