Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7bf236874292fd073c6bdd27f89c3d9e81a79cbc
Commit:     7bf236874292fd073c6bdd27f89c3d9e81a79cbc
Parent:     3223ea8cca5936b8e78450dd5b8ba88372e9c0a8
Author:     Rafael J. Wysocki <[EMAIL PROTECTED]>
AuthorDate: Fri Jan 5 16:36:28 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Fri Jan 5 23:55:22 2007 -0800

    [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 <[EMAIL PROTECTED]>
    Acked-by: Pavel Machek <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 include/linux/swap.h |    2 +-
 kernel/power/swap.c  |    9 +++++----
 kernel/power/user.c  |    7 ++++---
 mm/swapfile.c        |    8 +++++++-
 4 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index add51ce..5423559 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -245,7 +245,7 @@ extern int swap_duplicate(swp_entry_t);
 extern int valid_swaphandles(swp_entry_t, unsigned long *);
 extern void swap_free(swp_entry_t);
 extern void free_swap_and_cache(swp_entry_t);
-extern int swap_type_of(dev_t, sector_t);
+extern int swap_type_of(dev_t, sector_t, struct block_device **);
 extern unsigned int count_swap_pages(int, int);
 extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t);
 extern sector_t swapdev_block(int, pgoff_t);
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index f133d4a..3581f8f 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 */
 {
        int res;
 
-       res = swap_type_of(swsusp_resume_device, swsusp_resume_block);
+       res = swap_type_of(swsusp_resume_device, swsusp_resume_block,
+                       &resume_bdev);
        if (res < 0)
                return res;
 
        root_swap = res;
-       resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_WRITE);
-       if (IS_ERR(resume_bdev))
-               return PTR_ERR(resume_bdev);
+       res = blkdev_get(resume_bdev, FMODE_WRITE, O_RDWR);
+       if (res)
+               return res;
 
        res = set_blocksize(resume_bdev, PAGE_SIZE);
        if (res < 0)
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 89443b8..f7b7a78 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)
        memset(&data->handle, 0, sizeof(struct snapshot_handle));
        if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
                data->swap = swsusp_resume_device ?
-                               swap_type_of(swsusp_resume_device, 0) : -1;
+                       swap_type_of(swsusp_resume_device, 0, NULL) : -1;
                data->mode = O_RDONLY;
        } else {
                data->swap = -1;
@@ -268,7 +268,8 @@ static int snapshot_ioctl(struct inode *inode, struct file 
*filp,
                         * so we need to recode them
                         */
                        if (old_decode_dev(arg)) {
-                               data->swap = swap_type_of(old_decode_dev(arg), 
0);
+                               data->swap = swap_type_of(old_decode_dev(arg),
+                                                       0, NULL);
                                if (data->swap < 0)
                                        error = -ENODEV;
                        } else {
@@ -365,7 +366,7 @@ static int snapshot_ioctl(struct inode *inode, struct file 
*filp,
                        swdev = old_decode_dev(swap_area.dev);
                        if (swdev) {
                                offset = swap_area.offset;
-                               data->swap = swap_type_of(swdev, offset);
+                               data->swap = swap_type_of(swdev, offset, NULL);
                                if (data->swap < 0)
                                        error = -ENODEV;
                        } else {
diff --git a/mm/swapfile.c b/mm/swapfile.c
index b9fc0e5..a2d9bb4 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -434,7 +434,7 @@ void free_swap_and_cache(swp_entry_t entry)
  *
  * This is needed for the suspend to disk (aka swsusp).
  */
-int swap_type_of(dev_t device, sector_t offset)
+int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
 {
        struct block_device *bdev = NULL;
        int i;
@@ -450,6 +450,9 @@ int swap_type_of(dev_t device, sector_t offset)
                        continue;
 
                if (!bdev) {
+                       if (bdev_p)
+                               *bdev_p = sis->bdev;
+
                        spin_unlock(&swap_lock);
                        return i;
                }
@@ -459,6 +462,9 @@ int swap_type_of(dev_t device, sector_t offset)
                        se = list_entry(sis->extent_list.next,
                                        struct swap_extent, list);
                        if (se->start_block == offset) {
+                               if (bdev_p)
+                                       *bdev_p = sis->bdev;
+
                                spin_unlock(&swap_lock);
                                bdput(bdev);
                                return i;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to