Commit 21bd9005 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

mm: split swap_type_of



swap_type_of is used for two entirely different purposes:

 (1) check what swap type a given device/offset corresponds to
 (2) find the first available swap device that can be written to

Mixing both in a single function creates an unreadable mess.  Create two
separate functions instead, and switch both to pass a dev_t instead of
a struct block_device to further simplify the code.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent bb3247a3
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -467,7 +467,8 @@ extern int swapcache_prepare(swp_entry_t);
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 **);
int swap_type_of(dev_t device, sector_t offset);
int find_first_swap(dev_t *device);
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);
+8 −9
Original line number Diff line number Diff line
@@ -335,12 +335,17 @@ static int swsusp_swap_check(void)
{
	int res;

	res = swap_type_of(swsusp_resume_device, swsusp_resume_block,
			&hib_resume_bdev);
	if (swsusp_resume_device)
		res = swap_type_of(swsusp_resume_device, swsusp_resume_block);
	else
		res = find_first_swap(&swsusp_resume_device);
	if (res < 0)
		return res;

	root_swap = res;

	hib_resume_bdev = bdget(swsusp_resume_device);
	if (!hib_resume_bdev)
		return -ENOMEM;
	res = blkdev_get(hib_resume_bdev, FMODE_WRITE, NULL);
	if (res)
		return res;
@@ -349,12 +354,6 @@ static int swsusp_swap_check(void)
	if (res < 0)
		blkdev_put(hib_resume_bdev, FMODE_WRITE);

	/*
	 * Update the resume device to the one actually used,
	 * so the test_resume mode can use it in case it is
	 * invoked from hibernate() to test the snapshot.
	 */
	swsusp_resume_device = hib_resume_bdev->bd_dev;
	return res;
}

+4 −12
Original line number Diff line number Diff line
@@ -69,8 +69,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) {
		/* Hibernating.  The image device should be accessible. */
		data->swap = swsusp_resume_device ?
			swap_type_of(swsusp_resume_device, 0, NULL) : -1;
		data->swap = swap_type_of(swsusp_resume_device, 0);
		data->mode = O_RDONLY;
		data->free_bitmaps = false;
		error = __pm_notifier_call_chain(PM_HIBERNATION_PREPARE, -1, &nr_calls);
@@ -210,7 +209,6 @@ struct compat_resume_swap_area {
static int snapshot_set_swap_area(struct snapshot_data *data,
		void __user *argp)
{
	struct block_device *bdev;
	sector_t offset;
	dev_t swdev;

@@ -237,16 +235,10 @@ static int snapshot_set_swap_area(struct snapshot_data *data,
	 * User space encodes device types as two-byte values,
	 * so we need to recode them
	 */
	if (!swdev) {
		data->swap = -1;
		return -EINVAL;
	}
	data->swap = swap_type_of(swdev, offset, &bdev);
	data->swap = swap_type_of(swdev, offset);
	if (data->swap < 0)
		return -ENODEV;

	data->dev = bdev->bd_dev;
	bdput(bdev);
		return swdev ? -ENODEV : -EINVAL;
	data->dev = swdev;
	return 0;
}

+21 −18
Original line number Diff line number Diff line
@@ -1801,13 +1801,12 @@ int 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, struct block_device **bdev_p)
int swap_type_of(dev_t device, sector_t offset)
{
	struct block_device *bdev = NULL;
	int type;

	if (device)
		bdev = bdget(device);
	if (!device)
		return -1;

	spin_lock(&swap_lock);
	for (type = 0; type < nr_swapfiles; type++) {
@@ -1816,30 +1815,34 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
		if (!(sis->flags & SWP_WRITEOK))
			continue;

		if (!bdev) {
			if (bdev_p)
				*bdev_p = bdgrab(sis->bdev);

			spin_unlock(&swap_lock);
			return type;
		}
		if (bdev == sis->bdev) {
		if (device == sis->bdev->bd_dev) {
			struct swap_extent *se = first_se(sis);

			if (se->start_block == offset) {
				if (bdev_p)
					*bdev_p = bdgrab(sis->bdev);

				spin_unlock(&swap_lock);
				bdput(bdev);
				return type;
			}
		}
	}
	spin_unlock(&swap_lock);
	if (bdev)
		bdput(bdev);
	return -ENODEV;
}

int find_first_swap(dev_t *device)
{
	int type;

	spin_lock(&swap_lock);
	for (type = 0; type < nr_swapfiles; type++) {
		struct swap_info_struct *sis = swap_info[type];

		if (!(sis->flags & SWP_WRITEOK))
			continue;
		*device = sis->bdev->bd_dev;
		spin_unlock(&swap_lock);
		return type;
	}
	spin_unlock(&swap_lock);
	return -ENODEV;
}