Commit 4b60c0ff authored by NeilBrown's avatar NeilBrown Committed by Andrew Morton
Browse files

mm: move responsibility for setting SWP_FS_OPS to ->swap_activate

If a filesystem wishes to handle all swap IO itself (via ->direct_IO and
->readpage), rather than just providing devices addresses for
submit_bio(), SWP_FS_OPS must be set.

Currently the protocol for setting this it to have ->swap_activate return
zero.  In that case SWP_FS_OPS is set, and add_swap_extent() is called for
the entire file.

This is a little clumsy as different return values for ->swap_activate
have quite different meanings, and it makes it hard to search for which
filesystems require SWP_FS_OPS to be set.

So remove the special meaning of a zero return, and require the filesystem
to set SWP_FS_OPS if it so desires, and to always call add_swap_extent()
as required.

Currently only NFS and CIFS return zero for add_swap_extent().

Link: https://lkml.kernel.org/r/164859778123.29473.17908205846599043598.stgit@noble.brown


Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Tested-by: default avatarDavid Howells <dhowells@redhat.com>
Tested-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Cc: Hugh Dickins <hughd@google.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Trond Myklebust <trond.myklebust@hammerspace.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 4c4a7634
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -4933,7 +4933,8 @@ static int cifs_swap_activate(struct swap_info_struct *sis,
	 * from reading or writing the file
	 */

	return 0;
	sis->flags |= SWP_FS_OPS;
	return add_swap_extent(sis, 0, sis->max, 0);
}

static void cifs_swap_deactivate(struct file *file)
+12 −2
Original line number Diff line number Diff line
@@ -483,6 +483,7 @@ static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
{
	unsigned long blocks;
	long long isize;
	int ret;
	struct inode *inode = file_inode(file);
	struct rpc_clnt *clnt = NFS_CLIENT(inode);
	struct nfs_client *cl = NFS_SERVER(inode)->nfs_client;
@@ -496,13 +497,22 @@ static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
		return -EINVAL;
	}

	*span = sis->pages;
	ret = rpc_clnt_swap_activate(clnt);
	if (ret)
		return ret;
	ret = add_swap_extent(sis, 0, sis->max, 0);
	if (ret < 0) {
		rpc_clnt_swap_deactivate(clnt);
		return ret;
	}

	*span = sis->pages;

	if (cl->rpc_ops->enable_swap)
		cl->rpc_ops->enable_swap(inode);

	return rpc_clnt_swap_activate(clnt);
	sis->flags |= SWP_FS_OPS;
	return ret;
}

static void nfs_swap_deactivate(struct file *file)
+6 −0
Original line number Diff line number Diff line
@@ -577,6 +577,12 @@ static inline swp_entry_t get_swap_page(struct page *page)
	return entry;
}

static inline int add_swap_extent(struct swap_info_struct *sis,
				  unsigned long start_page,
				  unsigned long nr_pages, sector_t start_block)
{
	return -EINVAL;
}
#endif /* CONFIG_SWAP */

#ifdef CONFIG_THP_SWAP
+3 −7
Original line number Diff line number Diff line
@@ -2259,13 +2259,9 @@ static int setup_swap_extents(struct swap_info_struct *sis, sector_t *span)

	if (mapping->a_ops->swap_activate) {
		ret = mapping->a_ops->swap_activate(sis, swap_file, span);
		if (ret >= 0)
		if (ret < 0)
			return ret;
		sis->flags |= SWP_ACTIVATED;
		if (!ret) {
			sis->flags |= SWP_FS_OPS;
			ret = add_swap_extent(sis, 0, sis->max, 0);
			*span = sis->pages;
		}
		return ret;
	}