patch exist, please apply for ubuntu 20.04:
marian@kubuntu2004:~/kernelubuntu/linux$ git diff diff --git a/include/linux/swap.h b/include/linux/swap.h index de2c67a33b7e..da1dc5a338cc 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -456,6 +456,7 @@ extern void swap_free(swp_entry_t); extern void swapcache_free_entries(swp_entry_t *entries, int n); extern int free_swap_and_cache(swp_entry_t); extern int swap_type_of(dev_t, sector_t, struct block_device **); +extern void swap_relockall(void); extern unsigned int count_swap_pages(int, int); extern sector_t map_swap_page(struct page *, struct block_device **); extern sector_t swapdev_block(int, pgoff_t); diff --git a/kernel/power/user.c b/kernel/power/user.c index 77438954cc2b..bfef2097edaa 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -271,6 +271,8 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, break; } error = hibernation_restore(data->platform_support); + if (!error) + swap_relockall(); break;
case SNAPSHOT_FREE: @@ -372,10 +374,16 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, */ swdev = new_decode_dev(swap_area.dev); if (swdev) { + struct block_device *bd; offset = swap_area.offset; - data->swap = swap_type_of(swdev, offset, NULL); + data->swap = swap_type_of(swdev, offset, &bd); if (data->swap < 0) error = -ENODEV; + + inode_lock(bd->bd_inode); + bd->bd_inode->i_flags &= ~S_SWAPFILE; + inode_unlock(bd->bd_inode); + bdput(bd); } else { data->swap = -1; error = -EINVAL; diff --git a/mm/swapfile.c b/mm/swapfile.c index dab43523afdd..c7c83d3a313b 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1799,6 +1799,32 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) return -ENODEV; }
+/* Re-lock swap devices after resuming from userspace suspend. */ +void swap_relockall(void) +{ + int type; + + spin_lock(&swap_lock); + for (type = 0; type < nr_swapfiles; type++) { + struct swap_info_struct *sis = swap_info[type]; + struct block_device *bdev = bdgrab(sis->bdev); + + /* + * uswsusp only knows how to suspend to block devices, so we + * can skip swap files. + */ + if (!(sis->flags & SWP_WRITEOK) || + !(sis->flags & SWP_BLKDEV)) + continue; + + inode_lock(bdev->bd_inode); + bdev->bd_inode->i_flags |= S_SWAPFILE; + inode_unlock(bdev->bd_inode); + bdput(bdev); + } + spin_unlock(&swap_lock); +} + /* * Get the (PAGE_SIZE) block corresponding to given offset on the swapdev * corresponding to given index in swap_info (swap type).
patch exist, please apply for ubuntu 20.04:
marian@ kubuntu2004: ~/kernelubuntu/ linux$ git diff linux/swap. h b/include/ linux/swap. h .da1dc5a338cc 100644 linux/swap. h linux/swap. h swp_entry_ t); free_entries( swp_entry_ t *entries, int n); and_cache( swp_entry_ t); void); pages(int, int); page(struct page *, struct block_device **); power/user. c b/kernel/ power/user. c .bfef2097edaa 100644 power/user. c power/user. c ioctl(struct file *filp, unsigned int cmd,
break;
error = hibernation_ restore( data->platform_ support) ;
break;
diff --git a/include/
index de2c67a33b7e.
--- a/include/
+++ b/include/
@@ -456,6 +456,7 @@ extern void swap_free(
extern void swapcache_
extern int free_swap_
extern int swap_type_of(dev_t, sector_t, struct block_device **);
+extern void swap_relockall(
extern unsigned int count_swap_
extern sector_t map_swap_
extern sector_t swapdev_block(int, pgoff_t);
diff --git a/kernel/
index 77438954cc2b.
--- a/kernel/
+++ b/kernel/
@@ -271,6 +271,8 @@ static long snapshot_
}
+ if (!error)
+ swap_relockall();
case SNAPSHOT_FREE: ioctl(struct file *filp, unsigned int cmd,
*/
swdev = new_decode_ dev(swap_ area.dev) ;
if (swdev) {
offset = swap_area.offset;
if (data->swap < 0)
error = -ENODEV; bd->bd_ inode); inode-> i_flags &= ~S_SWAPFILE; bd->bd_ inode);
} else {
data- >swap = -1;
error = -EINVAL; .c7c83d3a313b 100644
@@ -372,10 +374,16 @@ static long snapshot_
+ struct block_device *bd;
- data->swap = swap_type_of(swdev, offset, NULL);
+ data->swap = swap_type_of(swdev, offset, &bd);
+
+ inode_lock(
+ bd->bd_
+ inode_unlock(
+ bdput(bd);
diff --git a/mm/swapfile.c b/mm/swapfile.c
index dab43523afdd.
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1799,6 +1799,32 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
return -ENODEV;
}
+/* Re-lock swap devices after resuming from userspace suspend. */ void) &swap_lock) ; bdev->bd_ inode); inode-> i_flags |= S_SWAPFILE; bdev->bd_ inode); &swap_lock) ;
+void swap_relockall(
+{
+ int type;
+
+ spin_lock(
+ for (type = 0; type < nr_swapfiles; type++) {
+ struct swap_info_struct *sis = swap_info[type];
+ struct block_device *bdev = bdgrab(sis->bdev);
+
+ /*
+ * uswsusp only knows how to suspend to block devices, so we
+ * can skip swap files.
+ */
+ if (!(sis->flags & SWP_WRITEOK) ||
+ !(sis->flags & SWP_BLKDEV))
+ continue;
+
+ inode_lock(
+ bdev->bd_
+ inode_unlock(
+ bdput(bdev);
+ }
+ spin_unlock(
+}
+
/*
* Get the (PAGE_SIZE) block corresponding to given offset on the swapdev
* corresponding to given index in swap_info (swap type).