diff options
Diffstat (limited to '')
-rw-r--r-- | mm/swapfile.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index e52f486834..022581ec40 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2530,11 +2530,10 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) exit_swap_address_space(p->type); inode = mapping->host; - if (S_ISBLK(inode->i_mode)) { - struct block_device *bdev = I_BDEV(inode); - - set_blocksize(bdev, old_block_size); - blkdev_put(bdev, p); + if (p->bdev_handle) { + set_blocksize(p->bdev, old_block_size); + bdev_release(p->bdev_handle); + p->bdev_handle = NULL; } inode_lock(inode); @@ -2764,13 +2763,14 @@ static int claim_swapfile(struct swap_info_struct *p, struct inode *inode) int error; if (S_ISBLK(inode->i_mode)) { - p->bdev = blkdev_get_by_dev(inode->i_rdev, + p->bdev_handle = bdev_open_by_dev(inode->i_rdev, BLK_OPEN_READ | BLK_OPEN_WRITE, p, NULL); - if (IS_ERR(p->bdev)) { - error = PTR_ERR(p->bdev); - p->bdev = NULL; + if (IS_ERR(p->bdev_handle)) { + error = PTR_ERR(p->bdev_handle); + p->bdev_handle = NULL; return error; } + p->bdev = p->bdev_handle->bdev; p->old_block_size = block_size(p->bdev); error = set_blocksize(p->bdev, PAGE_SIZE); if (error < 0) @@ -3206,9 +3206,10 @@ bad_swap: p->percpu_cluster = NULL; free_percpu(p->cluster_next_cpu); p->cluster_next_cpu = NULL; - if (inode && S_ISBLK(inode->i_mode) && p->bdev) { + if (p->bdev_handle) { set_blocksize(p->bdev, p->old_block_size); - blkdev_put(p->bdev, p); + bdev_release(p->bdev_handle); + p->bdev_handle = NULL; } inode = NULL; destroy_swap_extents(p); @@ -3362,6 +3363,19 @@ int swapcache_prepare(swp_entry_t entry) return __swap_duplicate(entry, SWAP_HAS_CACHE); } +void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry) +{ + struct swap_cluster_info *ci; + unsigned long offset = swp_offset(entry); + unsigned char usage; + + ci = lock_cluster_or_swap_info(si, offset); + usage = __swap_entry_free_locked(si, offset, SWAP_HAS_CACHE); + unlock_cluster_or_swap_info(si, ci); + if (!usage) + free_swap_slot(entry); +} + struct swap_info_struct *swp_swap_info(swp_entry_t entry) { return swap_type_to_swap_info(swp_type(entry)); |