[PATCH 27/28] nfs: enable swap on NFS
Implement all the new swapfile a_ops for NFS. This will set the NFS socket to SOCK_MEMALLOC and run socket reconnect under PF_MEMALLOC as well as reset SOCK_MEMALLOC before engaging the protocol ->connect() method. PF_MEMALLOC should allow the allocation of struct socket and related objects and the early (re)setting of SOCK_MEMALLOC should allow us to receive the packets required for the TCP connection buildup. (swapping continues over a server reset during heavy network traffic) Signed-off-by: Peter Zijlstra <[EMAIL PROTECTED]> --- fs/Kconfig | 17 +++ fs/nfs/file.c | 12 fs/nfs/write.c | 19 + include/linux/nfs_fs.h |2 + include/linux/sunrpc/xprt.h |5 ++- net/sunrpc/sched.c |9 -- net/sunrpc/xprtsock.c | 63 7 files changed, 124 insertions(+), 3 deletions(-) Index: linux-2.6/fs/nfs/file.c === --- linux-2.6.orig/fs/nfs/file.c +++ linux-2.6/fs/nfs/file.c @@ -373,6 +373,13 @@ static int nfs_launder_page(struct page return nfs_wb_page(page_file_mapping(page)->host, page); } +#ifdef CONFIG_NFS_SWAP +static int nfs_swapfile(struct address_space *mapping, int enable) +{ + return xs_swapper(NFS_CLIENT(mapping->host)->cl_xprt, enable); +} +#endif + const struct address_space_operations nfs_file_aops = { .readpage = nfs_readpage, .readpages = nfs_readpages, @@ -387,6 +394,11 @@ const struct address_space_operations nf .direct_IO = nfs_direct_IO, #endif .launder_page = nfs_launder_page, +#ifdef CONFIG_NFS_SWAP + .swapfile = nfs_swapfile, + .swap_out = nfs_swap_out, + .swap_in = nfs_readpage, +#endif }; static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) Index: linux-2.6/fs/nfs/write.c === --- linux-2.6.orig/fs/nfs/write.c +++ linux-2.6/fs/nfs/write.c @@ -362,6 +362,25 @@ int nfs_writepage(struct page *page, str return ret; } +int nfs_swap_out(struct file *file, struct page *page, +struct writeback_control *wbc) +{ + struct nfs_open_context *ctx = nfs_file_open_context(file); + int status; + + status = nfs_writepage_setup(ctx, page, 0, nfs_page_length(page)); + if (status < 0) { + nfs_set_pageerror(page); + goto out; + } + + status = nfs_writepage_locked(page, wbc); + +out: + unlock_page(page); + return status; +} + static int nfs_writepages_callback(struct page *page, struct writeback_control *wbc, void *data) { int ret; Index: linux-2.6/include/linux/nfs_fs.h === --- linux-2.6.orig/include/linux/nfs_fs.h +++ linux-2.6/include/linux/nfs_fs.h @@ -453,6 +453,8 @@ extern int nfs_flush_incompatible(struc extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *); extern void nfs_writedata_release(void *); +extern int nfs_swap_out(struct file *file, struct page *page, +struct writeback_control *wbc); /* * Try to write back everything synchronously (but check the Index: linux-2.6/fs/Kconfig === --- linux-2.6.orig/fs/Kconfig +++ linux-2.6/fs/Kconfig @@ -1661,6 +1661,18 @@ config NFS_DIRECTIO causes open() to return EINVAL if a file residing in NFS is opened with the O_DIRECT flag. +config NFS_SWAP + bool "Provide swap over NFS support" + default n + depends on NFS_FS + select SUNRPC_SWAP + help + This option enables swapon to work on files located on NFS mounts. + + For more details, see Documentation/vm_deadlock.txt + + If unsure, say N. + config NFSD tristate "NFS server support" depends on INET @@ -1794,6 +1806,11 @@ config SUNRPC_BIND34 If unsure, say N to get traditional behavior (version 2 rpcbind requests only). +config SUNRPC_SWAP + def_bool n + depends on SUNRPC + select NETVM + config RPCSEC_GSS_KRB5 tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)" depends on SUNRPC && EXPERIMENTAL Index: linux-2.6/include/linux/sunrpc/xprt.h === --- linux-2.6.orig/include/linux/sunrpc/xprt.h +++ linux-2.6/include/linux/sunrpc/xprt.h @@ -143,7 +143,9 @@ struct rpc_xprt { unsigned intmax_reqs; /* total slots */ unsigned long state; /* transport state */ unsigned char shutdown : 1, /* being shut down */ - resvport : 1; /* use a reserved port */ +
[PATCH 27/28] nfs: enable swap on NFS
Implement all the new swapfile a_ops for NFS. This will set the NFS socket to SOCK_MEMALLOC and run socket reconnect under PF_MEMALLOC as well as reset SOCK_MEMALLOC before engaging the protocol -connect() method. PF_MEMALLOC should allow the allocation of struct socket and related objects and the early (re)setting of SOCK_MEMALLOC should allow us to receive the packets required for the TCP connection buildup. (swapping continues over a server reset during heavy network traffic) Signed-off-by: Peter Zijlstra [EMAIL PROTECTED] --- fs/Kconfig | 17 +++ fs/nfs/file.c | 12 fs/nfs/write.c | 19 + include/linux/nfs_fs.h |2 + include/linux/sunrpc/xprt.h |5 ++- net/sunrpc/sched.c |9 -- net/sunrpc/xprtsock.c | 63 7 files changed, 124 insertions(+), 3 deletions(-) Index: linux-2.6/fs/nfs/file.c === --- linux-2.6.orig/fs/nfs/file.c +++ linux-2.6/fs/nfs/file.c @@ -373,6 +373,13 @@ static int nfs_launder_page(struct page return nfs_wb_page(page_file_mapping(page)-host, page); } +#ifdef CONFIG_NFS_SWAP +static int nfs_swapfile(struct address_space *mapping, int enable) +{ + return xs_swapper(NFS_CLIENT(mapping-host)-cl_xprt, enable); +} +#endif + const struct address_space_operations nfs_file_aops = { .readpage = nfs_readpage, .readpages = nfs_readpages, @@ -387,6 +394,11 @@ const struct address_space_operations nf .direct_IO = nfs_direct_IO, #endif .launder_page = nfs_launder_page, +#ifdef CONFIG_NFS_SWAP + .swapfile = nfs_swapfile, + .swap_out = nfs_swap_out, + .swap_in = nfs_readpage, +#endif }; static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) Index: linux-2.6/fs/nfs/write.c === --- linux-2.6.orig/fs/nfs/write.c +++ linux-2.6/fs/nfs/write.c @@ -362,6 +362,25 @@ int nfs_writepage(struct page *page, str return ret; } +int nfs_swap_out(struct file *file, struct page *page, +struct writeback_control *wbc) +{ + struct nfs_open_context *ctx = nfs_file_open_context(file); + int status; + + status = nfs_writepage_setup(ctx, page, 0, nfs_page_length(page)); + if (status 0) { + nfs_set_pageerror(page); + goto out; + } + + status = nfs_writepage_locked(page, wbc); + +out: + unlock_page(page); + return status; +} + static int nfs_writepages_callback(struct page *page, struct writeback_control *wbc, void *data) { int ret; Index: linux-2.6/include/linux/nfs_fs.h === --- linux-2.6.orig/include/linux/nfs_fs.h +++ linux-2.6/include/linux/nfs_fs.h @@ -453,6 +453,8 @@ extern int nfs_flush_incompatible(struc extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *); extern void nfs_writedata_release(void *); +extern int nfs_swap_out(struct file *file, struct page *page, +struct writeback_control *wbc); /* * Try to write back everything synchronously (but check the Index: linux-2.6/fs/Kconfig === --- linux-2.6.orig/fs/Kconfig +++ linux-2.6/fs/Kconfig @@ -1661,6 +1661,18 @@ config NFS_DIRECTIO causes open() to return EINVAL if a file residing in NFS is opened with the O_DIRECT flag. +config NFS_SWAP + bool Provide swap over NFS support + default n + depends on NFS_FS + select SUNRPC_SWAP + help + This option enables swapon to work on files located on NFS mounts. + + For more details, see Documentation/vm_deadlock.txt + + If unsure, say N. + config NFSD tristate NFS server support depends on INET @@ -1794,6 +1806,11 @@ config SUNRPC_BIND34 If unsure, say N to get traditional behavior (version 2 rpcbind requests only). +config SUNRPC_SWAP + def_bool n + depends on SUNRPC + select NETVM + config RPCSEC_GSS_KRB5 tristate Secure RPC: Kerberos V mechanism (EXPERIMENTAL) depends on SUNRPC EXPERIMENTAL Index: linux-2.6/include/linux/sunrpc/xprt.h === --- linux-2.6.orig/include/linux/sunrpc/xprt.h +++ linux-2.6/include/linux/sunrpc/xprt.h @@ -143,7 +143,9 @@ struct rpc_xprt { unsigned intmax_reqs; /* total slots */ unsigned long state; /* transport state */ unsigned char shutdown : 1, /* being shut down */ - resvport : 1; /* use a reserved port */ +