From: Bryan Schumaker <[email protected]>
This is the final set of patches to turn NFS into modules. The first patch
creates an "nfs_subversion" structure that will represent a single NFS
version. The next 6 patches are cleanups that the nfs_subversion structure
allows us to put in. Finally, the last 3 patches convert v2, v3 and v4 into
kernel modules.
Changes in version 2:
- Add a patch to keep nfs4 module parameters in the generic client. Without
this we break backwards compatibility with older kernels.
- Bryan
Bryan Schumaker (10):
NFS: Add version registering framework
NFS: Remove the NFS v4 xdev mount function
NFS: Create a try_mount rpc op
NFS: Only initialize the ACL client in the v3 case
NFS: Pass super operations and xattr handlers in the nfs_subversion
NFS: Split out remaining NFS v4 inode functions
NFS: Keep module parameters in the generic NFS client
NFS: Convert v2 into a module
NFS: Convert v3 into a module
NFS: Convert v4 into a module
fs/nfs/Kconfig | 6 +-
fs/nfs/Makefile | 27 +++----
fs/nfs/callback.c | 24 ------
fs/nfs/callback.h | 2 +-
fs/nfs/client.c | 191 +++++++++++++++++++++++++---------------------
fs/nfs/delegation.h | 2 +-
fs/nfs/dir.c | 20 ++++-
fs/nfs/direct.c | 2 +-
fs/nfs/dns_resolve.c | 4 +
fs/nfs/file.c | 15 ++++
fs/nfs/idmap.c | 3 -
fs/nfs/inode.c | 105 ++++++++++++-------------
fs/nfs/internal.h | 38 +++++----
fs/nfs/namespace.c | 17 +----
fs/nfs/netns.h | 2 +-
fs/nfs/nfs.h | 29 +++++++
fs/nfs/nfs2super.c | 31 ++++++++
fs/nfs/nfs3client.c | 65 ++++++++++++++++
fs/nfs/nfs3proc.c | 3 +
fs/nfs/nfs3super.c | 31 ++++++++
fs/nfs/nfs4_fs.h | 13 ++--
fs/nfs/nfs4client.c | 23 ++----
fs/nfs/nfs4proc.c | 9 +--
fs/nfs/nfs4super.c | 106 +++++++++++++------------
fs/nfs/nfs4xdr.c | 6 --
fs/nfs/pagelist.c | 4 +
fs/nfs/pnfs.c | 2 +
fs/nfs/proc.c | 3 +
fs/nfs/read.c | 5 ++
fs/nfs/super.c | 172 ++++++++++++++++++++++++++++-------------
fs/nfs/write.c | 35 +++------
include/linux/nfs_fs.h | 6 +-
include/linux/nfs_fs_sb.h | 7 +-
include/linux/nfs_idmap.h | 2 +-
include/linux/nfs_xdr.h | 9 ++-
35 files changed, 632 insertions(+), 387 deletions(-)
create mode 100644 fs/nfs/nfs.h
create mode 100644 fs/nfs/nfs2super.c
create mode 100644 fs/nfs/nfs3client.c
create mode 100644 fs/nfs/nfs3super.c
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
This patch exports symbols needed by the v4 module. In addition, I also
switch over to using IS_ENABLED() to check if CONFIG_NFS_V4 or
CONFIG_NFS_V4_MODULE are set.
The module (nfs4.ko) will be created in the same directory as nfs.ko and
will be automatically loaded the first time you try to mount over NFS v4.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Kconfig | 2 +-
fs/nfs/Makefile | 19 ++++++--------
fs/nfs/callback.h | 2 +-
fs/nfs/client.c | 34 +++++++++++--------------
fs/nfs/delegation.h | 2 +-
fs/nfs/dir.c | 6 ++++-
fs/nfs/direct.c | 2 +-
fs/nfs/dns_resolve.c | 4 +++
fs/nfs/file.c | 13 ++++++++++
fs/nfs/inode.c | 64 +++++++++++++++++++++++------------------------
fs/nfs/internal.h | 8 +++---
fs/nfs/namespace.c | 2 ++
fs/nfs/netns.h | 2 +-
fs/nfs/nfs.h | 17 -------------
fs/nfs/nfs4_fs.h | 5 ++--
fs/nfs/nfs4super.c | 9 +++++--
fs/nfs/pagelist.c | 4 +++
fs/nfs/pnfs.c | 2 ++
fs/nfs/read.c | 4 +++
fs/nfs/super.c | 41 +++++++++++++++++++++++-------
fs/nfs/write.c | 13 +++++++---
include/linux/nfs_fs.h | 6 ++---
include/linux/nfs_fs_sb.h | 6 ++---
include/linux/nfs_idmap.h | 2 +-
include/linux/nfs_xdr.h | 2 +-
25 files changed, 155 insertions(+), 116 deletions(-)
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index f81a729..195c1ea 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -72,7 +72,7 @@ config NFS_V3_ACL
If unsure, say N.
config NFS_V4
- bool "NFS client support for NFS version 4"
+ tristate "NFS client support for NFS version 4"
depends on NFS_FS
select SUNRPC_GSS
select KEYS
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 01846ed..8bf3a3f 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -9,17 +9,7 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
write.o namespace.o mount_clnt.o \
dns_resolve.o cache_lib.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
-nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
- nfs4super.o nfs4file.o delegation.o idmap.o \
- callback.o callback_xdr.o callback_proc.o \
- nfs4namespace.o nfs4getroot.o nfs4client.o
-nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
-
-ifeq ($(CONFIG_SYSCTL), y)
-nfs-y += sysctl.o
-nfs-$(CONFIG_NFS_V4) += nfs4sysctl.o
-endif
-
+nfs-$(CONFIG_SYSCTL) += sysctl.o
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
obj-$(CONFIG_NFS_V2) += nfs2.o
@@ -29,6 +19,13 @@ obj-$(CONFIG_NFS_V3) += nfs3.o
nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
+obj-$(CONFIG_NFS_V4) += nfs4.o
+nfs4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
+ delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
+ nfs4namespace.o nfs4getroot.o nfs4client.o
+nfs4-$(CONFIG_SYSCTL) += nfs4sysctl.o
+nfs4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
+
obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index a5527c9..b44d7b1 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -192,7 +192,7 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args,
struct cb_process_state *cps);
extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy,
struct cb_process_state *cps);
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
extern void nfs_callback_down(int minorversion);
extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 8687b6b..9fc0d9d 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -143,24 +143,6 @@ void unregister_nfs_version(struct nfs_subversion *nfs)
EXPORT_SYMBOL_GPL(unregister_nfs_version);
/*
- * Preload all configured NFS versions during module init.
- * This function should be edited after each protocol is converted,
- * and eventually removed.
- */
-int __init nfs_register_versions(void)
-{
- return init_nfs_v4();
-}
-
-/*
- * Remove each pre-loaded NFS version
- */
-void nfs_unregister_versions(void)
-{
- exit_nfs_v4();
-}
-
-/*
* Allocate a shared client record
*
* Since these are allocated/deallocated very rarely, we don't
@@ -214,7 +196,7 @@ error_0:
}
EXPORT_SYMBOL_GPL(nfs_alloc_client);
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
/* idr_remove_all is not needed as all id's are removed by nfs_put_client */
void nfs_cleanup_cb_ident_idr(struct net *net)
{
@@ -390,6 +372,7 @@ int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
}
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_sockaddr_match_ipaddr);
#endif /* CONFIG_NFS_V4_1 */
/*
@@ -456,6 +439,7 @@ int nfs_wait_client_init_complete(const struct nfs_client *clp)
return wait_event_killable(nfs_client_active_wq,
nfs_client_init_is_complete(clp));
}
+EXPORT_SYMBOL_GPL(nfs_wait_client_init_complete);
/*
* Found an existing client. Make sure it's ready before returning.
@@ -530,6 +514,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
cl_init->hostname ?: "", PTR_ERR(new));
return new;
}
+EXPORT_SYMBOL_GPL(nfs_get_client);
/*
* Mark a server as ready or failed
@@ -540,6 +525,7 @@ void nfs_mark_client_ready(struct nfs_client *clp, int state)
clp->cl_cons_state = state;
wake_up_all(&nfs_client_active_wq);
}
+EXPORT_SYMBOL_GPL(nfs_mark_client_ready);
/*
* Initialise the timeout values for a connection
@@ -581,6 +567,7 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
BUG();
}
}
+EXPORT_SYMBOL_GPL(nfs_init_timeout_values);
/*
* Create an RPC client handle
@@ -620,6 +607,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
clp->cl_rpcclient = clnt;
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
/*
* Version 2 or 3 client destruction
@@ -706,6 +694,7 @@ int nfs_init_server_rpcclient(struct nfs_server *server,
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
/**
* nfs_init_client - Initialise an NFS2 or NFS3 client
@@ -932,6 +921,7 @@ out_error:
dprintk("nfs_probe_fsinfo: error = %d\n", -error);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_probe_fsinfo);
/*
* Copy useful information when duplicating a server record
@@ -948,6 +938,7 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
target->caps = source->caps;
target->options = source->options;
}
+EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
void nfs_server_insert_lists(struct nfs_server *server)
{
@@ -961,6 +952,7 @@ void nfs_server_insert_lists(struct nfs_server *server)
spin_unlock(&nn->nfs_client_lock);
}
+EXPORT_SYMBOL_GPL(nfs_server_insert_lists);
static void nfs_server_remove_lists(struct nfs_server *server)
{
@@ -1020,6 +1012,7 @@ struct nfs_server *nfs_alloc_server(void)
return server;
}
+EXPORT_SYMBOL_GPL(nfs_alloc_server);
/*
* Free up a server record
@@ -1048,6 +1041,7 @@ void nfs_free_server(struct nfs_server *server)
nfs_release_automount_timer();
dprintk("<-- nfs_free_server()\n");
}
+EXPORT_SYMBOL_GPL(nfs_free_server);
/*
* Create a version 2 or 3 volume record
@@ -1193,7 +1187,7 @@ void nfs_clients_init(struct net *net)
INIT_LIST_HEAD(&nn->nfs_client_list);
INIT_LIST_HEAD(&nn->nfs_volume_list);
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
idr_init(&nn->cb_ident_idr);
#endif
spin_lock_init(&nn->nfs_client_lock);
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 1f3ccd9..bbc6a4d 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -8,7 +8,7 @@
#ifndef FS_NFS_DELEGATION_H
#define FS_NFS_DELEGATION_H
-#if defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V4)
/*
* NFSv4 delegation
*/
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 55438c9..627f108 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -936,6 +936,7 @@ void nfs_force_lookup_revalidate(struct inode *dir)
{
NFS_I(dir)->cache_change_attribute++;
}
+EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate);
/*
* A check for whether or not the parent directory has changed.
@@ -1267,7 +1268,7 @@ out:
}
EXPORT_SYMBOL_GPL(nfs_lookup);
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
static int nfs4_lookup_revalidate(struct dentry *, unsigned int);
const struct dentry_operations nfs4_dentry_operations = {
@@ -1277,6 +1278,7 @@ const struct dentry_operations nfs4_dentry_operations = {
.d_automount = nfs_d_automount,
.d_release = nfs_d_release,
};
+EXPORT_SYMBOL_GPL(nfs4_dentry_operations);
static fmode_t flags_to_mode(int flags)
{
@@ -1419,6 +1421,7 @@ no_open:
return finish_no_open(file, res);
}
+EXPORT_SYMBOL_GPL(nfs_atomic_open);
static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
{
@@ -2142,6 +2145,7 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
{
return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
}
+EXPORT_SYMBOL_GPL(nfs_may_open);
int nfs_permission(struct inode *inode, int mask)
{
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index a947484..237a33d 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -460,7 +460,7 @@ static void nfs_inode_dio_write_done(struct inode *inode)
inode_dio_done(inode);
}
-#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
{
struct nfs_pageio_descriptor desc;
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index b3924b8..31c26c4 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -8,6 +8,7 @@
#ifdef CONFIG_NFS_USE_KERNEL_DNS
+#include <linux/module.h>
#include <linux/sunrpc/clnt.h>
#include <linux/dns_resolver.h>
#include "dns_resolve.h"
@@ -27,9 +28,11 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
kfree(ip_addr);
return ret;
}
+EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
#else
+#include <linux/module.h>
#include <linux/hash.h>
#include <linux/string.h>
#include <linux/kmod.h>
@@ -345,6 +348,7 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name,
ret = -ESRCH;
return ret;
}
+EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
int nfs_dns_resolver_cache_init(struct net *net)
{
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 130a7bb..3d557057 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -53,6 +53,7 @@ int nfs_check_flags(int flags)
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_check_flags);
/*
* Open file
@@ -85,6 +86,7 @@ nfs_file_release(struct inode *inode, struct file *filp)
nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
return nfs_release(inode, filp);
}
+EXPORT_SYMBOL_GPL(nfs_file_release);
/**
* nfs_revalidate_size - Revalidate the file size
@@ -138,6 +140,7 @@ loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
return generic_file_llseek(filp, offset, origin);
}
+EXPORT_SYMBOL_GPL(nfs_file_llseek);
/*
* Flush all dirty pages, and check for write errors.
@@ -166,6 +169,7 @@ nfs_file_flush(struct file *file, fl_owner_t id)
/* Flush writes to the server and return any errors */
return vfs_fsync(file, 0);
}
+EXPORT_SYMBOL_GPL(nfs_file_flush);
ssize_t
nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
@@ -190,6 +194,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
}
return result;
}
+EXPORT_SYMBOL_GPL(nfs_file_read);
ssize_t
nfs_file_splice_read(struct file *filp, loff_t *ppos,
@@ -212,6 +217,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
}
return res;
}
+EXPORT_SYMBOL_GPL(nfs_file_splice_read);
int
nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
@@ -233,6 +239,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
}
return status;
}
+EXPORT_SYMBOL_GPL(nfs_file_mmap);
/*
* Flush any dirty pages for this process, and check for write errors.
@@ -271,6 +278,7 @@ nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
ret = status;
return ret;
}
+EXPORT_SYMBOL_GPL(nfs_file_fsync_commit);
static int
nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
@@ -612,6 +620,7 @@ out_swapfile:
printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
goto out;
}
+EXPORT_SYMBOL_GPL(nfs_file_write);
ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
struct file *filp, loff_t *ppos,
@@ -643,6 +652,7 @@ ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
return ret;
}
+EXPORT_SYMBOL_GPL(nfs_file_splice_write);
static int
do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
@@ -803,6 +813,7 @@ int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
out_err:
return ret;
}
+EXPORT_SYMBOL_GPL(nfs_lock);
/*
* Lock a (portion of) a file
@@ -832,6 +843,7 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
return do_unlk(filp, cmd, fl, is_local);
return do_setlk(filp, cmd, fl, is_local);
}
+EXPORT_SYMBOL_GPL(nfs_flock);
/*
* There is no protocol support for leases, so we have no way to implement
@@ -844,6 +856,7 @@ int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
file->f_path.dentry->d_name.name, arg);
return -EINVAL;
}
+EXPORT_SYMBOL_GPL(nfs_setlease);
const struct file_operations nfs_file_operations = {
.llseek = nfs_file_llseek,
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 78dfc3e..2ed6138 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -82,6 +82,7 @@ int nfs_wait_bit_killable(void *word)
freezable_schedule();
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
/**
* nfs_compat_user_ino64 - returns the user-visible inode number
@@ -117,6 +118,7 @@ void nfs_clear_inode(struct inode *inode)
nfs_access_zap_cache(inode);
nfs_fscache_release_inode_cookie(inode);
}
+EXPORT_SYMBOL_GPL(nfs_clear_inode);
void nfs_evict_inode(struct inode *inode)
{
@@ -393,6 +395,7 @@ out_no_inode:
dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode));
goto out;
}
+EXPORT_SYMBOL_GPL(nfs_fhget);
#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN)
@@ -655,6 +658,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f
ctx->mdsthreshold = NULL;
return ctx;
}
+EXPORT_SYMBOL_GPL(alloc_nfs_open_context);
struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
{
@@ -662,6 +666,7 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
atomic_inc(&ctx->lock_context.count);
return ctx;
}
+EXPORT_SYMBOL_GPL(get_nfs_open_context);
static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
{
@@ -689,6 +694,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
{
__put_nfs_open_context(ctx, 0);
}
+EXPORT_SYMBOL_GPL(put_nfs_open_context);
/*
* Ensure that mmap has a recent RPC credential for use when writing out
@@ -704,6 +710,7 @@ void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
list_add(&ctx->list, &nfsi->open_files);
spin_unlock(&inode->i_lock);
}
+EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
/*
* Given an inode, search for an open context with the desired characteristics
@@ -1497,11 +1504,12 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
nfsi->acl_access = ERR_PTR(-EAGAIN);
nfsi->acl_default = ERR_PTR(-EAGAIN);
#endif
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
nfsi->nfs4_acl = NULL;
#endif /* CONFIG_NFS_V4 */
return &nfsi->vfs_inode;
}
+EXPORT_SYMBOL_GPL(nfs_alloc_inode);
static void nfs_i_callback(struct rcu_head *head)
{
@@ -1513,10 +1521,11 @@ void nfs_destroy_inode(struct inode *inode)
{
call_rcu(&inode->i_rcu, nfs_i_callback);
}
+EXPORT_SYMBOL_GPL(nfs_destroy_inode);
static inline void nfs4_init_once(struct nfs_inode *nfsi)
{
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
INIT_LIST_HEAD(&nfsi->open_states);
nfsi->delegation = NULL;
nfsi->delegation_state = 0;
@@ -1562,6 +1571,7 @@ static void nfs_destroy_inodecache(void)
}
struct workqueue_struct *nfsiod_workqueue;
+EXPORT_SYMBOL_GPL(nfsiod_workqueue);
/*
* start up the nfsiod workqueue
@@ -1622,90 +1632,80 @@ static int __init init_nfs_fs(void)
err = nfs_dns_resolver_init();
if (err < 0)
- goto out11;
+ goto out10;;
err = register_pernet_subsys(&nfs_net_ops);
if (err < 0)
- goto out10;
+ goto out9;
err = nfs_fscache_register();
if (err < 0)
- goto out9;
+ goto out8;
err = nfsiod_start();
if (err)
- goto out8;
+ goto out7;
err = nfs_fs_proc_init();
if (err)
- goto out7;
+ goto out6;
err = nfs_init_nfspagecache();
if (err)
- goto out6;
+ goto out5;
err = nfs_init_inodecache();
if (err)
- goto out5;
+ goto out4;
err = nfs_init_readpagecache();
if (err)
- goto out4;
+ goto out3;
err = nfs_init_writepagecache();
if (err)
- goto out3;
+ goto out2;
err = nfs_init_directcache();
if (err)
- goto out2;
+ goto out1;
#ifdef CONFIG_PROC_FS
rpc_proc_register(&init_net, &nfs_rpcstat);
#endif
-
- err = nfs_register_versions();
- if (err)
- goto out1;
-
if ((err = register_nfs_fs()) != 0)
goto out0;
return 0;
out0:
- nfs_unregister_versions();
-out1:
#ifdef CONFIG_PROC_FS
rpc_proc_unregister(&init_net, "nfs");
#endif
nfs_destroy_directcache();
-out2:
+out1:
nfs_destroy_writepagecache();
-out3:
+out2:
nfs_destroy_readpagecache();
-out4:
+out3:
nfs_destroy_inodecache();
-out5:
+out4:
nfs_destroy_nfspagecache();
-out6:
+out5:
nfs_fs_proc_exit();
-out7:
+out6:
nfsiod_stop();
-out8:
+out7:
nfs_fscache_unregister();
-out9:
+out8:
unregister_pernet_subsys(&nfs_net_ops);
-out10:
+out9:
nfs_dns_resolver_destroy();
-out11:
+out10:
return err;
}
static void __exit exit_nfs_fs(void)
{
-#ifdef CONFIG_NFS_V4
- exit_nfs_v4();
-#endif
nfs_destroy_directcache();
nfs_destroy_writepagecache();
nfs_destroy_readpagecache();
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 64f0dc4..8865538 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -262,7 +262,7 @@ extern int nfs3_decode_dirent(struct xdr_stream *,
struct nfs_entry *, int);
/* nfs4xdr.c */
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
extern int nfs4_decode_dirent(struct xdr_stream *,
struct nfs_entry *, int);
#endif
@@ -272,7 +272,7 @@ extern const u32 nfs41_maxwrite_overhead;
#endif
/* nfs4proc.c */
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
extern struct rpc_procinfo nfs4_procedures[];
#endif
@@ -328,7 +328,7 @@ extern int nfs_wait_bit_killable(void *word);
extern const struct super_operations nfs_sops;
extern struct file_system_type nfs_fs_type;
extern struct file_system_type nfs_xdev_fs_type;
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
extern struct file_system_type nfs4_xdev_fs_type;
extern struct file_system_type nfs4_referral_fs_type;
#endif
@@ -364,7 +364,7 @@ struct vfsmount *nfs_do_submount(struct dentry *, struct nfs_fh *,
/* getroot.c */
extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
const char *);
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
const char *);
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 2a3b170..6559253 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -113,6 +113,7 @@ Elong_unlock:
Elong:
return ERR_PTR(-ENAMETOOLONG);
}
+EXPORT_SYMBOL_GPL(nfs_path);
/*
* nfs_d_automount - Handle crossing a mountpoint on the server
@@ -241,6 +242,7 @@ out:
dprintk("<-- nfs_do_submount() = %p\n", mnt);
return mnt;
}
+EXPORT_SYMBOL_GPL(nfs_do_submount);
struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry,
struct nfs_fh *fh, struct nfs_fattr *fattr)
diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
index 8a6394e..0539de1 100644
--- a/fs/nfs/netns.h
+++ b/fs/nfs/netns.h
@@ -20,7 +20,7 @@ struct nfs_net {
wait_queue_head_t bl_wq;
struct list_head nfs_client_list;
struct list_head nfs_volume_list;
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
struct idr cb_ident_idr; /* Protected by nfs_client_lock */
#endif
spinlock_t nfs_client_lock;
diff --git a/fs/nfs/nfs.h b/fs/nfs/nfs.h
index 3e1b84b..43679df 100644
--- a/fs/nfs/nfs.h
+++ b/fs/nfs/nfs.h
@@ -21,23 +21,6 @@ struct nfs_subversion {
struct list_head list; /* List of NFS versions */
};
-int nfs_register_versions(void);
-void nfs_unregister_versions(void);
-
-#ifdef CONFIG_NFS_V4
-int init_nfs_v4(void);
-void exit_nfs_v4(void);
-#else /* CONFIG_NFS_V4 */
-static inline int __init init_nfs_v4(void)
-{
- return 0;
-}
-
-static inline void exit_nfs_v4(void)
-{
-}
-#endif /* CONFIG_NFS_V4 */
-
struct nfs_subversion *get_nfs_version(unsigned int);
void put_nfs_version(struct nfs_subversion *);
void register_nfs_version(struct nfs_subversion *);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index dfaa26bc..19c1a56 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -9,7 +9,7 @@
#ifndef __LINUX_FS_NFS_NFS4_FS_H
#define __LINUX_FS_NFS_NFS4_FS_H
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
struct idmap;
@@ -365,11 +365,10 @@ extern const nfs4_stateid zero_stateid;
struct nfs_mount_info;
extern struct nfs_subversion nfs_v4;
struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *);
-int init_nfs_v4(void);
-void exit_nfs_v4(void);
extern bool nfs4_disable_idmapping;
extern unsigned short max_session_slots;
extern unsigned short send_implementation_id;
+
/* nfs4sysctl.c */
#ifdef CONFIG_SYSCTL
int nfs4_register_sysctl(void);
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 1c825f3..12a31a9 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -332,7 +332,7 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
}
-int __init init_nfs_v4(void)
+static int __init init_nfs_v4(void)
{
int err;
@@ -358,10 +358,15 @@ out:
return err;
}
-void exit_nfs_v4(void)
+static void __exit exit_nfs_v4(void)
{
unregister_nfs_version(&nfs_v4);
unregister_filesystem(&nfs4_fs_type);
nfs4_unregister_sysctl();
nfs_idmap_quit();
}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_nfs_v4);
+module_exit(exit_nfs_v4);
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index aed913c..1e7d887 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -54,6 +54,7 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
if (hdr->completion_ops->init_hdr)
hdr->completion_ops->init_hdr(hdr);
}
+EXPORT_SYMBOL_GPL(nfs_pgheader_init);
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos)
{
@@ -268,6 +269,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
desc->pg_lseg = NULL;
desc->pg_dreq = NULL;
}
+EXPORT_SYMBOL_GPL(nfs_pageio_init);
/**
* nfs_can_coalesce_requests - test two requests for compatibility
@@ -409,6 +411,7 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
} while (ret);
return ret;
}
+EXPORT_SYMBOL_GPL(nfs_pageio_add_request);
/**
* nfs_pageio_complete - Complete I/O on an nfs_pageio_descriptor
@@ -424,6 +427,7 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
break;
}
}
+EXPORT_SYMBOL_GPL(nfs_pageio_complete);
/**
* nfs_pageio_cond_complete - Conditional I/O completion
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 7fbd25a..76875bf 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1407,6 +1407,7 @@ static void pnfs_writehdr_free(struct nfs_pgio_header *hdr)
put_lseg(hdr->lseg);
nfs_writehdr_free(hdr);
}
+EXPORT_SYMBOL_GPL(pnfs_writehdr_free);
int
pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
@@ -1561,6 +1562,7 @@ static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
put_lseg(hdr->lseg);
nfs_readhdr_free(hdr);
}
+EXPORT_SYMBOL_GPL(pnfs_readhdr_free);
int
pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index b000e4c..6935e40 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -48,6 +48,7 @@ struct nfs_read_header *nfs_readhdr_alloc(void)
}
return rhdr;
}
+EXPORT_SYMBOL_GPL(nfs_readhdr_alloc);
static struct nfs_read_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr,
unsigned int pagecount)
@@ -80,6 +81,7 @@ void nfs_readhdr_free(struct nfs_pgio_header *hdr)
kmem_cache_free(nfs_rdata_cachep, rhdr);
}
+EXPORT_SYMBOL_GPL(nfs_readhdr_free);
void nfs_readdata_release(struct nfs_read_data *rdata)
{
@@ -96,6 +98,7 @@ void nfs_readdata_release(struct nfs_read_data *rdata)
if (atomic_dec_and_test(&hdr->refcnt))
hdr->completion_ops->completion(hdr);
}
+EXPORT_SYMBOL_GPL(nfs_readdata_release);
static
int nfs_return_empty_page(struct page *page)
@@ -398,6 +401,7 @@ int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
return nfs_pagein_multi(desc, hdr);
return nfs_pagein_one(desc, hdr);
}
+EXPORT_SYMBOL_GPL(nfs_generic_pagein);
static int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
{
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 558a85c..ac6a3c5 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -315,7 +315,7 @@ const struct super_operations nfs_sops = {
};
EXPORT_SYMBOL_GPL(nfs_sops);
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
static int nfs4_validate_mount_data(void *options,
struct nfs_parsed_mount_data *args, const char *dev_name);
@@ -366,6 +366,7 @@ void nfs_sb_active(struct super_block *sb)
if (atomic_inc_return(&server->active) == 1)
atomic_inc(&sb->s_active);
}
+EXPORT_SYMBOL_GPL(nfs_sb_active);
void nfs_sb_deactive(struct super_block *sb)
{
@@ -374,6 +375,7 @@ void nfs_sb_deactive(struct super_block *sb)
if (atomic_dec_and_test(&server->active))
deactivate_super(sb);
}
+EXPORT_SYMBOL_GPL(nfs_sb_deactive);
/*
* Deliver file system statistics to userspace
@@ -439,6 +441,7 @@ int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
dprintk("%s: statfs error = %d\n", __func__, -error);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_statfs);
/*
* Map the security flavour number to a name
@@ -544,7 +547,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
nfs_show_mountd_netid(m, nfss, showdefaults);
}
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
int showdefaults)
{
@@ -675,8 +678,9 @@ int nfs_show_options(struct seq_file *m, struct dentry *root)
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_show_options);
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
#ifdef CONFIG_NFS_V4_1
static void show_sessions(struct seq_file *m, struct nfs_server *server)
{
@@ -709,7 +713,7 @@ static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss)
}
}
#else
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
static void show_pnfs(struct seq_file *m, struct nfs_server *server)
{
}
@@ -734,12 +738,14 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
free_page((unsigned long)page);
return err;
}
+EXPORT_SYMBOL_GPL(nfs_show_devname);
int nfs_show_path(struct seq_file *m, struct dentry *dentry)
{
seq_puts(m, "/");
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_show_path);
/*
* Present statistical information for this VFS mountpoint
@@ -774,7 +780,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
seq_printf(m, ",bsize=%u", nfss->bsize);
seq_printf(m, ",namlen=%u", nfss->namelen);
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
if (nfss->nfs_client->rpc_ops->version == 4) {
seq_printf(m, "\n\tnfsv4:\t");
seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
@@ -832,6 +838,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_show_stats);
/*
* Begin unmount by attempting to remove all automounted mountpoints we added
@@ -851,6 +858,7 @@ void nfs_umount_begin(struct super_block *sb)
if (!IS_ERR(rpc))
rpc_killall_tasks(rpc);
}
+EXPORT_SYMBOL_GPL(nfs_umount_begin);
static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
{
@@ -1915,7 +1923,7 @@ out_invalid_fh:
return -EINVAL;
}
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
static int nfs_validate_mount_data(struct file_system_type *fs_type,
void *options,
struct nfs_parsed_mount_data *args,
@@ -1953,7 +1961,7 @@ static int nfs_validate_text_mount_data(void *options,
goto out_no_address;
if (args->version == 4) {
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
port = NFS_PORT;
max_namelen = NFS4_MAXNAMLEN;
max_pathlen = NFS4_MAXPATHLEN;
@@ -1976,7 +1984,7 @@ static int nfs_validate_text_mount_data(void *options,
&args->nfs_server.export_path,
max_pathlen);
-#ifndef CONFIG_NFS_V4
+#if !IS_ENABLED(CONFIG_NFS_V4)
out_v4_not_compiled:
dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
return -EPROTONOSUPPORT;
@@ -2075,6 +2083,7 @@ out:
kfree(data);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_remount);
/*
* Initialise the common bits of the superblock
@@ -2123,6 +2132,7 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
nfs_initialise_sb(sb);
}
+EXPORT_SYMBOL_GPL(nfs_fill_super);
/*
* Finish setting up a cloned NFS2/3/4 superblock
@@ -2292,6 +2302,7 @@ int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
{
return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
}
+EXPORT_SYMBOL_GPL(nfs_set_sb_security);
int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
struct nfs_mount_info *mount_info)
@@ -2302,6 +2313,7 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
return -ESTALE;
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
struct dentry *nfs_fs_mount_common(struct nfs_server *server,
int flags, const char *dev_name,
@@ -2375,6 +2387,7 @@ error_splat_bdi:
deactivate_locked_super(s);
goto out;
}
+EXPORT_SYMBOL_GPL(nfs_fs_mount_common);
struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data)
@@ -2415,6 +2428,7 @@ out:
nfs_free_fhandle(mount_info.mntfh);
return mntroot;
}
+EXPORT_SYMBOL_GPL(nfs_fs_mount);
/*
* Ensure that we unregister the bdi before kill_anon_super
@@ -2426,6 +2440,7 @@ void nfs_put_super(struct super_block *s)
bdi_unregister(&server->backing_dev_info);
}
+EXPORT_SYMBOL_GPL(nfs_put_super);
/*
* Destroy an NFS2/3 superblock
@@ -2438,6 +2453,7 @@ void nfs_kill_super(struct super_block *s)
nfs_fscache_release_super_cookie(s);
nfs_free_server(server);
}
+EXPORT_SYMBOL_GPL(nfs_kill_super);
/*
* Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
@@ -2478,7 +2494,7 @@ out_err:
goto out;
}
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
{
@@ -2590,6 +2606,13 @@ bool nfs4_disable_idmapping = true;
unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
unsigned short send_implementation_id = 1;
+EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
+EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
+EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout);
+EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
+EXPORT_SYMBOL_GPL(max_session_slots);
+EXPORT_SYMBOL_GPL(send_implementation_id);
+
#define NFS_CALLBACK_MAXPORTNR (65535U)
static int param_set_portnr(const char *val, const struct kernel_param *kp)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f268fe4..e4a2ad2 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -84,6 +84,7 @@ struct nfs_write_header *nfs_writehdr_alloc(void)
}
return p;
}
+EXPORT_SYMBOL_GPL(nfs_writehdr_alloc);
static struct nfs_write_data *nfs_writedata_alloc(struct nfs_pgio_header *hdr,
unsigned int pagecount)
@@ -115,6 +116,7 @@ void nfs_writehdr_free(struct nfs_pgio_header *hdr)
struct nfs_write_header *whdr = container_of(hdr, struct nfs_write_header, header);
mempool_free(whdr, nfs_wdata_mempool);
}
+EXPORT_SYMBOL_GPL(nfs_writehdr_free);
void nfs_writedata_release(struct nfs_write_data *wdata)
{
@@ -131,6 +133,7 @@ void nfs_writedata_release(struct nfs_write_data *wdata)
if (atomic_dec_and_test(&hdr->refcnt))
hdr->completion_ops->completion(hdr);
}
+EXPORT_SYMBOL_GPL(nfs_writedata_release);
static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
{
@@ -446,7 +449,7 @@ nfs_mark_request_dirty(struct nfs_page *req)
__set_page_dirty_nobuffers(req->wb_page);
}
-#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
/**
* nfs_request_add_commit_list - add request to a commit list
* @req: pointer to a struct nfs_page
@@ -636,7 +639,7 @@ out:
hdr->release(hdr);
}
-#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
static unsigned long
nfs_reqs_to_commit(struct nfs_commit_info *cinfo)
{
@@ -1173,6 +1176,7 @@ int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
return nfs_flush_multi(desc, hdr);
return nfs_flush_one(desc, hdr);
}
+EXPORT_SYMBOL_GPL(nfs_generic_flush);
static int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
{
@@ -1298,7 +1302,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
return;
nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, resp->count);
-#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
if (resp->verf->committed < argp->stable && task->tk_status >= 0) {
/* We tried a write call, but the server did not
* commit data to stable storage even though we
@@ -1358,7 +1362,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
}
-#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
{
int ret;
@@ -1674,6 +1678,7 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
return nfs_commit_unstable_pages(inode, wbc);
}
+EXPORT_SYMBOL_GPL(nfs_write_inode);
/*
* flush the inode to disk.
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 4b6043c..2889877 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -191,7 +191,7 @@ struct nfs_inode {
struct hlist_head silly_list;
wait_queue_head_t waitqueue;
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
struct nfs4_cached_acl *nfs4_acl;
/* NFSv4 state */
struct list_head open_states;
@@ -428,7 +428,7 @@ extern __be32 root_nfs_parse_addr(char *name); /*__init*/
* linux/fs/nfs/file.c
*/
extern const struct file_operations nfs_file_operations;
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
extern const struct file_operations nfs4_file_operations;
#endif /* CONFIG_NFS_V4 */
extern const struct address_space_operations nfs_file_aops;
@@ -538,7 +538,7 @@ extern void nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
extern int nfs_wb_all(struct inode *inode);
extern int nfs_wb_page(struct inode *inode, struct page* page);
extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
extern int nfs_commit_inode(struct inode *, int);
extern struct nfs_commit_data *nfs_commitdata_alloc(void);
extern void nfs_commit_free(struct nfs_commit_data *data);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 6039297..310c63c 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -53,7 +53,7 @@ struct nfs_client {
u32 cl_minorversion;/* NFSv4 minorversion */
struct rpc_cred *cl_machine_cred;
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
u64 cl_clientid; /* constant */
nfs4_verifier cl_confirm; /* Clientid verifier */
unsigned long cl_state;
@@ -138,7 +138,7 @@ struct nfs_server {
#endif
u32 pnfs_blksize; /* layout_blksize attr */
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
u32 attr_bitmask[3];/* V4 bitmask representing the set
of attributes supported on this
filesystem */
@@ -201,7 +201,7 @@ struct nfs_server {
#define NFS4_MAX_SLOT_TABLE (256U)
#define NFS4_NO_SLOT ((u32)-1)
-#if defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V4)
/* Sessions */
#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h
index 7eed201..ece91c5 100644
--- a/include/linux/nfs_idmap.h
+++ b/include/linux/nfs_idmap.h
@@ -69,7 +69,7 @@ struct nfs_server;
struct nfs_fattr;
struct nfs4_string;
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
int nfs_idmap_init(void);
void nfs_idmap_quit(void);
#else
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 6311820..00485e0 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -824,7 +824,7 @@ struct nfs3_getaclres {
struct posix_acl * acl_default;
};
-#ifdef CONFIG_NFS_V4
+#if IS_ENABLED(CONFIG_NFS_V4)
typedef u64 clientid4;
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
Otherwise we break backwards compatibility when v4 becomes a modules.
---
fs/nfs/callback.c | 24 ------------------------
fs/nfs/idmap.c | 3 ---
fs/nfs/nfs4_fs.h | 4 +++-
fs/nfs/nfs4client.c | 9 ---------
fs/nfs/nfs4proc.c | 6 ------
fs/nfs/nfs4xdr.c | 6 ------
fs/nfs/super.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 48 insertions(+), 49 deletions(-)
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 23ff18f..ca3ac99 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -37,31 +37,7 @@ static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1];
static DEFINE_MUTEX(nfs_callback_mutex);
static struct svc_program nfs4_callback_program;
-unsigned int nfs_callback_set_tcpport;
-unsigned short nfs_callback_tcpport;
unsigned short nfs_callback_tcpport6;
-#define NFS_CALLBACK_MAXPORTNR (65535U)
-
-static int param_set_portnr(const char *val, const struct kernel_param *kp)
-{
- unsigned long num;
- int ret;
-
- if (!val)
- return -EINVAL;
- ret = strict_strtoul(val, 0, &num);
- if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
- return -EINVAL;
- *((unsigned int *)kp->arg) = num;
- return 0;
-}
-static struct kernel_param_ops param_ops_portnr = {
- .set = param_set_portnr,
- .get = param_get_uint,
-};
-#define param_check_portnr(name, p) __param_check(name, p, unsigned int);
-
-module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
/*
* This is the NFSv4 callback kernel thread.
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 864c51e..407a9b2 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -52,8 +52,6 @@
#define NFS_UINT_MAXLEN 11
-/* Default cache timeout is 10 minutes */
-unsigned int nfs_idmap_cache_timeout = 600;
static const struct cred *id_resolver_cache;
static struct key_type key_type_id_resolver_legacy;
@@ -359,7 +357,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ
}
/* idmap classic begins here */
-module_param(nfs_idmap_cache_timeout, int, 0644);
enum {
Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index af8712d..dfaa26bc 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -367,7 +367,9 @@ extern struct nfs_subversion nfs_v4;
struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *);
int init_nfs_v4(void);
void exit_nfs_v4(void);
-
+extern bool nfs4_disable_idmapping;
+extern unsigned short max_session_slots;
+extern unsigned short send_implementation_id;
/* nfs4sysctl.c */
#ifdef CONFIG_SYSCTL
int nfs4_register_sysctl(void);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index b2d409d..cbcdfaf 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -18,11 +18,6 @@
#define NFSDBG_FACILITY NFSDBG_CLIENT
/*
- * Turn off NFSv4 uid/gid mapping when using AUTH_SYS
- */
-static bool nfs4_disable_idmapping = true;
-
-/*
* Get a unique NFSv4.0 callback identifier which will be used
* by the V4.0 callback service to lookup the nfs_client struct
*/
@@ -659,7 +654,3 @@ error:
dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
return ERR_PTR(error);
}
-
-module_param(nfs4_disable_idmapping, bool, 0644);
-MODULE_PARM_DESC(nfs4_disable_idmapping,
- "Turn off NFSv4 idmapping when using 'sec=sys'");
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2e87727..a02cb73 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -72,8 +72,6 @@
#define NFS4_MAX_LOOP_ON_RECOVER (10)
-static unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
-
struct nfs4_opendata;
static int _nfs4_proc_open(struct nfs4_opendata *data);
static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
@@ -6932,10 +6930,6 @@ const struct xattr_handler *nfs4_xattr_handlers[] = {
NULL
};
-module_param(max_session_slots, ushort, 0644);
-MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
- "requests the client will negotiate");
-
/*
* Local variables:
* c-basic-offset: 8
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 610ebcc..45ecaee 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -852,12 +852,6 @@ const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
XDR_UNIT);
#endif /* CONFIG_NFS_V4_1 */
-static unsigned short send_implementation_id = 1;
-
-module_param(send_implementation_id, ushort, 0644);
-MODULE_PARM_DESC(send_implementation_id,
- "Send implementation ID with NFSv4.1 exchange_id");
-
static const umode_t nfs_type2fmt[] = {
[NF4BAD] = 0,
[NF4REG] = S_IFREG,
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a275d19..8e0da5a 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2574,4 +2574,49 @@ out_no_address:
return -EINVAL;
}
+/*
+ * NFS v4 module parameters need to stay in the
+ * NFS client for backwards compatibility
+ */
+unsigned int nfs_callback_set_tcpport;
+unsigned short nfs_callback_tcpport;
+/* Default cache timeout is 10 minutes */
+unsigned int nfs_idmap_cache_timeout = 600;
+/* Turn off NFSv4 uid/gid mapping when using AUTH_SYS */
+bool nfs4_disable_idmapping = true;
+unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
+unsigned short send_implementation_id = 1;
+
+#define NFS_CALLBACK_MAXPORTNR (65535U)
+
+static int param_set_portnr(const char *val, const struct kernel_param *kp)
+{
+ unsigned long num;
+ int ret;
+
+ if (!val)
+ return -EINVAL;
+ ret = strict_strtoul(val, 0, &num);
+ if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
+ return -EINVAL;
+ *((unsigned int *)kp->arg) = num;
+ return 0;
+}
+static struct kernel_param_ops param_ops_portnr = {
+ .set = param_set_portnr,
+ .get = param_get_uint,
+};
+#define param_check_portnr(name, p) __param_check(name, p, unsigned int);
+
+module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
+module_param(nfs_idmap_cache_timeout, int, 0644);
+module_param(nfs4_disable_idmapping, bool, 0644);
+MODULE_PARM_DESC(nfs4_disable_idmapping,
+ "Turn off NFSv4 idmapping when using 'sec=sys'");
+module_param(max_session_slots, ushort, 0644);
+MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
+ "requests the client will negotiate");
+module_param(send_implementation_id, ushort, 0644);
+MODULE_PARM_DESC(send_implementation_id,
+ "Send implementation ID with NFSv4.1 exchange_id");
#endif /* CONFIG_NFS_V4 */
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
v2 and v4 don't use it, so I create two new nfs_rpc_ops functions to
initialize the ACL client only when we are using v3.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Makefile | 2 +-
fs/nfs/client.c | 61 ++++------------------------------------------
fs/nfs/internal.h | 15 ++++++++----
fs/nfs/nfs3client.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
fs/nfs/nfs3proc.c | 2 ++
fs/nfs/nfs4client.c | 10 +++++---
fs/nfs/nfs4proc.c | 2 ++
fs/nfs/nfs4super.c | 2 +-
fs/nfs/proc.c | 2 ++
fs/nfs/super.c | 4 +--
include/linux/nfs_xdr.h | 3 +++
11 files changed, 99 insertions(+), 69 deletions(-)
create mode 100644 fs/nfs/nfs3client.c
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 66dd307..7ca0125 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -10,7 +10,7 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
dns_resolve.o cache_lib.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
nfs-$(CONFIG_NFS_V2) += nfs2super.o proc.o nfs2xdr.o
-nfs-$(CONFIG_NFS_V3) += nfs3super.o nfs3proc.o nfs3xdr.o
+nfs-$(CONFIG_NFS_V3) += nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
nfs4super.o nfs4file.o delegation.o idmap.o \
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 462de24..1f29082 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -83,22 +83,6 @@ struct rpc_stat nfs_rpcstat = {
.program = &nfs_program
};
-
-#ifdef CONFIG_NFS_V3_ACL
-static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
-static const struct rpc_version *nfsacl_version[] = {
- [3] = &nfsacl_version3,
-};
-
-const struct rpc_program nfsacl_program = {
- .name = "nfsacl",
- .number = NFS_ACL_PROGRAM,
- .nrvers = ARRAY_SIZE(nfsacl_version),
- .version = nfsacl_version,
- .stats = &nfsacl_rpcstat,
-};
-#endif /* CONFIG_NFS_V3_ACL */
-
static struct nfs_subversion *find_nfs_version(unsigned int version)
{
struct nfs_subversion *nfs;
@@ -696,36 +680,6 @@ static int nfs_start_lockd(struct nfs_server *server)
}
/*
- * Initialise an NFSv3 ACL client connection
- */
-#ifdef CONFIG_NFS_V3_ACL
-static void nfs_init_server_aclclient(struct nfs_server *server)
-{
- if (server->nfs_client->rpc_ops->version != 3)
- goto out_noacl;
- if (server->flags & NFS_MOUNT_NOACL)
- goto out_noacl;
-
- server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
- if (IS_ERR(server->client_acl))
- goto out_noacl;
-
- /* No errors! Assume that Sun nfsacls are supported */
- server->caps |= NFS_CAP_ACLS;
- return;
-
-out_noacl:
- server->caps &= ~NFS_CAP_ACLS;
-}
-#else
-static inline void nfs_init_server_aclclient(struct nfs_server *server)
-{
- server->flags &= ~NFS_MOUNT_NOACL;
- server->caps &= ~NFS_CAP_ACLS;
-}
-#endif
-
-/*
* Create a general RPC client
*/
int nfs_init_server_rpcclient(struct nfs_server *server,
@@ -874,8 +828,6 @@ static int nfs_init_server(struct nfs_server *server,
server->mountd_protocol = data->mount_server.protocol;
server->namelen = data->namlen;
- /* Create a client RPC handle for the NFSv3 ACL management interface */
- nfs_init_server_aclclient(server);
dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
return 0;
@@ -1108,8 +1060,7 @@ void nfs_free_server(struct nfs_server *server)
* Create a version 2 or 3 volume record
* - keyed on server and FSID
*/
-struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
- struct nfs_fh *mntfh,
+struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
struct nfs_subversion *nfs_mod)
{
struct nfs_server *server;
@@ -1126,7 +1077,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
goto error;
/* Get a client representation */
- error = nfs_init_server(server, data, nfs_mod);
+ error = nfs_init_server(server, mount_info->parsed, nfs_mod);
if (error < 0)
goto error;
@@ -1135,13 +1086,13 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
/* Probe the root fh to retrieve its FSID */
- error = nfs_probe_fsinfo(server, mntfh, fattr);
+ error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr);
if (error < 0)
goto error;
if (server->nfs_client->rpc_ops->version == 3) {
if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
server->namelen = NFS3_MAXNAMLEN;
- if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
+ if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS))
server->caps |= NFS_CAP_READDIRPLUS;
} else {
if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
@@ -1149,7 +1100,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
}
if (!(fattr->valid & NFS_ATTR_FATTR)) {
- error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
+ error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh, fattr);
if (error < 0) {
dprintk("nfs_create_server: getattr error = %d\n", -error);
goto error;
@@ -1210,8 +1161,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
flavor);
if (error < 0)
goto out_free_server;
- if (!IS_ERR(source->client_acl))
- nfs_init_server_aclclient(server);
/* probe the filesystem info for this server filesystem */
error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 3364ecc..2151baf 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -187,13 +187,11 @@ extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
extern struct nfs_client *
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
struct nfs4_sessionid *);
-extern struct nfs_server *nfs_create_server(
- const struct nfs_parsed_mount_data *,
- struct nfs_fh *,
+extern struct nfs_server *nfs_create_server(struct nfs_mount_info *,
struct nfs_subversion *);
extern struct nfs_server *nfs4_create_server(
- const struct nfs_parsed_mount_data *,
- struct nfs_fh *);
+ struct nfs_mount_info *,
+ struct nfs_subversion *);
extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
struct nfs_fh *);
extern void nfs_free_server(struct nfs_server *server);
@@ -225,6 +223,13 @@ static inline void nfs_fs_proc_exit(void)
int nfs_sockaddr_match_ipaddr(const struct sockaddr *, const struct sockaddr *);
#endif
+/* nfs3client.c */
+#ifdef CONFIG_NFS_V3
+struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *);
+struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *,
+ struct nfs_fattr *, rpc_authflavor_t);
+#endif
+
/* callback_xdr.c */
extern struct svc_version nfs4_callback_version1;
extern struct svc_version nfs4_callback_version4;
diff --git a/fs/nfs/nfs3client.c b/fs/nfs/nfs3client.c
new file mode 100644
index 0000000..b3fc65e
--- /dev/null
+++ b/fs/nfs/nfs3client.c
@@ -0,0 +1,65 @@
+#include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
+#include "internal.h"
+
+#ifdef CONFIG_NFS_V3_ACL
+static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
+static const struct rpc_version *nfsacl_version[] = {
+ [3] = &nfsacl_version3,
+};
+
+const struct rpc_program nfsacl_program = {
+ .name = "nfsacl",
+ .number = NFS_ACL_PROGRAM,
+ .nrvers = ARRAY_SIZE(nfsacl_version),
+ .version = nfsacl_version,
+ .stats = &nfsacl_rpcstat,
+};
+
+/*
+ * Initialise an NFSv3 ACL client connection
+ */
+static void nfs_init_server_aclclient(struct nfs_server *server)
+{
+ if (server->flags & NFS_MOUNT_NOACL)
+ goto out_noacl;
+
+ server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
+ if (IS_ERR(server->client_acl))
+ goto out_noacl;
+
+ /* No errors! Assume that Sun nfsacls are supported */
+ server->caps |= NFS_CAP_ACLS;
+ return;
+
+out_noacl:
+ server->caps &= ~NFS_CAP_ACLS;
+}
+#else
+static inline void nfs_init_server_aclclient(struct nfs_server *server)
+{
+ server->flags &= ~NFS_MOUNT_NOACL;
+ server->caps &= ~NFS_CAP_ACLS;
+}
+#endif
+
+struct nfs_server *nfs3_create_server(struct nfs_mount_info *mount_info,
+ struct nfs_subversion *nfs_mod)
+{
+ struct nfs_server *server = nfs_create_server(mount_info, nfs_mod);
+ /* Create a client RPC handle for the NFS v3 ACL management interface */
+ if (!IS_ERR(server))
+ nfs_init_server_aclclient(server);
+ return server;
+}
+
+struct nfs_server *nfs3_clone_server(struct nfs_server *source,
+ struct nfs_fh *fh,
+ struct nfs_fattr *fattr,
+ rpc_authflavor_t flavor)
+{
+ struct nfs_server *server = nfs_clone_server(source, fh, fattr, flavor);
+ if (!IS_ERR(server) && !IS_ERR(source->client_acl))
+ nfs_init_server_aclclient(server);
+ return server;
+}
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 4f4cb8e..0952c79 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -969,4 +969,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
.alloc_client = nfs_alloc_client,
.init_client = nfs_init_client,
.free_client = nfs_free_client,
+ .create_server = nfs3_create_server,
+ .clone_server = nfs3_clone_server,
};
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 769e798..b2d409d 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -574,8 +574,10 @@ error:
* Create a version 4 volume record
* - keyed on server and FSID
*/
-struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
- struct nfs_fh *mntfh)
+/*struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
+ struct nfs_fh *mntfh)*/
+struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
+ struct nfs_subversion *nfs_mod)
{
struct nfs_server *server;
int error;
@@ -587,11 +589,11 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
return ERR_PTR(-ENOMEM);
/* set up the general RPC client */
- error = nfs4_init_server(server, data);
+ error = nfs4_init_server(server, mount_info->parsed);
if (error < 0)
goto error;
- error = nfs4_server_common_setup(server, mntfh);
+ error = nfs4_server_common_setup(server, mount_info->mntfh);
if (error < 0)
goto error;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ac78df9..2e87727 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6916,6 +6916,8 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.alloc_client = nfs4_alloc_client,
.init_client = nfs4_init_client,
.free_client = nfs4_free_client,
+ .create_server = nfs4_create_server,
+ .clone_server = nfs_clone_server,
};
static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 9384f66..a628362 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -105,7 +105,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
mount_info->set_security = nfs_set_sb_security;
/* Get a volume representation */
- server = nfs4_create_server(mount_info->parsed, mount_info->mntfh);
+ server = nfs4_create_server(mount_info, &nfs_v4);
if (IS_ERR(server)) {
mntroot = ERR_CAST(server);
goto out;
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index ebb3d9c..50a88c3 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -817,4 +817,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
.alloc_client = nfs_alloc_client,
.init_client = nfs_init_client,
.free_client = nfs_free_client,
+ .create_server = nfs_create_server,
+ .clone_server = nfs_clone_server,
};
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 5fca59d7..a5f9fb3 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1664,7 +1664,7 @@ struct dentry *nfs_try_mount(int flags, const char *dev_name,
}
/* Get a volume representation */
- server = nfs_create_server(mount_info->parsed, mount_info->mntfh, nfs_mod);
+ server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
if (IS_ERR(server))
return ERR_CAST(server);
@@ -2458,7 +2458,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
mount_info.mntfh = mount_info.cloned->fh;
/* create a new volume representation */
- server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
+ server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
if (IS_ERR(server)) {
error = PTR_ERR(server);
goto out_err;
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index bc7415b..6311820 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1439,6 +1439,9 @@ struct nfs_rpc_ops {
(*init_client) (struct nfs_client *, const struct rpc_timeout *,
const char *, rpc_authflavor_t);
void (*free_client) (struct nfs_client *);
+ struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *);
+ struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
+ struct nfs_fattr *, rpc_authflavor_t);
};
/*
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
I can set all variables in the nfs_fill_super() function, allowing me to
remove the nfs4_fill_super() function.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/internal.h | 1 +
fs/nfs/nfs.h | 2 ++
fs/nfs/nfs2super.c | 1 +
fs/nfs/nfs3super.c | 1 +
fs/nfs/nfs4super.c | 24 +++---------------------
fs/nfs/super.c | 9 +++++----
6 files changed, 13 insertions(+), 25 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 2151baf..17d1470 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -327,6 +327,7 @@ void nfs_zap_acl_cache(struct inode *inode);
extern int nfs_wait_bit_killable(void *word);
/* super.c */
+extern const struct super_operations nfs_sops;
extern struct file_system_type nfs_fs_type;
extern struct file_system_type nfs_xdev_fs_type;
#ifdef CONFIG_NFS_V4
diff --git a/fs/nfs/nfs.h b/fs/nfs/nfs.h
index ac10b9e..9f502a0 100644
--- a/fs/nfs/nfs.h
+++ b/fs/nfs/nfs.h
@@ -16,6 +16,8 @@ struct nfs_subversion {
struct file_system_type *nfs_fs; /* NFS filesystem type */
const struct rpc_version *rpc_vers; /* NFS version information */
const struct nfs_rpc_ops *rpc_ops; /* NFS operations */
+ const struct super_operations *sops; /* NFS Super operations */
+ const struct xattr_handler **xattr; /* NFS xattr handlers */
struct list_head list; /* List of NFS versions */
};
diff --git a/fs/nfs/nfs2super.c b/fs/nfs/nfs2super.c
index cef06d4..a9fb69d 100644
--- a/fs/nfs/nfs2super.c
+++ b/fs/nfs/nfs2super.c
@@ -11,6 +11,7 @@ static struct nfs_subversion nfs_v2 = {
.nfs_fs = &nfs_fs_type,
.rpc_vers = &nfs_version2,
.rpc_ops = &nfs_v2_clientops,
+ .sops = &nfs_sops,
};
int __init init_nfs_v2(void)
diff --git a/fs/nfs/nfs3super.c b/fs/nfs/nfs3super.c
index f815cf3..8378090 100644
--- a/fs/nfs/nfs3super.c
+++ b/fs/nfs/nfs3super.c
@@ -11,6 +11,7 @@ static struct nfs_subversion nfs_v3 = {
.nfs_fs = &nfs_fs_type,
.rpc_vers = &nfs_version3,
.rpc_ops = &nfs_v3_clientops,
+ .sops = &nfs_sops,
};
int __init init_nfs_v3(void)
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index a628362..c70e173 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -71,26 +71,11 @@ struct nfs_subversion nfs_v4 = {
.nfs_fs = &nfs4_fs_type,
.rpc_vers = &nfs_version4,
.rpc_ops = &nfs_v4_clientops,
+ .sops = &nfs4_sops,
+ .xattr = nfs4_xattr_handlers,
};
/*
- * Set up an NFS4 superblock
- */
-static void nfs4_fill_super(struct super_block *sb,
- struct nfs_mount_info *mount_info)
-{
- sb->s_time_gran = 1;
- sb->s_op = &nfs4_sops;
- /*
- * The VFS shouldn't apply the umask to mode bits. We will do
- * so ourselves when necessary.
- */
- sb->s_flags |= MS_POSIXACL;
- sb->s_xattr = nfs4_xattr_handlers;
- nfs_initialise_sb(sb);
-}
-
-/*
* Get the superblock for the NFS4 root partition
*/
static struct dentry *
@@ -101,7 +86,6 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
struct nfs_server *server;
struct dentry *mntroot = ERR_PTR(-ENOMEM);
- mount_info->fill_super = nfs4_fill_super;
mount_info->set_security = nfs_set_sb_security;
/* Get a volume representation */
@@ -236,8 +220,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
dfprintk(MOUNT, "--> nfs4_try_mount()\n");
- mount_info->fill_super = nfs4_fill_super;
-
export_path = data->nfs_server.export_path;
data->nfs_server.export_path = "/";
root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
@@ -257,7 +239,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *raw_data)
{
struct nfs_mount_info mount_info = {
- .fill_super = nfs4_fill_super,
+ .fill_super = nfs_fill_super,
.set_security = nfs_clone_sb_security,
.cloned = raw_data,
};
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a5f9fb3..a275d19 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -298,7 +298,7 @@ struct file_system_type nfs_xdev_fs_type = {
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
};
-static const struct super_operations nfs_sops = {
+const struct super_operations nfs_sops = {
.alloc_inode = nfs_alloc_inode,
.destroy_inode = nfs_destroy_inode,
.write_inode = nfs_write_inode,
@@ -2105,10 +2105,12 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
sb->s_blocksize_bits = 0;
sb->s_blocksize = 0;
- if (data->bsize)
+ sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
+ sb->s_op = server->nfs_client->cl_nfs_mod->sops;
+ if (data && data->bsize)
sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
- if (server->nfs_client->rpc_ops->version == 3) {
+ if (server->nfs_client->rpc_ops->version != 2) {
/* The VFS shouldn't apply the umask to mode bits. We will do
* so ourselves when necessary.
*/
@@ -2116,7 +2118,6 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
sb->s_time_gran = 1;
}
- sb->s_op = &nfs_sops;
nfs_initialise_sb(sb);
}
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
I can now share this code with the v2 and v3 code by using the NFS
subversion structure.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/namespace.c | 13 -------------
fs/nfs/nfs4super.c | 25 -------------------------
fs/nfs/super.c | 30 ++++++++++--------------------
3 files changed, 10 insertions(+), 58 deletions(-)
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 08b9c93..0f699fe 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -195,20 +195,7 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
const char *devname,
struct nfs_clone_mount *mountdata)
{
-#ifdef CONFIG_NFS_V4
- struct vfsmount *mnt = ERR_PTR(-EINVAL);
- switch (server->nfs_client->rpc_ops->version) {
- case 2:
- case 3:
- mnt = vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
- break;
- case 4:
- mnt = vfs_kern_mount(&nfs4_xdev_fs_type, 0, devname, mountdata);
- }
- return mnt;
-#else
return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
-#endif
}
/**
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 1f34019..8a50557 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -14,8 +14,6 @@
static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data);
-static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *raw_data);
static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data);
static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
@@ -37,14 +35,6 @@ static struct file_system_type nfs4_remote_fs_type = {
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
};
-struct file_system_type nfs4_xdev_fs_type = {
- .owner = THIS_MODULE,
- .name = "nfs4",
- .mount = nfs4_xdev_mount,
- .kill_sb = nfs_kill_super,
- .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
-};
-
static struct file_system_type nfs4_remote_referral_fs_type = {
.owner = THIS_MODULE,
.name = "nfs4",
@@ -261,21 +251,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
return res;
}
-/*
- * Clone an NFS4 server record on xdev traversal (FSID-change)
- */
-static struct dentry *
-nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *raw_data)
-{
- struct nfs_mount_info mount_info = {
- .fill_super = nfs_clone_super,
- .set_security = nfs_clone_sb_security,
- .cloned = raw_data,
- };
- return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
-}
-
static struct dentry *
nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *raw_data)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 61405a7..4faefa1 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2445,10 +2445,15 @@ void nfs_kill_super(struct super_block *s)
* Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
*/
struct dentry *
-nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
- const char *dev_name, struct nfs_mount_info *mount_info)
+nfs_xdev_mount(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *raw_data)
{
- struct nfs_clone_mount *data = mount_info->cloned;
+ struct nfs_clone_mount *data = raw_data;
+ struct nfs_mount_info mount_info = {
+ .fill_super = nfs_clone_super,
+ .set_security = nfs_clone_sb_security,
+ .cloned = data,
+ };
struct nfs_server *server;
struct dentry *mntroot = ERR_PTR(-ENOMEM);
struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod;
@@ -2456,7 +2461,7 @@ nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
dprintk("--> nfs_xdev_mount_common()\n");
- mount_info->mntfh = data->fh;
+ mount_info.mntfh = mount_info.cloned->fh;
/* create a new volume representation */
server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
@@ -2465,7 +2470,7 @@ nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
goto out_err;
}
- mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
+ mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, nfs_mod);
dprintk("<-- nfs_xdev_mount_common() = 0\n");
out:
return mntroot;
@@ -2475,21 +2480,6 @@ out_err:
goto out;
}
-/*
- * Clone an NFS2/3 server record on xdev traversal (FSID-change)
- */
-static struct dentry *
-nfs_xdev_mount(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *raw_data)
-{
- struct nfs_mount_info mount_info = {
- .fill_super = nfs_clone_super,
- .set_security = nfs_clone_sb_security,
- .cloned = raw_data,
- };
- return nfs_xdev_mount_common(&nfs_fs_type, flags, dev_name, &mount_info);
-}
-
#ifdef CONFIG_NFS_V4
static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
I'm already looking up the nfs subversion in nfs_fs_mount(), so I have
easy access to rpc_ops that used to be difficult to reach. This allows
me to set up a different mount path for NFS v2/3 and NFS v4.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/internal.h | 2 ++
fs/nfs/nfs3proc.c | 1 +
fs/nfs/nfs4_fs.h | 2 +-
fs/nfs/nfs4proc.c | 1 +
fs/nfs/nfs4super.c | 3 ++-
fs/nfs/proc.c | 1 +
fs/nfs/super.c | 14 ++++----------
include/linux/nfs_xdr.h | 4 ++++
8 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index ac93647..3364ecc 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -328,6 +328,8 @@ extern struct file_system_type nfs_xdev_fs_type;
extern struct file_system_type nfs4_xdev_fs_type;
extern struct file_system_type nfs4_referral_fs_type;
#endif
+struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *,
+ struct nfs_subversion *);
void nfs_initialise_sb(struct super_block *);
int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 65d23eb..4f4cb8e 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -925,6 +925,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
.file_ops = &nfs_file_operations,
.getroot = nfs3_proc_get_root,
.submount = nfs_submount,
+ .try_mount = nfs_try_mount,
.getattr = nfs3_proc_getattr,
.setattr = nfs3_proc_setattr,
.lookup = nfs3_proc_lookup,
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 005558a..290762f 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -367,7 +367,7 @@ extern const nfs4_stateid zero_stateid;
/* nfs4super.c */
struct nfs_mount_info;
extern struct nfs_subversion nfs_v4;
-struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *);
+struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *);
int init_nfs_v4(void);
void exit_nfs_v4(void);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5e373c3..ac78df9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6870,6 +6870,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.file_ops = &nfs4_file_operations,
.getroot = nfs4_proc_get_root,
.submount = nfs4_submount,
+ .try_mount = nfs4_try_mount,
.getattr = nfs4_proc_getattr,
.setattr = nfs4_proc_setattr,
.lookup = nfs4_proc_lookup,
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 8a50557..9384f66 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -226,7 +226,8 @@ static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
}
struct dentry *nfs4_try_mount(int flags, const char *dev_name,
- struct nfs_mount_info *mount_info)
+ struct nfs_mount_info *mount_info,
+ struct nfs_subversion *nfs_mod)
{
char *export_path;
struct vfsmount *root_mnt;
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 4d3356af..ebb3d9c 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -774,6 +774,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
.file_ops = &nfs_file_operations,
.getroot = nfs_proc_get_root,
.submount = nfs_submount,
+ .try_mount = nfs_try_mount,
.getattr = nfs_proc_getattr,
.setattr = nfs_proc_setattr,
.lookup = nfs_proc_lookup,
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 4faefa1..5fca59d7 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1650,9 +1650,9 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
return nfs_walk_authlist(args, &request);
}
-static struct dentry *nfs_try_mount(int flags, const char *dev_name,
- struct nfs_mount_info *mount_info,
- struct nfs_subversion *nfs_mod)
+struct dentry *nfs_try_mount(int flags, const char *dev_name,
+ struct nfs_mount_info *mount_info,
+ struct nfs_subversion *nfs_mod)
{
int status;
struct nfs_server *server;
@@ -2403,15 +2403,9 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
goto out;
}
-#ifdef CONFIG_NFS_V4
- if (mount_info.parsed->version == 4)
- mntroot = nfs4_try_mount(flags, dev_name, &mount_info);
- else
-#endif /* CONFIG_NFS_V4 */
- mntroot = nfs_try_mount(flags, dev_name, &mount_info, nfs_mod);
+ mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod);
put_nfs_version(nfs_mod);
-
out:
nfs_free_parsed_mount_data(mount_info.parsed);
nfs_free_fhandle(mount_info.mntfh);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 0e181c2..bc7415b 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1353,6 +1353,8 @@ struct nfs_renamedata {
struct nfs_access_entry;
struct nfs_client;
struct rpc_timeout;
+struct nfs_subversion;
+struct nfs_mount_info;
struct nfs_client_initdata;
struct nfs_pageio_descriptor;
@@ -1370,6 +1372,8 @@ struct nfs_rpc_ops {
struct nfs_fsinfo *);
struct vfsmount *(*submount) (struct nfs_server *, struct dentry *,
struct nfs_fh *, struct nfs_fattr *);
+ struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *,
+ struct nfs_subversion *);
int (*getattr) (struct nfs_server *, struct nfs_fh *,
struct nfs_fattr *);
int (*setattr) (struct dentry *, struct nfs_fattr *,
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
This patch adds in the code to track multiple versions of the NFS
protocol. I created default structures for v2, v3 and v4 so that each
version can continue to work while I convert them into kernel modules.
I also removed the const parameter from the rpc_version array so that I
can change it at runtime.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Makefile | 4 +-
fs/nfs/client.c | 147 +++++++++++++++++++++++++++++++++++-----------
fs/nfs/inode.c | 9 +--
fs/nfs/internal.h | 10 ++--
fs/nfs/nfs.h | 72 +++++++++++++++++++++++
fs/nfs/nfs2super.c | 25 ++++++++
fs/nfs/nfs3super.c | 25 ++++++++
fs/nfs/nfs4_fs.h | 1 +
fs/nfs/nfs4client.c | 4 +-
fs/nfs/nfs4super.c | 14 ++++-
fs/nfs/super.c | 32 ++++++----
include/linux/nfs_fs_sb.h | 1 +
12 files changed, 283 insertions(+), 61 deletions(-)
create mode 100644 fs/nfs/nfs.h
create mode 100644 fs/nfs/nfs2super.c
create mode 100644 fs/nfs/nfs3super.c
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 0b96c20..66dd307 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -9,8 +9,8 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
write.o namespace.o mount_clnt.o \
dns_resolve.o cache_lib.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
-nfs-$(CONFIG_NFS_V2) += proc.o nfs2xdr.o
-nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
+nfs-$(CONFIG_NFS_V2) += nfs2super.o proc.o nfs2xdr.o
+nfs-$(CONFIG_NFS_V3) += nfs3super.o nfs3proc.o nfs3xdr.o
nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
nfs4super.o nfs4file.o delegation.o idmap.o \
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 65afa38..462de24 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -51,25 +51,23 @@
#include "internal.h"
#include "fscache.h"
#include "pnfs.h"
+#include "nfs.h"
#include "netns.h"
#define NFSDBG_FACILITY NFSDBG_CLIENT
static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
+static DEFINE_SPINLOCK(nfs_version_lock);
+static DEFINE_MUTEX(nfs_version_mutex);
+static LIST_HEAD(nfs_versions);
/*
* RPC cruft for NFS
*/
static const struct rpc_version *nfs_version[5] = {
-#ifdef CONFIG_NFS_V2
- [2] = &nfs_version2,
-#endif
-#ifdef CONFIG_NFS_V3
- [3] = &nfs_version3,
-#endif
-#ifdef CONFIG_NFS_V4
- [4] = &nfs_version4,
-#endif
+ [2] = NULL,
+ [3] = NULL,
+ [4] = NULL,
};
const struct rpc_program nfs_program = {
@@ -101,6 +99,93 @@ const struct rpc_program nfsacl_program = {
};
#endif /* CONFIG_NFS_V3_ACL */
+static struct nfs_subversion *find_nfs_version(unsigned int version)
+{
+ struct nfs_subversion *nfs;
+ spin_lock(&nfs_version_lock);
+
+ list_for_each_entry(nfs, &nfs_versions, list) {
+ if (nfs->rpc_ops->version == version) {
+ spin_unlock(&nfs_version_lock);
+ return nfs;
+ }
+ };
+
+ spin_unlock(&nfs_version_lock);
+ return ERR_PTR(-EPROTONOSUPPORT);;
+}
+
+struct nfs_subversion *get_nfs_version(unsigned int version)
+{
+ struct nfs_subversion *nfs = find_nfs_version(version);
+
+ if (IS_ERR(nfs)) {
+ mutex_lock(&nfs_version_mutex);
+ request_module("nfs%d", version);
+ nfs = find_nfs_version(version);
+ mutex_unlock(&nfs_version_mutex);
+ }
+
+ if (!IS_ERR(nfs))
+ try_module_get(nfs->owner);
+ return nfs;
+}
+
+void put_nfs_version(struct nfs_subversion *nfs)
+{
+ module_put(nfs->owner);
+}
+
+void register_nfs_version(struct nfs_subversion *nfs)
+{
+ spin_lock(&nfs_version_lock);
+
+ list_add(&nfs->list, &nfs_versions);
+ nfs_version[nfs->rpc_ops->version] = nfs->rpc_vers;
+
+ spin_unlock(&nfs_version_lock);
+}
+EXPORT_SYMBOL_GPL(register_nfs_version);
+
+void unregister_nfs_version(struct nfs_subversion *nfs)
+{
+ spin_lock(&nfs_version_lock);
+
+ nfs_version[nfs->rpc_ops->version] = NULL;
+ list_del(&nfs->list);
+
+ spin_unlock(&nfs_version_lock);
+}
+EXPORT_SYMBOL_GPL(unregister_nfs_version);
+
+/*
+ * Preload all configured NFS versions during module init.
+ * This function should be edited after each protocol is converted,
+ * and eventually removed.
+ */
+int __init nfs_register_versions(void)
+{
+ int err = init_nfs_v2();
+ if (err)
+ return err;
+
+ err = init_nfs_v3();
+ if (err)
+ return err;
+
+ return init_nfs_v4();
+}
+
+/*
+ * Remove each pre-loaded NFS version
+ */
+void nfs_unregister_versions(void)
+{
+ exit_nfs_v2();
+ exit_nfs_v3();
+ exit_nfs_v4();
+}
+
/*
* Allocate a shared client record
*
@@ -116,7 +201,10 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
goto error_0;
- clp->rpc_ops = cl_init->rpc_ops;
+ clp->cl_nfs_mod = cl_init->nfs_mod;
+ try_module_get(clp->cl_nfs_mod->owner);
+
+ clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
atomic_set(&clp->cl_count, 1);
clp->cl_cons_state = NFS_CS_INITING;
@@ -145,6 +233,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
return clp;
error_cleanup:
+ put_nfs_version(clp->cl_nfs_mod);
kfree(clp);
error_0:
return ERR_PTR(err);
@@ -205,6 +294,7 @@ void nfs_free_client(struct nfs_client *clp)
put_rpccred(clp->cl_machine_cred);
put_net(clp->cl_net);
+ put_nfs_version(clp->cl_nfs_mod);
kfree(clp->cl_hostname);
kfree(clp);
@@ -362,7 +452,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
continue;
/* Different NFS versions cannot share the same nfs_client */
- if (clp->rpc_ops != data->rpc_ops)
+ if (clp->rpc_ops != data->nfs_mod->rpc_ops)
continue;
if (clp->cl_proto != data->proto)
@@ -431,9 +521,10 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
{
struct nfs_client *clp, *new = NULL;
struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id);
+ const struct nfs_rpc_ops *rpc_ops = cl_init->nfs_mod->rpc_ops;
dprintk("--> nfs_get_client(%s,v%u)\n",
- cl_init->hostname ?: "", cl_init->rpc_ops->version);
+ cl_init->hostname ?: "", rpc_ops->version);
/* see if the client already exists */
do {
@@ -450,14 +541,13 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
list_add(&new->cl_share_link, &nn->nfs_client_list);
spin_unlock(&nn->nfs_client_lock);
new->cl_flags = cl_init->init_flags;
- return cl_init->rpc_ops->init_client(new,
- timeparms, ip_addr,
- authflavour);
+ return rpc_ops->init_client(new, timeparms, ip_addr,
+ authflavour);
}
spin_unlock(&nn->nfs_client_lock);
- new = cl_init->rpc_ops->alloc_client(cl_init);
+ new = rpc_ops->alloc_client(cl_init);
} while (!IS_ERR(new));
dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n",
@@ -714,13 +804,14 @@ error:
* Create a version 2 or 3 client
*/
static int nfs_init_server(struct nfs_server *server,
- const struct nfs_parsed_mount_data *data)
+ const struct nfs_parsed_mount_data *data,
+ struct nfs_subversion *nfs_mod)
{
struct nfs_client_initdata cl_init = {
.hostname = data->nfs_server.hostname,
.addr = (const struct sockaddr *)&data->nfs_server.address,
.addrlen = data->nfs_server.addrlen,
- .rpc_ops = NULL,
+ .nfs_mod = nfs_mod,
.proto = data->nfs_server.protocol,
.net = data->net,
};
@@ -730,21 +821,6 @@ static int nfs_init_server(struct nfs_server *server,
dprintk("--> nfs_init_server()\n");
- switch (data->version) {
-#ifdef CONFIG_NFS_V2
- case 2:
- cl_init.rpc_ops = &nfs_v2_clientops;
- break;
-#endif
-#ifdef CONFIG_NFS_V3
- case 3:
- cl_init.rpc_ops = &nfs_v3_clientops;
- break;
-#endif
- default:
- return -EPROTONOSUPPORT;
- }
-
nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
data->timeo, data->retrans);
if (data->flags & NFS_MOUNT_NORESVPORT)
@@ -1033,7 +1109,8 @@ void nfs_free_server(struct nfs_server *server)
* - keyed on server and FSID
*/
struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
- struct nfs_fh *mntfh)
+ struct nfs_fh *mntfh,
+ struct nfs_subversion *nfs_mod)
{
struct nfs_server *server;
struct nfs_fattr *fattr;
@@ -1049,7 +1126,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
goto error;
/* Get a client representation */
- error = nfs_init_server(server, data);
+ error = nfs_init_server(server, data, nfs_mod);
if (error < 0)
goto error;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 35f7e4b..e8877c8 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -50,6 +50,7 @@
#include "fscache.h"
#include "dns_resolve.h"
#include "pnfs.h"
+#include "nfs.h"
#include "netns.h"
#define NFSDBG_FACILITY NFSDBG_VFS
@@ -1671,21 +1672,17 @@ static int __init init_nfs_fs(void)
rpc_proc_register(&init_net, &nfs_rpcstat);
#endif
-#ifdef CONFIG_NFS_V4
- err = init_nfs_v4();
+ err = nfs_register_versions();
if (err)
goto out1;
-#endif
if ((err = register_nfs_fs()) != 0)
goto out0;
return 0;
out0:
-#ifdef CONFIG_NFS_V4
- exit_nfs_v4();
+ nfs_unregister_versions();
out1:
-#endif
#ifdef CONFIG_PROC_FS
rpc_proc_unregister(&init_net, "nfs");
#endif
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index cfafd13..ac93647 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -90,7 +90,7 @@ struct nfs_client_initdata {
const char *hostname;
const struct sockaddr *addr;
size_t addrlen;
- const struct nfs_rpc_ops *rpc_ops;
+ struct nfs_subversion *nfs_mod;
int proto;
u32 minorversion;
struct net *net;
@@ -189,7 +189,8 @@ nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
struct nfs4_sessionid *);
extern struct nfs_server *nfs_create_server(
const struct nfs_parsed_mount_data *,
- struct nfs_fh *);
+ struct nfs_fh *,
+ struct nfs_subversion *);
extern struct nfs_server *nfs4_create_server(
const struct nfs_parsed_mount_data *,
struct nfs_fh *);
@@ -321,6 +322,7 @@ void nfs_zap_acl_cache(struct inode *inode);
extern int nfs_wait_bit_killable(void *word);
/* super.c */
+extern struct file_system_type nfs_fs_type;
extern struct file_system_type nfs_xdev_fs_type;
#ifdef CONFIG_NFS_V4
extern struct file_system_type nfs4_xdev_fs_type;
@@ -329,8 +331,8 @@ extern struct file_system_type nfs4_referral_fs_type;
void nfs_initialise_sb(struct super_block *);
int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
-struct dentry *nfs_fs_mount_common(struct file_system_type *, struct nfs_server *,
- int, const char *, struct nfs_mount_info *);
+struct dentry *nfs_fs_mount_common(struct nfs_server *, int, const char *,
+ struct nfs_mount_info *, struct nfs_subversion *);
struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *);
struct dentry * nfs_xdev_mount_common(struct file_system_type *, int,
const char *, struct nfs_mount_info *);
diff --git a/fs/nfs/nfs.h b/fs/nfs/nfs.h
new file mode 100644
index 0000000..ac10b9e
--- /dev/null
+++ b/fs/nfs/nfs.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2012 Netapp, Inc. All rights reserved.
+ *
+ * Function and structures exported by the NFS module
+ * for use by NFS version-specific modules.
+ */
+#ifndef __LINUX_INTERNAL_NFS_H
+#define __LINUX_INTERNAL_NFS_H
+
+#include <linux/fs.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/nfs_xdr.h>
+
+struct nfs_subversion {
+ struct module *owner; /* THIS_MODULE pointer */
+ struct file_system_type *nfs_fs; /* NFS filesystem type */
+ const struct rpc_version *rpc_vers; /* NFS version information */
+ const struct nfs_rpc_ops *rpc_ops; /* NFS operations */
+ struct list_head list; /* List of NFS versions */
+};
+
+int nfs_register_versions(void);
+void nfs_unregister_versions(void);
+
+#ifdef CONFIG_NFS_V2
+int init_nfs_v2(void);
+void exit_nfs_v2(void);
+#else /* CONFIG_NFS_V2 */
+static inline int __init init_nfs_v2(void)
+{
+ return 0;
+}
+
+static inline void exit_nfs_v2(void)
+{
+}
+#endif /* CONFIG_NFS_V2 */
+
+#ifdef CONFIG_NFS_V3
+int init_nfs_v3(void);
+void exit_nfs_v3(void);
+#else /* CONFIG_NFS_V3 */
+static inline int __init init_nfs_v3(void)
+{
+ return 0;
+}
+
+static inline void exit_nfs_v3(void)
+{
+}
+#endif /* CONFIG_NFS_V3 */
+
+#ifdef CONFIG_NFS_V4
+int init_nfs_v4(void);
+void exit_nfs_v4(void);
+#else /* CONFIG_NFS_V4 */
+static inline int __init init_nfs_v4(void)
+{
+ return 0;
+}
+
+static inline void exit_nfs_v4(void)
+{
+}
+#endif /* CONFIG_NFS_V4 */
+
+struct nfs_subversion *get_nfs_version(unsigned int);
+void put_nfs_version(struct nfs_subversion *);
+void register_nfs_version(struct nfs_subversion *);
+void unregister_nfs_version(struct nfs_subversion *);
+
+#endif /* __LINUX_INTERNAL_NFS_H */
diff --git a/fs/nfs/nfs2super.c b/fs/nfs/nfs2super.c
new file mode 100644
index 0000000..cef06d4
--- /dev/null
+++ b/fs/nfs/nfs2super.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 Netapp, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/nfs_fs.h>
+#include "internal.h"
+#include "nfs.h"
+
+static struct nfs_subversion nfs_v2 = {
+ .owner = THIS_MODULE,
+ .nfs_fs = &nfs_fs_type,
+ .rpc_vers = &nfs_version2,
+ .rpc_ops = &nfs_v2_clientops,
+};
+
+int __init init_nfs_v2(void)
+{
+ register_nfs_version(&nfs_v2);
+ return 0;
+}
+
+void exit_nfs_v2(void)
+{
+ unregister_nfs_version(&nfs_v2);
+}
diff --git a/fs/nfs/nfs3super.c b/fs/nfs/nfs3super.c
new file mode 100644
index 0000000..f815cf3
--- /dev/null
+++ b/fs/nfs/nfs3super.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 Netapp, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/nfs_fs.h>
+#include "internal.h"
+#include "nfs.h"
+
+static struct nfs_subversion nfs_v3 = {
+ .owner = THIS_MODULE,
+ .nfs_fs = &nfs_fs_type,
+ .rpc_vers = &nfs_version3,
+ .rpc_ops = &nfs_v3_clientops,
+};
+
+int __init init_nfs_v3(void)
+{
+ register_nfs_version(&nfs_v3);
+ return 0;
+}
+
+void exit_nfs_v3(void)
+{
+ unregister_nfs_version(&nfs_v3);
+}
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index b1ecacd..005558a 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -366,6 +366,7 @@ extern const nfs4_stateid zero_stateid;
/* nfs4super.c */
struct nfs_mount_info;
+extern struct nfs_subversion nfs_v4;
struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *);
int init_nfs_v4(void);
void exit_nfs_v4(void);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 1c3f13c..769e798 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -357,7 +357,7 @@ static int nfs4_set_client(struct nfs_server *server,
.hostname = hostname,
.addr = addr,
.addrlen = addrlen,
- .rpc_ops = &nfs_v4_clientops,
+ .nfs_mod = &nfs_v4,
.proto = proto,
.minorversion = minorversion,
.net = net,
@@ -411,7 +411,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
struct nfs_client_initdata cl_init = {
.addr = ds_addr,
.addrlen = ds_addrlen,
- .rpc_ops = &nfs_v4_clientops,
+ .nfs_mod = &nfs_v4,
.proto = ds_proto,
.minorversion = mds_clp->cl_minorversion,
.net = mds_clp->cl_net,
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 59264fb..1f34019 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -8,6 +8,7 @@
#include <linux/nfs_fs.h>
#include "internal.h"
#include "nfs4_fs.h"
+#include "nfs.h"
#define NFSDBG_FACILITY NFSDBG_VFS
@@ -75,6 +76,13 @@ static const struct super_operations nfs4_sops = {
.remount_fs = nfs_remount,
};
+struct nfs_subversion nfs_v4 = {
+ .owner = THIS_MODULE,
+ .nfs_fs = &nfs4_fs_type,
+ .rpc_vers = &nfs_version4,
+ .rpc_ops = &nfs_v4_clientops,
+};
+
/*
* Set up an NFS4 superblock
*/
@@ -113,7 +121,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
goto out;
}
- mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info);
+ mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4);
out:
return mntroot;
@@ -293,7 +301,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
goto out;
}
- mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, &mount_info);
+ mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, &nfs_v4);
out:
nfs_free_fhandle(mount_info.mntfh);
return mntroot;
@@ -343,6 +351,7 @@ int __init init_nfs_v4(void)
if (err < 0)
goto out2;
+ register_nfs_version(&nfs_v4);
return 0;
out2:
nfs4_unregister_sysctl();
@@ -354,6 +363,7 @@ out:
void exit_nfs_v4(void)
{
+ unregister_nfs_version(&nfs_v4);
unregister_filesystem(&nfs4_fs_type);
nfs4_unregister_sysctl();
nfs_idmap_quit();
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 95866a8..61405a7 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -64,6 +64,7 @@
#include "internal.h"
#include "fscache.h"
#include "pnfs.h"
+#include "nfs.h"
#define NFSDBG_FACILITY NFSDBG_VFS
#define NFS_TEXT_DATA 1
@@ -281,7 +282,7 @@ static match_table_t nfs_vers_tokens = {
static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data);
-static struct file_system_type nfs_fs_type = {
+struct file_system_type nfs_fs_type = {
.owner = THIS_MODULE,
.name = "nfs",
.mount = nfs_fs_mount,
@@ -1650,7 +1651,8 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
}
static struct dentry *nfs_try_mount(int flags, const char *dev_name,
- struct nfs_mount_info *mount_info)
+ struct nfs_mount_info *mount_info,
+ struct nfs_subversion *nfs_mod)
{
int status;
struct nfs_server *server;
@@ -1662,11 +1664,11 @@ static struct dentry *nfs_try_mount(int flags, const char *dev_name,
}
/* Get a volume representation */
- server = nfs_create_server(mount_info->parsed, mount_info->mntfh);
+ server = nfs_create_server(mount_info->parsed, mount_info->mntfh, nfs_mod);
if (IS_ERR(server))
return ERR_CAST(server);
- return nfs_fs_mount_common(&nfs_fs_type, server, flags, dev_name, mount_info);
+ return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
}
/*
@@ -2297,10 +2299,10 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
return 0;
}
-struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
- struct nfs_server *server,
+struct dentry *nfs_fs_mount_common(struct nfs_server *server,
int flags, const char *dev_name,
- struct nfs_mount_info *mount_info)
+ struct nfs_mount_info *mount_info,
+ struct nfs_subversion *nfs_mod)
{
struct super_block *s;
struct dentry *mntroot = ERR_PTR(-ENOMEM);
@@ -2319,7 +2321,7 @@ struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
/* Get a superblock - note that we may end up sharing one that already exists */
- s = sget(fs_type, compare_super, nfs_set_super, flags, &sb_mntdata);
+ s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata);
if (IS_ERR(s)) {
mntroot = ERR_CAST(s);
goto out_err_nosb;
@@ -2378,6 +2380,7 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
.set_security = nfs_set_sb_security,
};
struct dentry *mntroot = ERR_PTR(-ENOMEM);
+ struct nfs_subversion *nfs_mod;
int error;
mount_info.parsed = nfs_alloc_parsed_mount_data();
@@ -2394,12 +2397,20 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
goto out;
}
+ nfs_mod = get_nfs_version(mount_info.parsed->version);
+ if (IS_ERR(nfs_mod)) {
+ mntroot = ERR_CAST(nfs_mod);
+ goto out;
+ }
+
#ifdef CONFIG_NFS_V4
if (mount_info.parsed->version == 4)
mntroot = nfs4_try_mount(flags, dev_name, &mount_info);
else
#endif /* CONFIG_NFS_V4 */
- mntroot = nfs_try_mount(flags, dev_name, &mount_info);
+ mntroot = nfs_try_mount(flags, dev_name, &mount_info, nfs_mod);
+
+ put_nfs_version(nfs_mod);
out:
nfs_free_parsed_mount_data(mount_info.parsed);
@@ -2440,6 +2451,7 @@ nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
struct nfs_clone_mount *data = mount_info->cloned;
struct nfs_server *server;
struct dentry *mntroot = ERR_PTR(-ENOMEM);
+ struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod;
int error;
dprintk("--> nfs_xdev_mount_common()\n");
@@ -2453,7 +2465,7 @@ nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
goto out_err;
}
- mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info);
+ mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
dprintk("<-- nfs_xdev_mount_common() = 0\n");
out:
return mntroot;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 6532765..6039297 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -48,6 +48,7 @@ struct nfs_client {
struct rpc_clnt * cl_rpcclient;
const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */
int cl_proto; /* Network transport protocol */
+ struct nfs_subversion * cl_nfs_mod; /* pointer to nfs version module */
u32 cl_minorversion;/* NFSv4 minorversion */
struct rpc_cred *cl_machine_cred;
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
This patch exports symbols and moves over the final structures needed by
the v3 module. In addition, I also switch over to using IS_ENABLED() to
check if CONFIG_NFS_V3 or CONFIG_NFS_V3_MODULE are set.
The module (nfs3.ko) will be created in the same directory as nfs.ko and
will be automatically loaded the first time you try to mount over NFS v3.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Kconfig | 2 +-
fs/nfs/Makefile | 6 ++++--
fs/nfs/client.c | 5 -----
fs/nfs/dir.c | 1 +
fs/nfs/direct.c | 2 +-
fs/nfs/inode.c | 3 +++
fs/nfs/internal.h | 2 +-
fs/nfs/nfs.h | 14 --------------
fs/nfs/nfs3super.c | 9 +++++++--
fs/nfs/super.c | 6 +++---
fs/nfs/write.c | 8 ++++----
11 files changed, 25 insertions(+), 33 deletions(-)
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 6764dbf..f81a729 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -40,7 +40,7 @@ config NFS_V2
If unsure, say Y.
config NFS_V3
- bool "NFS client support for NFS version 3"
+ tristate "NFS client support for NFS version 3"
depends on NFS_FS
default y
help
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index df61db4..01846ed 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -9,8 +9,6 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
write.o namespace.o mount_clnt.o \
dns_resolve.o cache_lib.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
-nfs-$(CONFIG_NFS_V3) += nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
-nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
nfs4super.o nfs4file.o delegation.o idmap.o \
callback.o callback_xdr.o callback_proc.o \
@@ -27,6 +25,10 @@ nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
obj-$(CONFIG_NFS_V2) += nfs2.o
nfs2-y := nfs2super.o proc.o nfs2xdr.o
+obj-$(CONFIG_NFS_V3) += nfs3.o
+nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
+nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
+
obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index fa8acf5..8687b6b 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -149,10 +149,6 @@ EXPORT_SYMBOL_GPL(unregister_nfs_version);
*/
int __init nfs_register_versions(void)
{
- int err = init_nfs_v3();
- if (err)
- return err;
-
return init_nfs_v4();
}
@@ -161,7 +157,6 @@ int __init nfs_register_versions(void)
*/
void nfs_unregister_versions(void)
{
- exit_nfs_v3();
exit_nfs_v4();
}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index c382a6d..55438c9 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1981,6 +1981,7 @@ void nfs_access_zap_cache(struct inode *inode)
spin_unlock(&nfs_access_lru_lock);
nfs_access_free_list(&head);
}
+EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
{
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 4825337..a947484 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -460,7 +460,7 @@ static void nfs_inode_dio_write_done(struct inode *inode)
inode_dio_done(inode);
}
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
{
struct nfs_pageio_descriptor desc;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f358b97..78dfc3e 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -186,6 +186,7 @@ void nfs_zap_acl_cache(struct inode *inode)
NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL;
spin_unlock(&inode->i_lock);
}
+EXPORT_SYMBOL_GPL(nfs_zap_acl_cache);
void nfs_invalidate_atime(struct inode *inode)
{
@@ -847,6 +848,7 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
return NFS_STALE(inode) ? -ESTALE : 0;
return __nfs_revalidate_inode(server, inode);
}
+EXPORT_SYMBOL_GPL(nfs_revalidate_inode);
static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
{
@@ -1213,6 +1215,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
spin_unlock(&inode->i_lock);
return status;
}
+EXPORT_SYMBOL_GPL(nfs_post_op_update_inode);
/**
* nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 4174faf..64f0dc4 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -224,7 +224,7 @@ int nfs_sockaddr_match_ipaddr(const struct sockaddr *, const struct sockaddr *);
#endif
/* nfs3client.c */
-#ifdef CONFIG_NFS_V3
+#if IS_ENABLED(CONFIG_NFS_V3)
struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *);
struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *,
struct nfs_fattr *, rpc_authflavor_t);
diff --git a/fs/nfs/nfs.h b/fs/nfs/nfs.h
index f5d1cf5..3e1b84b 100644
--- a/fs/nfs/nfs.h
+++ b/fs/nfs/nfs.h
@@ -24,20 +24,6 @@ struct nfs_subversion {
int nfs_register_versions(void);
void nfs_unregister_versions(void);
-#ifdef CONFIG_NFS_V3
-int init_nfs_v3(void);
-void exit_nfs_v3(void);
-#else /* CONFIG_NFS_V3 */
-static inline int __init init_nfs_v3(void)
-{
- return 0;
-}
-
-static inline void exit_nfs_v3(void)
-{
-}
-#endif /* CONFIG_NFS_V3 */
-
#ifdef CONFIG_NFS_V4
int init_nfs_v4(void);
void exit_nfs_v4(void);
diff --git a/fs/nfs/nfs3super.c b/fs/nfs/nfs3super.c
index 8378090..cc471c7 100644
--- a/fs/nfs/nfs3super.c
+++ b/fs/nfs/nfs3super.c
@@ -14,13 +14,18 @@ static struct nfs_subversion nfs_v3 = {
.sops = &nfs_sops,
};
-int __init init_nfs_v3(void)
+static int __init init_nfs_v3(void)
{
register_nfs_version(&nfs_v3);
return 0;
}
-void exit_nfs_v3(void)
+static void __exit exit_nfs_v3(void)
{
unregister_nfs_version(&nfs_v3);
}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_nfs_v3);
+module_exit(exit_nfs_v3);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 999ce75..558a85c 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -69,7 +69,7 @@
#define NFSDBG_FACILITY NFSDBG_VFS
#define NFS_TEXT_DATA 1
-#ifdef CONFIG_NFS_V3
+#if IS_ENABLED(CONFIG_NFS_V3)
#define NFS_DEFAULT_VERSION 3
#else
#define NFS_DEFAULT_VERSION 2
@@ -1876,7 +1876,7 @@ static int nfs23_validate_mount_data(void *options,
return NFS_TEXT_DATA;
}
-#ifndef CONFIG_NFS_V3
+#if !IS_ENABLED(CONFIG_NFS_V3)
if (args->version == 3)
goto out_v3_not_compiled;
#endif /* !CONFIG_NFS_V3 */
@@ -1896,7 +1896,7 @@ out_no_sec:
dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
return -EINVAL;
-#ifndef CONFIG_NFS_V3
+#if !IS_ENABLED(CONFIG_NFS_V3)
out_v3_not_compiled:
dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n");
return -EPROTONOSUPPORT;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 1e8d4b0..f268fe4 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -446,7 +446,7 @@ nfs_mark_request_dirty(struct nfs_page *req)
__set_page_dirty_nobuffers(req->wb_page);
}
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
/**
* nfs_request_add_commit_list - add request to a commit list
* @req: pointer to a struct nfs_page
@@ -636,7 +636,7 @@ out:
hdr->release(hdr);
}
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
static unsigned long
nfs_reqs_to_commit(struct nfs_commit_info *cinfo)
{
@@ -1298,7 +1298,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
return;
nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, resp->count);
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
if (resp->verf->committed < argp->stable && task->tk_status >= 0) {
/* We tried a write call, but the server did not
* commit data to stable storage even though we
@@ -1358,7 +1358,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
}
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+#if IS_ENABLED(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
{
int ret;
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
The module (nfs2.ko) will be created in the same directory as nfs.ko and
will be automatically loaded the first time you try to mount over NFS v2.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Kconfig | 2 +-
fs/nfs/Makefile | 4 +++-
fs/nfs/client.c | 12 ++++++------
fs/nfs/dir.c | 13 +++++++++++++
fs/nfs/file.c | 2 ++
fs/nfs/inode.c | 10 ++++++++++
fs/nfs/namespace.c | 2 ++
fs/nfs/nfs.h | 14 --------------
fs/nfs/nfs2super.c | 9 +++++++--
fs/nfs/read.c | 1 +
fs/nfs/super.c | 3 +++
fs/nfs/write.c | 2 ++
12 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 404c6a8..6764dbf 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -30,7 +30,7 @@ config NFS_FS
If unsure, say N.
config NFS_V2
- bool "NFS client support for NFS version 2"
+ tristate "NFS client support for NFS version 2"
depends on NFS_FS
default y
help
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 7ca0125..df61db4 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -9,7 +9,6 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
write.o namespace.o mount_clnt.o \
dns_resolve.o cache_lib.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
-nfs-$(CONFIG_NFS_V2) += nfs2super.o proc.o nfs2xdr.o
nfs-$(CONFIG_NFS_V3) += nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
@@ -25,6 +24,9 @@ endif
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
+obj-$(CONFIG_NFS_V2) += nfs2.o
+nfs2-y := nfs2super.o proc.o nfs2xdr.o
+
obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 1f29082..fa8acf5 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -149,11 +149,7 @@ EXPORT_SYMBOL_GPL(unregister_nfs_version);
*/
int __init nfs_register_versions(void)
{
- int err = init_nfs_v2();
- if (err)
- return err;
-
- err = init_nfs_v3();
+ int err = init_nfs_v3();
if (err)
return err;
@@ -165,7 +161,6 @@ int __init nfs_register_versions(void)
*/
void nfs_unregister_versions(void)
{
- exit_nfs_v2();
exit_nfs_v3();
exit_nfs_v4();
}
@@ -222,6 +217,7 @@ error_cleanup:
error_0:
return ERR_PTR(err);
}
+EXPORT_SYMBOL_GPL(nfs_alloc_client);
#ifdef CONFIG_NFS_V4
/* idr_remove_all is not needed as all id's are removed by nfs_put_client */
@@ -284,6 +280,7 @@ void nfs_free_client(struct nfs_client *clp)
dprintk("<-- nfs_free_client()\n");
}
+EXPORT_SYMBOL_GPL(nfs_free_client);
/*
* Release a reference to a shared client record
@@ -753,6 +750,7 @@ error:
dprintk("<-- nfs_init_client() = xerror %d\n", error);
return ERR_PTR(error);
}
+EXPORT_SYMBOL_GPL(nfs_init_client);
/*
* Create a version 2 or 3 client
@@ -1122,6 +1120,7 @@ error:
nfs_free_server(server);
return ERR_PTR(error);
}
+EXPORT_SYMBOL_GPL(nfs_create_server);
/*
* Clone an NFS2, NFS3 or NFS4 server record
@@ -1191,6 +1190,7 @@ out_free_server:
dprintk("<-- nfs_clone_server() = error %d\n", error);
return ERR_PTR(error);
}
+EXPORT_SYMBOL_GPL(nfs_clone_server);
void nfs_clients_init(struct net *net)
{
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index d49f1b9..c382a6d 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -17,6 +17,7 @@
* 6 Jun 1999 Cache readdir lookups in the page cache. -DaveM
*/
+#include <linux/module.h>
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/stat.h>
@@ -1196,6 +1197,7 @@ const struct dentry_operations nfs_dentry_operations = {
.d_automount = nfs_d_automount,
.d_release = nfs_d_release,
};
+EXPORT_SYMBOL_GPL(nfs_dentry_operations);
struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
{
@@ -1263,6 +1265,7 @@ out:
nfs_free_fhandle(fhandle);
return res;
}
+EXPORT_SYMBOL_GPL(nfs_lookup);
#ifdef CONFIG_NFS_V4
static int nfs4_lookup_revalidate(struct dentry *, unsigned int);
@@ -1508,6 +1511,7 @@ out_error:
dput(parent);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_instantiate);
/*
* Following a failed create operation, we drop the dentry rather
@@ -1536,6 +1540,7 @@ out_err:
d_drop(dentry);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_create);
/*
* See comments for nfs_proc_create regarding failed operations.
@@ -1563,6 +1568,7 @@ out_err:
d_drop(dentry);
return status;
}
+EXPORT_SYMBOL_GPL(nfs_mknod);
/*
* See comments for nfs_proc_create regarding failed operations.
@@ -1586,6 +1592,7 @@ out_err:
d_drop(dentry);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_mkdir);
static void nfs_dentry_handle_enoent(struct dentry *dentry)
{
@@ -1609,6 +1616,7 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry)
return error;
}
+EXPORT_SYMBOL_GPL(nfs_rmdir);
/*
* Remove a file after making sure there are no pending writes,
@@ -1680,6 +1688,7 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
d_rehash(dentry);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_unlink);
/*
* To create a symbolic link, most file systems instantiate a new inode,
@@ -1750,6 +1759,7 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
return 0;
}
+EXPORT_SYMBOL_GPL(nfs_symlink);
int
nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
@@ -1771,6 +1781,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
}
return error;
}
+EXPORT_SYMBOL_GPL(nfs_link);
/*
* RENAME
@@ -1869,6 +1880,7 @@ out:
dput(dentry);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_rename);
static DEFINE_SPINLOCK(nfs_access_lru_lock);
static LIST_HEAD(nfs_access_lru_list);
@@ -2188,6 +2200,7 @@ out_notsup:
res = generic_permission(inode, mask);
goto out;
}
+EXPORT_SYMBOL_GPL(nfs_permission);
/*
* Local variables:
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 70d124a..130a7bb 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -16,6 +16,7 @@
* nfs regular file handling functions
*/
+#include <linux/module.h>
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -862,3 +863,4 @@ const struct file_operations nfs_file_operations = {
.check_flags = nfs_check_flags,
.setlease = nfs_setlease,
};
+EXPORT_SYMBOL_GPL(nfs_file_operations);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index a6ffa4b..f358b97 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -193,6 +193,7 @@ void nfs_invalidate_atime(struct inode *inode)
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
spin_unlock(&inode->i_lock);
}
+EXPORT_SYMBOL_GPL(nfs_invalidate_atime);
/*
* Invalidate, but do not unhash, the inode.
@@ -438,6 +439,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
out:
return error;
}
+EXPORT_SYMBOL_GPL(nfs_setattr);
/**
* nfs_vmtruncate - unmap mappings "freed" by truncate() syscall
@@ -496,6 +498,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
nfs_vmtruncate(inode, attr->ia_size);
}
}
+EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
@@ -535,6 +538,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
out:
return err;
}
+EXPORT_SYMBOL_GPL(nfs_getattr);
static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
{
@@ -623,6 +627,7 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
return;
nfs_revalidate_inode(server, inode);
}
+EXPORT_SYMBOL_GPL(nfs_close_context);
struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode)
{
@@ -1028,6 +1033,7 @@ void nfs_fattr_init(struct nfs_fattr *fattr)
fattr->owner_name = NULL;
fattr->group_name = NULL;
}
+EXPORT_SYMBOL_GPL(nfs_fattr_init);
struct nfs_fattr *nfs_alloc_fattr(void)
{
@@ -1038,6 +1044,7 @@ struct nfs_fattr *nfs_alloc_fattr(void)
nfs_fattr_init(fattr);
return fattr;
}
+EXPORT_SYMBOL_GPL(nfs_alloc_fattr);
struct nfs_fh *nfs_alloc_fhandle(void)
{
@@ -1048,6 +1055,7 @@ struct nfs_fh *nfs_alloc_fhandle(void)
fh->size = 0;
return fh;
}
+EXPORT_SYMBOL_GPL(nfs_alloc_fhandle);
#ifdef NFS_DEBUG
/*
@@ -1168,6 +1176,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
return status;
}
+EXPORT_SYMBOL_GPL(nfs_refresh_inode);
static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
{
@@ -1255,6 +1264,7 @@ out_noforce:
spin_unlock(&inode->i_lock);
return status;
}
+EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
/*
* Many nfs protocol calls return the new file attributes after
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 0f699fe..2a3b170 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -7,6 +7,7 @@
* NFS namespace
*/
+#include <linux/module.h>
#include <linux/dcache.h>
#include <linux/gfp.h>
#include <linux/mount.h>
@@ -255,3 +256,4 @@ struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry,
return nfs_do_submount(dentry, fh, fattr, server->client->cl_auth->au_flavor);
}
+EXPORT_SYMBOL_GPL(nfs_submount);
diff --git a/fs/nfs/nfs.h b/fs/nfs/nfs.h
index 9f502a0..f5d1cf5 100644
--- a/fs/nfs/nfs.h
+++ b/fs/nfs/nfs.h
@@ -24,20 +24,6 @@ struct nfs_subversion {
int nfs_register_versions(void);
void nfs_unregister_versions(void);
-#ifdef CONFIG_NFS_V2
-int init_nfs_v2(void);
-void exit_nfs_v2(void);
-#else /* CONFIG_NFS_V2 */
-static inline int __init init_nfs_v2(void)
-{
- return 0;
-}
-
-static inline void exit_nfs_v2(void)
-{
-}
-#endif /* CONFIG_NFS_V2 */
-
#ifdef CONFIG_NFS_V3
int init_nfs_v3(void);
void exit_nfs_v3(void);
diff --git a/fs/nfs/nfs2super.c b/fs/nfs/nfs2super.c
index a9fb69d..0a9782c 100644
--- a/fs/nfs/nfs2super.c
+++ b/fs/nfs/nfs2super.c
@@ -14,13 +14,18 @@ static struct nfs_subversion nfs_v2 = {
.sops = &nfs_sops,
};
-int __init init_nfs_v2(void)
+static int __init init_nfs_v2(void)
{
register_nfs_version(&nfs_v2);
return 0;
}
-void exit_nfs_v2(void)
+static void __exit exit_nfs_v2(void)
{
unregister_nfs_version(&nfs_v2);
}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_nfs_v2);
+module_exit(exit_nfs_v2);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 6267b87..b000e4c 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -113,6 +113,7 @@ void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, compl_ops,
NFS_SERVER(inode)->rsize, 0);
}
+EXPORT_SYMBOL_GPL(nfs_pageio_init_read);
void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio)
{
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 8e0da5a..999ce75 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -289,6 +289,7 @@ struct file_system_type nfs_fs_type = {
.kill_sb = nfs_kill_super,
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
};
+EXPORT_SYMBOL_GPL(nfs_fs_type);
struct file_system_type nfs_xdev_fs_type = {
.owner = THIS_MODULE,
@@ -312,6 +313,7 @@ const struct super_operations nfs_sops = {
.show_stats = nfs_show_stats,
.remount_fs = nfs_remount,
};
+EXPORT_SYMBOL_GPL(nfs_sops);
#ifdef CONFIG_NFS_V4
static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
@@ -1670,6 +1672,7 @@ struct dentry *nfs_try_mount(int flags, const char *dev_name,
return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
}
+EXPORT_SYMBOL_GPL(nfs_try_mount);
/*
* Split "dev_name" into "hostname:export_path".
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 6ddac54..1e8d4b0 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1210,6 +1210,7 @@ void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops, compl_ops,
NFS_SERVER(inode)->wsize, ioflags);
}
+EXPORT_SYMBOL_GPL(nfs_pageio_init_write);
void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio)
{
@@ -1688,6 +1689,7 @@ int nfs_wb_all(struct inode *inode)
return sync_inode(inode, &wbc);
}
+EXPORT_SYMBOL_GPL(nfs_wb_all);
int nfs_wb_page_cancel(struct inode *inode, struct page *page)
{
--
1.7.11.3
From: Bryan Schumaker <[email protected]>
Somehow I missed this in my previous patch series, but these functions
are only needed by the v4 code and should be moved to a v4-only file. I
wasn't exactly sure where I should put these functions, so I moved them
into nfs4super.c where I could make them static.
Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/inode.c | 23 +----------------------
fs/nfs/internal.h | 4 +---
fs/nfs/nfs4_fs.h | 3 ---
fs/nfs/nfs4super.c | 39 +++++++++++++++++++++++++++++++++++++++
fs/nfs/write.c | 20 --------------------
5 files changed, 41 insertions(+), 48 deletions(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index e8877c8..a6ffa4b 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -106,7 +106,7 @@ u64 nfs_compat_user_ino64(u64 fileid)
return ino;
}
-static void nfs_clear_inode(struct inode *inode)
+void nfs_clear_inode(struct inode *inode)
{
/*
* The following should never happen...
@@ -1472,27 +1472,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
return -ESTALE;
}
-
-#ifdef CONFIG_NFS_V4
-
-/*
- * Clean out any remaining NFSv4 state that might be left over due
- * to open() calls that passed nfs_atomic_lookup, but failed to call
- * nfs_open().
- */
-void nfs4_evict_inode(struct inode *inode)
-{
- truncate_inode_pages(&inode->i_data, 0);
- clear_inode(inode);
- pnfs_return_layout(inode);
- pnfs_destroy_layout(NFS_I(inode));
- /* If we are holding a delegation, return it! */
- nfs_inode_return_delegation_noreclaim(inode);
- /* First call standard NFS clear_inode() code */
- nfs_clear_inode(inode);
-}
-#endif
-
struct inode *nfs_alloc_inode(struct super_block *sb)
{
struct nfs_inode *nfsi;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 17d1470..4174faf 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -319,10 +319,8 @@ extern struct workqueue_struct *nfsiod_workqueue;
extern struct inode *nfs_alloc_inode(struct super_block *sb);
extern void nfs_destroy_inode(struct inode *);
extern int nfs_write_inode(struct inode *, struct writeback_control *);
+extern void nfs_clear_inode(struct inode *);
extern void nfs_evict_inode(struct inode *);
-#ifdef CONFIG_NFS_V4
-extern void nfs4_evict_inode(struct inode *);
-#endif
void nfs_zap_acl_cache(struct inode *inode);
extern int nfs_wait_bit_killable(void *word);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 290762f..af8712d 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -205,9 +205,6 @@ extern const struct dentry_operations nfs4_dentry_operations;
int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
unsigned, umode_t, int *);
-/* write.c */
-int nfs4_write_inode(struct inode *, struct writeback_control *);
-
/* nfs4namespace.c */
rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index c70e173..1c825f3 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -6,12 +6,16 @@
#include <linux/nfs_idmap.h>
#include <linux/nfs4_mount.h>
#include <linux/nfs_fs.h>
+#include "delegation.h"
#include "internal.h"
#include "nfs4_fs.h"
+#include "pnfs.h"
#include "nfs.h"
#define NFSDBG_FACILITY NFSDBG_VFS
+static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc);
+static void nfs4_evict_inode(struct inode *inode);
static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data);
static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
@@ -75,6 +79,41 @@ struct nfs_subversion nfs_v4 = {
.xattr = nfs4_xattr_handlers,
};
+static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ int ret = nfs_write_inode(inode, wbc);
+
+ if (ret >= 0 && test_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags)) {
+ int status;
+ bool sync = true;
+
+ if (wbc->sync_mode == WB_SYNC_NONE)
+ sync = false;
+
+ status = pnfs_layoutcommit_inode(inode, sync);
+ if (status < 0)
+ return status;
+ }
+ return ret;
+}
+
+/*
+ * Clean out any remaining NFSv4 state that might be left over due
+ * to open() calls that passed nfs_atomic_lookup, but failed to call
+ * nfs_open().
+ */
+static void nfs4_evict_inode(struct inode *inode)
+{
+ truncate_inode_pages(&inode->i_data, 0);
+ clear_inode(inode);
+ pnfs_return_layout(inode);
+ pnfs_destroy_layout(NFS_I(inode));
+ /* If we are holding a delegation, return it! */
+ nfs_inode_return_delegation_noreclaim(inode);
+ /* First call standard NFS clear_inode() code */
+ nfs_clear_inode(inode);
+}
+
/*
* Get the superblock for the NFS4 root partition
*/
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f312860..6ddac54 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1674,26 +1674,6 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
return nfs_commit_unstable_pages(inode, wbc);
}
-#ifdef CONFIG_NFS_V4
-int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
-{
- int ret = nfs_write_inode(inode, wbc);
-
- if (ret >= 0 && test_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags)) {
- int status;
- bool sync = true;
-
- if (wbc->sync_mode == WB_SYNC_NONE)
- sync = false;
-
- status = pnfs_layoutcommit_inode(inode, sync);
- if (status < 0)
- return status;
- }
- return ret;
-}
-#endif
-
/*
* flush the inode to disk.
*/
--
1.7.11.3
On Thu, 02 Aug 2012 14:39:03 -0400
Bryan Schumaker <[email protected]> wrote:
> On 08/02/2012 02:33 PM, Jeff Layton wrote:
> > On Thu, 02 Aug 2012 11:26:43 -0400
> > Bryan Schumaker <[email protected]> wrote:
> >
> >> On 08/02/2012 11:20 AM, Jeff Layton wrote:
> >>> On Mon, 30 Jul 2012 16:05:15 -0400
> >>> [email protected] wrote:
> >>>
> >>>> From: Bryan Schumaker <[email protected]>
> >>>>
> >>>> This is the final set of patches to turn NFS into modules. The first patch
> >>>> creates an "nfs_subversion" structure that will represent a single NFS
> >>>> version. The next 6 patches are cleanups that the nfs_subversion structure
> >>>> allows us to put in. Finally, the last 3 patches convert v2, v3 and v4 into
> >>>> kernel modules.
> >>>>
> >>>> Changes in version 2:
> >>>> - Add a patch to keep nfs4 module parameters in the generic client. Without
> >>>> this we break backwards compatibility with older kernels.
> >>>>
> >>>> - Bryan
> >>>>
> >>>> Bryan Schumaker (10):
> >>>> NFS: Add version registering framework
> >>>> NFS: Remove the NFS v4 xdev mount function
> >>>> NFS: Create a try_mount rpc op
> >>>> NFS: Only initialize the ACL client in the v3 case
> >>>> NFS: Pass super operations and xattr handlers in the nfs_subversion
> >>>> NFS: Split out remaining NFS v4 inode functions
> >>>> NFS: Keep module parameters in the generic NFS client
> >>>> NFS: Convert v2 into a module
> >>>> NFS: Convert v3 into a module
> >>>> NFS: Convert v4 into a module
> >>>>
> >>>> fs/nfs/Kconfig | 6 +-
> >>>> fs/nfs/Makefile | 27 +++----
> >>>> fs/nfs/callback.c | 24 ------
> >>>> fs/nfs/callback.h | 2 +-
> >>>> fs/nfs/client.c | 191 +++++++++++++++++++++++++---------------------
> >>>> fs/nfs/delegation.h | 2 +-
> >>>> fs/nfs/dir.c | 20 ++++-
> >>>> fs/nfs/direct.c | 2 +-
> >>>> fs/nfs/dns_resolve.c | 4 +
> >>>> fs/nfs/file.c | 15 ++++
> >>>> fs/nfs/idmap.c | 3 -
> >>>> fs/nfs/inode.c | 105 ++++++++++++-------------
> >>>> fs/nfs/internal.h | 38 +++++----
> >>>> fs/nfs/namespace.c | 17 +----
> >>>> fs/nfs/netns.h | 2 +-
> >>>> fs/nfs/nfs.h | 29 +++++++
> >>>> fs/nfs/nfs2super.c | 31 ++++++++
> >>>> fs/nfs/nfs3client.c | 65 ++++++++++++++++
> >>>> fs/nfs/nfs3proc.c | 3 +
> >>>> fs/nfs/nfs3super.c | 31 ++++++++
> >>>> fs/nfs/nfs4_fs.h | 13 ++--
> >>>> fs/nfs/nfs4client.c | 23 ++----
> >>>> fs/nfs/nfs4proc.c | 9 +--
> >>>> fs/nfs/nfs4super.c | 106 +++++++++++++------------
> >>>> fs/nfs/nfs4xdr.c | 6 --
> >>>> fs/nfs/pagelist.c | 4 +
> >>>> fs/nfs/pnfs.c | 2 +
> >>>> fs/nfs/proc.c | 3 +
> >>>> fs/nfs/read.c | 5 ++
> >>>> fs/nfs/super.c | 172 ++++++++++++++++++++++++++++-------------
> >>>> fs/nfs/write.c | 35 +++------
> >>>> include/linux/nfs_fs.h | 6 +-
> >>>> include/linux/nfs_fs_sb.h | 7 +-
> >>>> include/linux/nfs_idmap.h | 2 +-
> >>>> include/linux/nfs_xdr.h | 9 ++-
> >>>> 35 files changed, 632 insertions(+), 387 deletions(-)
> >>>> create mode 100644 fs/nfs/nfs.h
> >>>> create mode 100644 fs/nfs/nfs2super.c
> >>>> create mode 100644 fs/nfs/nfs3client.c
> >>>> create mode 100644 fs/nfs/nfs3super.c
> >>>>
> >>>
> >>> I'm seeing a (minor?) regression that I think is probably due to these
> >>> patches. If I plug in nfs.ko, and then unplug it, I'm unable to plug it
> >>> back in again:
> >>
> >> Thanks for letting me know, I'll look into it today.
> >>
> >> - Bryan
> >>
> >
> > It was blocking some other testing so I went ahead and fixed it. It
> > looks like this was not introduced by these patches, but was a
> > long-standing bug. That patch should probably go to stable too, but I
> > haven't vetted it to make sure it'll apply cleanly to earlier kernels
> > yet.
>
> Ah, thank you!
>
> >
> > For the life of me though, I don't understand why it wasn't biting us
> > before the above set went in however...
>
> Maybe something else that was recently merged broke it?
>
> - Bryan
>
That seems to be the case. Looks like the check for a duplicate cache
name is new for SLUB as of commit 20cea968.
--
Jeff Layton <[email protected]>
On 08/02/2012 02:33 PM, Jeff Layton wrote:
> On Thu, 02 Aug 2012 11:26:43 -0400
> Bryan Schumaker <[email protected]> wrote:
>
>> On 08/02/2012 11:20 AM, Jeff Layton wrote:
>>> On Mon, 30 Jul 2012 16:05:15 -0400
>>> [email protected] wrote:
>>>
>>>> From: Bryan Schumaker <[email protected]>
>>>>
>>>> This is the final set of patches to turn NFS into modules. The first patch
>>>> creates an "nfs_subversion" structure that will represent a single NFS
>>>> version. The next 6 patches are cleanups that the nfs_subversion structure
>>>> allows us to put in. Finally, the last 3 patches convert v2, v3 and v4 into
>>>> kernel modules.
>>>>
>>>> Changes in version 2:
>>>> - Add a patch to keep nfs4 module parameters in the generic client. Without
>>>> this we break backwards compatibility with older kernels.
>>>>
>>>> - Bryan
>>>>
>>>> Bryan Schumaker (10):
>>>> NFS: Add version registering framework
>>>> NFS: Remove the NFS v4 xdev mount function
>>>> NFS: Create a try_mount rpc op
>>>> NFS: Only initialize the ACL client in the v3 case
>>>> NFS: Pass super operations and xattr handlers in the nfs_subversion
>>>> NFS: Split out remaining NFS v4 inode functions
>>>> NFS: Keep module parameters in the generic NFS client
>>>> NFS: Convert v2 into a module
>>>> NFS: Convert v3 into a module
>>>> NFS: Convert v4 into a module
>>>>
>>>> fs/nfs/Kconfig | 6 +-
>>>> fs/nfs/Makefile | 27 +++----
>>>> fs/nfs/callback.c | 24 ------
>>>> fs/nfs/callback.h | 2 +-
>>>> fs/nfs/client.c | 191 +++++++++++++++++++++++++---------------------
>>>> fs/nfs/delegation.h | 2 +-
>>>> fs/nfs/dir.c | 20 ++++-
>>>> fs/nfs/direct.c | 2 +-
>>>> fs/nfs/dns_resolve.c | 4 +
>>>> fs/nfs/file.c | 15 ++++
>>>> fs/nfs/idmap.c | 3 -
>>>> fs/nfs/inode.c | 105 ++++++++++++-------------
>>>> fs/nfs/internal.h | 38 +++++----
>>>> fs/nfs/namespace.c | 17 +----
>>>> fs/nfs/netns.h | 2 +-
>>>> fs/nfs/nfs.h | 29 +++++++
>>>> fs/nfs/nfs2super.c | 31 ++++++++
>>>> fs/nfs/nfs3client.c | 65 ++++++++++++++++
>>>> fs/nfs/nfs3proc.c | 3 +
>>>> fs/nfs/nfs3super.c | 31 ++++++++
>>>> fs/nfs/nfs4_fs.h | 13 ++--
>>>> fs/nfs/nfs4client.c | 23 ++----
>>>> fs/nfs/nfs4proc.c | 9 +--
>>>> fs/nfs/nfs4super.c | 106 +++++++++++++------------
>>>> fs/nfs/nfs4xdr.c | 6 --
>>>> fs/nfs/pagelist.c | 4 +
>>>> fs/nfs/pnfs.c | 2 +
>>>> fs/nfs/proc.c | 3 +
>>>> fs/nfs/read.c | 5 ++
>>>> fs/nfs/super.c | 172 ++++++++++++++++++++++++++++-------------
>>>> fs/nfs/write.c | 35 +++------
>>>> include/linux/nfs_fs.h | 6 +-
>>>> include/linux/nfs_fs_sb.h | 7 +-
>>>> include/linux/nfs_idmap.h | 2 +-
>>>> include/linux/nfs_xdr.h | 9 ++-
>>>> 35 files changed, 632 insertions(+), 387 deletions(-)
>>>> create mode 100644 fs/nfs/nfs.h
>>>> create mode 100644 fs/nfs/nfs2super.c
>>>> create mode 100644 fs/nfs/nfs3client.c
>>>> create mode 100644 fs/nfs/nfs3super.c
>>>>
>>>
>>> I'm seeing a (minor?) regression that I think is probably due to these
>>> patches. If I plug in nfs.ko, and then unplug it, I'm unable to plug it
>>> back in again:
>>
>> Thanks for letting me know, I'll look into it today.
>>
>> - Bryan
>>
>
> It was blocking some other testing so I went ahead and fixed it. It
> looks like this was not introduced by these patches, but was a
> long-standing bug. That patch should probably go to stable too, but I
> haven't vetted it to make sure it'll apply cleanly to earlier kernels
> yet.
Ah, thank you!
>
> For the life of me though, I don't understand why it wasn't biting us
> before the above set went in however...
Maybe something else that was recently merged broke it?
- Bryan
>
On 08/02/2012 11:20 AM, Jeff Layton wrote:
> On Mon, 30 Jul 2012 16:05:15 -0400
> [email protected] wrote:
>
>> From: Bryan Schumaker <[email protected]>
>>
>> This is the final set of patches to turn NFS into modules. The first patch
>> creates an "nfs_subversion" structure that will represent a single NFS
>> version. The next 6 patches are cleanups that the nfs_subversion structure
>> allows us to put in. Finally, the last 3 patches convert v2, v3 and v4 into
>> kernel modules.
>>
>> Changes in version 2:
>> - Add a patch to keep nfs4 module parameters in the generic client. Without
>> this we break backwards compatibility with older kernels.
>>
>> - Bryan
>>
>> Bryan Schumaker (10):
>> NFS: Add version registering framework
>> NFS: Remove the NFS v4 xdev mount function
>> NFS: Create a try_mount rpc op
>> NFS: Only initialize the ACL client in the v3 case
>> NFS: Pass super operations and xattr handlers in the nfs_subversion
>> NFS: Split out remaining NFS v4 inode functions
>> NFS: Keep module parameters in the generic NFS client
>> NFS: Convert v2 into a module
>> NFS: Convert v3 into a module
>> NFS: Convert v4 into a module
>>
>> fs/nfs/Kconfig | 6 +-
>> fs/nfs/Makefile | 27 +++----
>> fs/nfs/callback.c | 24 ------
>> fs/nfs/callback.h | 2 +-
>> fs/nfs/client.c | 191 +++++++++++++++++++++++++---------------------
>> fs/nfs/delegation.h | 2 +-
>> fs/nfs/dir.c | 20 ++++-
>> fs/nfs/direct.c | 2 +-
>> fs/nfs/dns_resolve.c | 4 +
>> fs/nfs/file.c | 15 ++++
>> fs/nfs/idmap.c | 3 -
>> fs/nfs/inode.c | 105 ++++++++++++-------------
>> fs/nfs/internal.h | 38 +++++----
>> fs/nfs/namespace.c | 17 +----
>> fs/nfs/netns.h | 2 +-
>> fs/nfs/nfs.h | 29 +++++++
>> fs/nfs/nfs2super.c | 31 ++++++++
>> fs/nfs/nfs3client.c | 65 ++++++++++++++++
>> fs/nfs/nfs3proc.c | 3 +
>> fs/nfs/nfs3super.c | 31 ++++++++
>> fs/nfs/nfs4_fs.h | 13 ++--
>> fs/nfs/nfs4client.c | 23 ++----
>> fs/nfs/nfs4proc.c | 9 +--
>> fs/nfs/nfs4super.c | 106 +++++++++++++------------
>> fs/nfs/nfs4xdr.c | 6 --
>> fs/nfs/pagelist.c | 4 +
>> fs/nfs/pnfs.c | 2 +
>> fs/nfs/proc.c | 3 +
>> fs/nfs/read.c | 5 ++
>> fs/nfs/super.c | 172 ++++++++++++++++++++++++++++-------------
>> fs/nfs/write.c | 35 +++------
>> include/linux/nfs_fs.h | 6 +-
>> include/linux/nfs_fs_sb.h | 7 +-
>> include/linux/nfs_idmap.h | 2 +-
>> include/linux/nfs_xdr.h | 9 ++-
>> 35 files changed, 632 insertions(+), 387 deletions(-)
>> create mode 100644 fs/nfs/nfs.h
>> create mode 100644 fs/nfs/nfs2super.c
>> create mode 100644 fs/nfs/nfs3client.c
>> create mode 100644 fs/nfs/nfs3super.c
>>
>
> I'm seeing a (minor?) regression that I think is probably due to these
> patches. If I plug in nfs.ko, and then unplug it, I'm unable to plug it
> back in again:
Thanks for letting me know, I'll look into it today.
- Bryan
>
> # modprobe nfs
> ERROR: could not insert 'nfs': Cannot allocate memory
>
> The following shows up in dmesg:
>
> [ 344.024976] kmem_cache_create(nfs_commit_data): Cache name already exists.
> [ 344.033771] Pid: 1377, comm: modprobe Not tainted 3.6.0-0.rc0.git8.1.fc18.x86_64 #1
> [ 344.042741] Call Trace:
> [ 344.051119] [<ffffffff811835f2>] kmem_cache_create+0x182/0x1e0
> [ 344.060250] [<ffffffffa027509b>] ? nfs_fs_proc_init+0x9b/0x9b [nfs]
> [ 344.069477] [<ffffffffa027509b>] ? nfs_fs_proc_init+0x9b/0x9b [nfs]
> [ 344.078508] [<ffffffffa027537c>] nfs_init_writepagecache+0x77/0xcfb [nfs]
> [ 344.087653] [<ffffffffa027515a>] init_nfs_fs+0xbf/0x190 [nfs]
> [ 344.096732] [<ffffffff8100212a>] do_one_initcall+0x12a/0x180
> [ 344.105755] [<ffffffff810e3636>] sys_init_module+0x156/0x2290
> [ 344.114936] [<ffffffff81359320>] ? ddebug_proc_open+0xd0/0xd0
> [ 344.123905] [<ffffffff811c5e40>] ? delayed_fput+0xb0/0xb0
> [ 344.132821] [<ffffffff816d8369>] system_call_fastpath+0x16/0x1b
> [ 344.169419] FS-Cache: Netfs 'nfs' unregistered from caching
> [ 469.258735] FS-Cache: Netfs 'nfs' registered for caching
> [ 469.281508] kmem_cache_create(nfs_write_data): Cache name already exists.
> [ 469.290690] Pid: 1386, comm: modprobe Not tainted 3.6.0-0.rc0.git8.1.fc18.x86_64 #1
> [ 469.300182] Call Trace:
> [ 469.309102] [<ffffffff811835f2>] kmem_cache_create+0x182/0x1e0
> [ 469.318609] [<ffffffffa027509b>] ? nfs_fs_proc_init+0x9b/0x9b [nfs]
> [ 469.328103] [<ffffffffa027509b>] ? nfs_fs_proc_init+0x9b/0x9b [nfs]
> [ 469.337475] [<ffffffffa0275324>] nfs_init_writepagecache+0x1f/0xcfb [nfs]
> [ 469.347034] [<ffffffffa027515a>] init_nfs_fs+0xbf/0x190 [nfs]
> [ 469.356541] [<ffffffff8100212a>] do_one_initcall+0x12a/0x180
> [ 469.366093] [<ffffffff810e3636>] sys_init_module+0x156/0x2290
> [ 469.375539] [<ffffffff81359320>] ? ddebug_proc_open+0xd0/0xd0
> [ 469.385151] [<ffffffff811c5e40>] ? delayed_fput+0xb0/0xb0
> [ 469.394555] [<ffffffff816d8369>] system_call_fastpath+0x16/0x1b
>
>
> I don't see where these are getting torn down now on module unload?
>
On Mon, 30 Jul 2012 16:05:15 -0400
[email protected] wrote:
> From: Bryan Schumaker <[email protected]>
>
> This is the final set of patches to turn NFS into modules. The first patch
> creates an "nfs_subversion" structure that will represent a single NFS
> version. The next 6 patches are cleanups that the nfs_subversion structure
> allows us to put in. Finally, the last 3 patches convert v2, v3 and v4 into
> kernel modules.
>
> Changes in version 2:
> - Add a patch to keep nfs4 module parameters in the generic client. Without
> this we break backwards compatibility with older kernels.
>
> - Bryan
>
> Bryan Schumaker (10):
> NFS: Add version registering framework
> NFS: Remove the NFS v4 xdev mount function
> NFS: Create a try_mount rpc op
> NFS: Only initialize the ACL client in the v3 case
> NFS: Pass super operations and xattr handlers in the nfs_subversion
> NFS: Split out remaining NFS v4 inode functions
> NFS: Keep module parameters in the generic NFS client
> NFS: Convert v2 into a module
> NFS: Convert v3 into a module
> NFS: Convert v4 into a module
>
> fs/nfs/Kconfig | 6 +-
> fs/nfs/Makefile | 27 +++----
> fs/nfs/callback.c | 24 ------
> fs/nfs/callback.h | 2 +-
> fs/nfs/client.c | 191 +++++++++++++++++++++++++---------------------
> fs/nfs/delegation.h | 2 +-
> fs/nfs/dir.c | 20 ++++-
> fs/nfs/direct.c | 2 +-
> fs/nfs/dns_resolve.c | 4 +
> fs/nfs/file.c | 15 ++++
> fs/nfs/idmap.c | 3 -
> fs/nfs/inode.c | 105 ++++++++++++-------------
> fs/nfs/internal.h | 38 +++++----
> fs/nfs/namespace.c | 17 +----
> fs/nfs/netns.h | 2 +-
> fs/nfs/nfs.h | 29 +++++++
> fs/nfs/nfs2super.c | 31 ++++++++
> fs/nfs/nfs3client.c | 65 ++++++++++++++++
> fs/nfs/nfs3proc.c | 3 +
> fs/nfs/nfs3super.c | 31 ++++++++
> fs/nfs/nfs4_fs.h | 13 ++--
> fs/nfs/nfs4client.c | 23 ++----
> fs/nfs/nfs4proc.c | 9 +--
> fs/nfs/nfs4super.c | 106 +++++++++++++------------
> fs/nfs/nfs4xdr.c | 6 --
> fs/nfs/pagelist.c | 4 +
> fs/nfs/pnfs.c | 2 +
> fs/nfs/proc.c | 3 +
> fs/nfs/read.c | 5 ++
> fs/nfs/super.c | 172 ++++++++++++++++++++++++++++-------------
> fs/nfs/write.c | 35 +++------
> include/linux/nfs_fs.h | 6 +-
> include/linux/nfs_fs_sb.h | 7 +-
> include/linux/nfs_idmap.h | 2 +-
> include/linux/nfs_xdr.h | 9 ++-
> 35 files changed, 632 insertions(+), 387 deletions(-)
> create mode 100644 fs/nfs/nfs.h
> create mode 100644 fs/nfs/nfs2super.c
> create mode 100644 fs/nfs/nfs3client.c
> create mode 100644 fs/nfs/nfs3super.c
>
I'm seeing a (minor?) regression that I think is probably due to these
patches. If I plug in nfs.ko, and then unplug it, I'm unable to plug it
back in again:
# modprobe nfs
ERROR: could not insert 'nfs': Cannot allocate memory
The following shows up in dmesg:
[ 344.024976] kmem_cache_create(nfs_commit_data): Cache name already exists.
[ 344.033771] Pid: 1377, comm: modprobe Not tainted 3.6.0-0.rc0.git8.1.fc18.x86_64 #1
[ 344.042741] Call Trace:
[ 344.051119] [<ffffffff811835f2>] kmem_cache_create+0x182/0x1e0
[ 344.060250] [<ffffffffa027509b>] ? nfs_fs_proc_init+0x9b/0x9b [nfs]
[ 344.069477] [<ffffffffa027509b>] ? nfs_fs_proc_init+0x9b/0x9b [nfs]
[ 344.078508] [<ffffffffa027537c>] nfs_init_writepagecache+0x77/0xcfb [nfs]
[ 344.087653] [<ffffffffa027515a>] init_nfs_fs+0xbf/0x190 [nfs]
[ 344.096732] [<ffffffff8100212a>] do_one_initcall+0x12a/0x180
[ 344.105755] [<ffffffff810e3636>] sys_init_module+0x156/0x2290
[ 344.114936] [<ffffffff81359320>] ? ddebug_proc_open+0xd0/0xd0
[ 344.123905] [<ffffffff811c5e40>] ? delayed_fput+0xb0/0xb0
[ 344.132821] [<ffffffff816d8369>] system_call_fastpath+0x16/0x1b
[ 344.169419] FS-Cache: Netfs 'nfs' unregistered from caching
[ 469.258735] FS-Cache: Netfs 'nfs' registered for caching
[ 469.281508] kmem_cache_create(nfs_write_data): Cache name already exists.
[ 469.290690] Pid: 1386, comm: modprobe Not tainted 3.6.0-0.rc0.git8.1.fc18.x86_64 #1
[ 469.300182] Call Trace:
[ 469.309102] [<ffffffff811835f2>] kmem_cache_create+0x182/0x1e0
[ 469.318609] [<ffffffffa027509b>] ? nfs_fs_proc_init+0x9b/0x9b [nfs]
[ 469.328103] [<ffffffffa027509b>] ? nfs_fs_proc_init+0x9b/0x9b [nfs]
[ 469.337475] [<ffffffffa0275324>] nfs_init_writepagecache+0x1f/0xcfb [nfs]
[ 469.347034] [<ffffffffa027515a>] init_nfs_fs+0xbf/0x190 [nfs]
[ 469.356541] [<ffffffff8100212a>] do_one_initcall+0x12a/0x180
[ 469.366093] [<ffffffff810e3636>] sys_init_module+0x156/0x2290
[ 469.375539] [<ffffffff81359320>] ? ddebug_proc_open+0xd0/0xd0
[ 469.385151] [<ffffffff811c5e40>] ? delayed_fput+0xb0/0xb0
[ 469.394555] [<ffffffff816d8369>] system_call_fastpath+0x16/0x1b
I don't see where these are getting torn down now on module unload?
--
Jeff Layton <[email protected]>
On Thu, 02 Aug 2012 11:26:43 -0400
Bryan Schumaker <[email protected]> wrote:
> On 08/02/2012 11:20 AM, Jeff Layton wrote:
> > On Mon, 30 Jul 2012 16:05:15 -0400
> > [email protected] wrote:
> >
> >> From: Bryan Schumaker <[email protected]>
> >>
> >> This is the final set of patches to turn NFS into modules. The first patch
> >> creates an "nfs_subversion" structure that will represent a single NFS
> >> version. The next 6 patches are cleanups that the nfs_subversion structure
> >> allows us to put in. Finally, the last 3 patches convert v2, v3 and v4 into
> >> kernel modules.
> >>
> >> Changes in version 2:
> >> - Add a patch to keep nfs4 module parameters in the generic client. Without
> >> this we break backwards compatibility with older kernels.
> >>
> >> - Bryan
> >>
> >> Bryan Schumaker (10):
> >> NFS: Add version registering framework
> >> NFS: Remove the NFS v4 xdev mount function
> >> NFS: Create a try_mount rpc op
> >> NFS: Only initialize the ACL client in the v3 case
> >> NFS: Pass super operations and xattr handlers in the nfs_subversion
> >> NFS: Split out remaining NFS v4 inode functions
> >> NFS: Keep module parameters in the generic NFS client
> >> NFS: Convert v2 into a module
> >> NFS: Convert v3 into a module
> >> NFS: Convert v4 into a module
> >>
> >> fs/nfs/Kconfig | 6 +-
> >> fs/nfs/Makefile | 27 +++----
> >> fs/nfs/callback.c | 24 ------
> >> fs/nfs/callback.h | 2 +-
> >> fs/nfs/client.c | 191 +++++++++++++++++++++++++---------------------
> >> fs/nfs/delegation.h | 2 +-
> >> fs/nfs/dir.c | 20 ++++-
> >> fs/nfs/direct.c | 2 +-
> >> fs/nfs/dns_resolve.c | 4 +
> >> fs/nfs/file.c | 15 ++++
> >> fs/nfs/idmap.c | 3 -
> >> fs/nfs/inode.c | 105 ++++++++++++-------------
> >> fs/nfs/internal.h | 38 +++++----
> >> fs/nfs/namespace.c | 17 +----
> >> fs/nfs/netns.h | 2 +-
> >> fs/nfs/nfs.h | 29 +++++++
> >> fs/nfs/nfs2super.c | 31 ++++++++
> >> fs/nfs/nfs3client.c | 65 ++++++++++++++++
> >> fs/nfs/nfs3proc.c | 3 +
> >> fs/nfs/nfs3super.c | 31 ++++++++
> >> fs/nfs/nfs4_fs.h | 13 ++--
> >> fs/nfs/nfs4client.c | 23 ++----
> >> fs/nfs/nfs4proc.c | 9 +--
> >> fs/nfs/nfs4super.c | 106 +++++++++++++------------
> >> fs/nfs/nfs4xdr.c | 6 --
> >> fs/nfs/pagelist.c | 4 +
> >> fs/nfs/pnfs.c | 2 +
> >> fs/nfs/proc.c | 3 +
> >> fs/nfs/read.c | 5 ++
> >> fs/nfs/super.c | 172 ++++++++++++++++++++++++++++-------------
> >> fs/nfs/write.c | 35 +++------
> >> include/linux/nfs_fs.h | 6 +-
> >> include/linux/nfs_fs_sb.h | 7 +-
> >> include/linux/nfs_idmap.h | 2 +-
> >> include/linux/nfs_xdr.h | 9 ++-
> >> 35 files changed, 632 insertions(+), 387 deletions(-)
> >> create mode 100644 fs/nfs/nfs.h
> >> create mode 100644 fs/nfs/nfs2super.c
> >> create mode 100644 fs/nfs/nfs3client.c
> >> create mode 100644 fs/nfs/nfs3super.c
> >>
> >
> > I'm seeing a (minor?) regression that I think is probably due to these
> > patches. If I plug in nfs.ko, and then unplug it, I'm unable to plug it
> > back in again:
>
> Thanks for letting me know, I'll look into it today.
>
> - Bryan
>
It was blocking some other testing so I went ahead and fixed it. It
looks like this was not introduced by these patches, but was a
long-standing bug. That patch should probably go to stable too, but I
haven't vetted it to make sure it'll apply cleanly to earlier kernels
yet.
For the life of me though, I don't understand why it wasn't biting us
before the above set went in however...
--
Jeff Layton <[email protected]>