aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-01-05 19:36:28 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:22 -0500
commit7bf236874292fd073c6bdd27f89c3d9e81a79cbc (patch)
tree27e4196e4b720c113010d544567f76f181c11428
parent3223ea8cca5936b8e78450dd5b8ba88372e9c0a8 (diff)
[PATCH] swsusp: Do not fail if resume device is not set
In the kernels later than 2.6.19 there is a regression that makes swsusp fail if the resume device is not explicitly specified. It can be fixed by adding an additional parameter to mm/swapfile.c:swap_type_of() allowing us to pass the (struct block_device *) corresponding to the first available swap back to the caller. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--include/linux/swap.h2
-rw-r--r--kernel/power/swap.c9
-rw-r--r--kernel/power/user.c7
-rw-r--r--mm/swapfile.c8
4 files changed, 17 insertions, 9 deletions
diff --git a/include/linux/swap.h b/include/linux/swap.h
index add51cebc8d9..5423559a44a6 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -245,7 +245,7 @@ extern int swap_duplicate(swp_entry_t);
245extern int valid_swaphandles(swp_entry_t, unsigned long *); 245extern int valid_swaphandles(swp_entry_t, unsigned long *);
246extern void swap_free(swp_entry_t); 246extern void swap_free(swp_entry_t);
247extern void free_swap_and_cache(swp_entry_t); 247extern void free_swap_and_cache(swp_entry_t);
248extern int swap_type_of(dev_t, sector_t); 248extern int swap_type_of(dev_t, sector_t, struct block_device **);
249extern unsigned int count_swap_pages(int, int); 249extern unsigned int count_swap_pages(int, int);
250extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t); 250extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t);
251extern sector_t swapdev_block(int, pgoff_t); 251extern sector_t swapdev_block(int, pgoff_t);
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index f133d4a6d817..3581f8f86acd 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -165,14 +165,15 @@ static int swsusp_swap_check(void) /* This is called before saving image */
165{ 165{
166 int res; 166 int res;
167 167
168 res = swap_type_of(swsusp_resume_device, swsusp_resume_block); 168 res = swap_type_of(swsusp_resume_device, swsusp_resume_block,
169 &resume_bdev);
169 if (res < 0) 170 if (res < 0)
170 return res; 171 return res;
171 172
172 root_swap = res; 173 root_swap = res;
173 resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_WRITE); 174 res = blkdev_get(resume_bdev, FMODE_WRITE, O_RDWR);
174 if (IS_ERR(resume_bdev)) 175 if (res)
175 return PTR_ERR(resume_bdev); 176 return res;
176 177
177 res = set_blocksize(resume_bdev, PAGE_SIZE); 178 res = set_blocksize(resume_bdev, PAGE_SIZE);
178 if (res < 0) 179 if (res < 0)
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 89443b85163b..f7b7a785a5c6 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -57,7 +57,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
57 memset(&data->handle, 0, sizeof(struct snapshot_handle)); 57 memset(&data->handle, 0, sizeof(struct snapshot_handle));
58 if ((filp->f_flags & O_ACCMODE) == O_RDONLY) { 58 if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
59 data->swap = swsusp_resume_device ? 59 data->swap = swsusp_resume_device ?
60 swap_type_of(swsusp_resume_device, 0) : -1; 60 swap_type_of(swsusp_resume_device, 0, NULL) : -1;
61 data->mode = O_RDONLY; 61 data->mode = O_RDONLY;
62 } else { 62 } else {
63 data->swap = -1; 63 data->swap = -1;
@@ -268,7 +268,8 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
268 * so we need to recode them 268 * so we need to recode them
269 */ 269 */
270 if (old_decode_dev(arg)) { 270 if (old_decode_dev(arg)) {
271 data->swap = swap_type_of(old_decode_dev(arg), 0); 271 data->swap = swap_type_of(old_decode_dev(arg),
272 0, NULL);
272 if (data->swap < 0) 273 if (data->swap < 0)
273 error = -ENODEV; 274 error = -ENODEV;
274 } else { 275 } else {
@@ -365,7 +366,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
365 swdev = old_decode_dev(swap_area.dev); 366 swdev = old_decode_dev(swap_area.dev);
366 if (swdev) { 367 if (swdev) {
367 offset = swap_area.offset; 368 offset = swap_area.offset;
368 data->swap = swap_type_of(swdev, offset); 369 data->swap = swap_type_of(swdev, offset, NULL);
369 if (data->swap < 0) 370 if (data->swap < 0)
370 error = -ENODEV; 371 error = -ENODEV;
371 } else { 372 } else {
diff --git a/mm/swapfile.c b/mm/swapfile.c
index b9fc0e5de6d5..a2d9bb4e80df 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -434,7 +434,7 @@ void free_swap_and_cache(swp_entry_t entry)
434 * 434 *
435 * This is needed for the suspend to disk (aka swsusp). 435 * This is needed for the suspend to disk (aka swsusp).
436 */ 436 */
437int swap_type_of(dev_t device, sector_t offset) 437int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
438{ 438{
439 struct block_device *bdev = NULL; 439 struct block_device *bdev = NULL;
440 int i; 440 int i;
@@ -450,6 +450,9 @@ int swap_type_of(dev_t device, sector_t offset)
450 continue; 450 continue;
451 451
452 if (!bdev) { 452 if (!bdev) {
453 if (bdev_p)
454 *bdev_p = sis->bdev;
455
453 spin_unlock(&swap_lock); 456 spin_unlock(&swap_lock);
454 return i; 457 return i;
455 } 458 }
@@ -459,6 +462,9 @@ int swap_type_of(dev_t device, sector_t offset)
459 se = list_entry(sis->extent_list.next, 462 se = list_entry(sis->extent_list.next,
460 struct swap_extent, list); 463 struct swap_extent, list);
461 if (se->start_block == offset) { 464 if (se->start_block == offset) {
465 if (bdev_p)
466 *bdev_p = sis->bdev;
467
462 spin_unlock(&swap_lock); 468 spin_unlock(&swap_lock);
463 bdput(bdev); 469 bdput(bdev);
464 return i; 470 return i;