aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2005-09-03 18:54:32 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:05:40 -0400
commite2244ec2efa4ee1edf391d0001d314933e2b2974 (patch)
treec9e43f9b6e11ce41d976025c6f9d94c273521132 /mm
parentb0d9bcd4bb79a7834f8492f2ae5c2655a551f23d (diff)
[PATCH] swap: correct swapfile nr_good_pages
If a regular swapfile lies on a filesystem whose blocksize is less than PAGE_SIZE, then setup_swap_extents may have to cut the number of usable swap pages; but sys_swapon's nr_good_pages was not expecting that. Also, setup_swap_extents takes no account of badpages listed in the swap header: not worth doing so, but ensure nr_badpages is 0 for a regular swapfile. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/swapfile.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 9f46d83b4ece..5ac5333f37a0 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1008,8 +1008,9 @@ reprobe:
1008 } 1008 }
1009 ret = 0; 1009 ret = 0;
1010 if (page_no == 0) 1010 if (page_no == 0)
1011 ret = -EINVAL; 1011 page_no = 1; /* force Empty message */
1012 sis->max = page_no; 1012 sis->max = page_no;
1013 sis->pages = page_no - 1;
1013 sis->highest_bit = page_no - 1; 1014 sis->highest_bit = page_no - 1;
1014done: 1015done:
1015 sis->curr_swap_extent = list_entry(sis->extent_list.prev, 1016 sis->curr_swap_extent = list_entry(sis->extent_list.prev,
@@ -1446,6 +1447,10 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1446 p->highest_bit = maxpages - 1; 1447 p->highest_bit = maxpages - 1;
1447 1448
1448 error = -EINVAL; 1449 error = -EINVAL;
1450 if (!maxpages)
1451 goto bad_swap;
1452 if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode))
1453 goto bad_swap;
1449 if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) 1454 if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
1450 goto bad_swap; 1455 goto bad_swap;
1451 1456
@@ -1470,25 +1475,27 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1470 if (error) 1475 if (error)
1471 goto bad_swap; 1476 goto bad_swap;
1472 } 1477 }
1473 1478
1474 if (swapfilesize && maxpages > swapfilesize) { 1479 if (swapfilesize && maxpages > swapfilesize) {
1475 printk(KERN_WARNING 1480 printk(KERN_WARNING
1476 "Swap area shorter than signature indicates\n"); 1481 "Swap area shorter than signature indicates\n");
1477 error = -EINVAL; 1482 error = -EINVAL;
1478 goto bad_swap; 1483 goto bad_swap;
1479 } 1484 }
1485 if (nr_good_pages) {
1486 p->swap_map[0] = SWAP_MAP_BAD;
1487 p->max = maxpages;
1488 p->pages = nr_good_pages;
1489 error = setup_swap_extents(p);
1490 if (error)
1491 goto bad_swap;
1492 nr_good_pages = p->pages;
1493 }
1480 if (!nr_good_pages) { 1494 if (!nr_good_pages) {
1481 printk(KERN_WARNING "Empty swap-file\n"); 1495 printk(KERN_WARNING "Empty swap-file\n");
1482 error = -EINVAL; 1496 error = -EINVAL;
1483 goto bad_swap; 1497 goto bad_swap;
1484 } 1498 }
1485 p->swap_map[0] = SWAP_MAP_BAD;
1486 p->max = maxpages;
1487 p->pages = nr_good_pages;
1488
1489 error = setup_swap_extents(p);
1490 if (error)
1491 goto bad_swap;
1492 1499
1493 down(&swapon_sem); 1500 down(&swapon_sem);
1494 swap_list_lock(); 1501 swap_list_lock();