2011-12-01 16:48:24

by Anna Schumaker

[permalink] [raw]
Subject: [RFC 0/4] NFS: Modularize NFS v3

From: Bryan Schumaker <[email protected]>

This set of patches removes NFS v3 from the main NFS kernel module and creates
a new module containing the proc, xdr, and acl code. This will give us a
single directory to put NFS v3 specific code so it doesn't need to be mixed in
with the generic client stuff.

I'm sure this could still use a lot of work, but I figured I would wait to see
what everybody thinks first. I imagine that once we get an "nfs submodule"
system working it'll be easier to convert v2 and v4 (and possibly v4.1?) to
modules.

I split the second patch into two to make it easier to see what my changes were
to get everything to compile. Hopefully this will save some pain in having to
look through 7000+ line patch that resulted from my `mv nfs3*.c nfs3/`
command. I can combine everything in a future version of the patch.

v2:
- I set the "diff.renames copy" git config option to create a smaller second
patch. Maybe this time it won't get me kicked off the mailing list...
Thanks to Boaz and Jim for the tip!

Thoughts?

- Bryan



2011-12-01 16:48:28

by Anna Schumaker

[permalink] [raw]
Subject: [RFC v2 3/4] NFS: Add functions for adding new NFS versions

From: Bryan Schumaker <[email protected]>

These functions and structures allow us to add modular NFS versions at
runtime, rather than requiring them to be compiled directly into the NFS
kernel module.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/client.c | 65 +++++++++++++++++++++++++++++++++++++++++++---
fs/nfs/file.c | 2 +
fs/nfs/internal.h | 15 +++++++++++
fs/nfs/mount_clnt.c | 1 +
fs/nfs/nfs3/nfs3proc.c | 2 +-
fs/nfs/nfs4proc.c | 2 +-
fs/nfs/proc.c | 2 +-
fs/nfs/super.c | 1 +
include/linux/nfs_xdr.h | 6 ++--
9 files changed, 85 insertions(+), 11 deletions(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index c32a21f..9e77056 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -87,6 +87,21 @@ retry:
static int nfs4_disable_idmapping = 0;

/*
+ * NFS versions
+ */
+static struct nfs_version_ops *nfs_version_ops[5] = {
+ [2] = NULL,
+ [3] = NULL,
+ [4] = NULL,
+};
+
+static struct nfs_rpc_ops *nfs_ops[5] = {
+ [2] = &nfs_v2_clientops,
+ [3] = &nfs_v3_clientops,
+ [4] = &nfs_v4_clientops,
+};
+
+/*
* RPC cruft for NFS
*/
static struct rpc_version *nfs_version[5] = {
@@ -137,6 +152,45 @@ struct nfs_client_initdata {
u32 minorversion;
};

+void nfs_register_version(unsigned int version, struct nfs_version_ops *ops)
+{
+ nfs_version_ops[version] = ops;
+ nfs_version[version] = ops->nfs_rpc;
+ nfs_ops[version] = ops->nfs_ops;
+#ifdef CONFIG_NFS_V3_ACL
+ nfsacl_version[version] = ops->nfs_acl;
+#endif
+}
+EXPORT_SYMBOL_GPL(nfs_register_version);
+
+void nfs_unregister_version(unsigned int version)
+{
+ struct nfs_version_ops *ops = nfs_version_ops[version];
+ if (ops != NULL) {
+ nfs_version_ops[version] = NULL;
+ nfs_version[version] = NULL;
+ nfs_ops[version] = NULL;
+#ifdef CONFIG_NFS_V3_ACL
+ nfsacl_version[version] = NULL;
+#endif
+ }
+}
+EXPORT_SYMBOL_GPL(nfs_unregister_version);
+
+void nfs_version_ref(unsigned int version)
+{
+ struct nfs_version_ops *nfs = nfs_version_ops[version];
+ if (nfs != NULL)
+ nfs->version_ref();
+}
+
+void nfs_version_unref(unsigned int version)
+{
+ struct nfs_version_ops *nfs = nfs_version_ops[version];
+ if (nfs != NULL)
+ nfs->version_unref();
+}
+
/*
* Allocate a shared client record
*
@@ -825,7 +879,7 @@ static int nfs_init_server(struct nfs_server *server,
.hostname = data->nfs_server.hostname,
.addr = (const struct sockaddr *)&data->nfs_server.address,
.addrlen = data->nfs_server.addrlen,
- .rpc_ops = &nfs_v2_clientops,
+ .rpc_ops = nfs_ops[data->version],
.proto = data->nfs_server.protocol,
};
struct rpc_timeout timeparms;
@@ -834,10 +888,10 @@ static int nfs_init_server(struct nfs_server *server,

dprintk("--> nfs_init_server()\n");

-#ifdef CONFIG_NFS_V3
- if (data->version == 3)
- cl_init.rpc_ops = &nfs_v3_clientops;
-#endif
+ if (cl_init.rpc_ops == NULL) {
+ error = -EPROTONOSUPPORT;
+ goto out;
+ }

nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
data->timeo, data->retrans);
@@ -899,6 +953,7 @@ static int nfs_init_server(struct nfs_server *server,
error:
server->nfs_client = NULL;
nfs_put_client(clp);
+out:
dprintk("<-- nfs_init_server() = xerror %d\n", error);
return error;
}
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index eca56d4..90389ca 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -19,6 +19,7 @@
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/export.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/nfs_fs.h>
@@ -865,6 +866,7 @@ const struct file_operations nfs_file_operations = {
.check_flags = nfs_check_flags,
.setlease = nfs_setlease,
};
+EXPORT_SYMBOL_GPL(nfs_file_operations);

#ifdef CONFIG_NFS_V4
static int
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 3f4d957..93a0ba2 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -68,6 +68,21 @@ struct nfs_clone_mount {
rpc_authflavor_t authflavor;
};

+struct nfs_version_ops {
+ struct rpc_version *nfs_rpc;
+ struct nfs_rpc_ops *nfs_ops;
+#ifdef CONFIG_NFS_V3_ACL
+ struct rpc_version *nfs_acl;
+#endif
+ void (*version_ref)(void);
+ void (*version_unref)(void);
+};
+
+void nfs_register_version(unsigned int, struct nfs_version_ops *);
+void nfs_unregister_version(unsigned int);
+void nfs_version_ref(unsigned int);
+void nfs_version_unref(unsigned int);
+
/*
* Note: RFC 1813 doesn't limit the number of auth flavors that
* a server can return, so make something up.
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index d4c2d6b..323a105 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -190,6 +190,7 @@ int nfs_mount(struct nfs_mount_request *info)
goto out_mnt_err;

dprintk("NFS: MNT request succeeded\n");
+ nfs_version_ref(info->version);
status = 0;

out:
diff --git a/fs/nfs/nfs3/nfs3proc.c b/fs/nfs/nfs3/nfs3proc.c
index f37ddb9..593a44c 100644
--- a/fs/nfs/nfs3/nfs3proc.c
+++ b/fs/nfs/nfs3/nfs3proc.c
@@ -848,7 +848,7 @@ nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
}

-const struct nfs_rpc_ops nfs_v3_clientops = {
+struct nfs_rpc_ops nfs_v3_clientops = {
.version = 3, /* protocol version */
.dentry_ops = &nfs_dentry_operations,
.dir_inode_ops = &nfs3_dir_inode_operations,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index be2bbac..58bb8d2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6247,7 +6247,7 @@ static const struct inode_operations nfs4_file_inode_operations = {
.removexattr = generic_removexattr,
};

-const struct nfs_rpc_ops nfs_v4_clientops = {
+struct nfs_rpc_ops nfs_v4_clientops = {
.version = 4, /* protocol version */
.dentry_ops = &nfs4_dentry_operations,
.dir_inode_ops = &nfs4_dir_inode_operations,
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index f48125d..d3eb291 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -705,7 +705,7 @@ out_einval:
return -EINVAL;
}

-const struct nfs_rpc_ops nfs_v2_clientops = {
+struct nfs_rpc_ops nfs_v2_clientops = {
.version = 2, /* protocol version */
.dentry_ops = &nfs_dentry_operations,
.dir_inode_ops = &nfs_dir_inode_operations,
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 1347774..96967ff 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2334,6 +2334,7 @@ static void nfs_kill_super(struct super_block *s)

kill_anon_super(s);
nfs_fscache_release_super_cookie(s);
+ nfs_version_unref(server->nfs_client->rpc_ops->version);
nfs_free_server(server);
}

diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 2a7c533..6004f5c 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1260,9 +1260,9 @@ struct nfs_rpc_ops {
/*
* Function vectors etc. for the NFS client
*/
-extern const struct nfs_rpc_ops nfs_v2_clientops;
-extern const struct nfs_rpc_ops nfs_v3_clientops;
-extern const struct nfs_rpc_ops nfs_v4_clientops;
+extern struct nfs_rpc_ops nfs_v2_clientops;
+extern struct nfs_rpc_ops nfs_v3_clientops;
+extern struct nfs_rpc_ops nfs_v4_clientops;
extern struct rpc_version nfs_version2;
extern struct rpc_version nfs_version3;
extern struct rpc_version nfs_version4;
--
1.7.7.4


2011-12-01 16:48:26

by Anna Schumaker

[permalink] [raw]
Subject: [RFC v2 2/4] NFS: Move the NFS v3 code into its own subdirectory

From: Bryan Schumaker <[email protected]>

Note that after applying this patch NFS v3 is still directly compiled
into the main NFS kernel module. The changes to turn it into a module
will come in a later patch.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Makefile | 4 ++--
fs/nfs/{ => nfs3}/nfs3acl.c | 2 +-
fs/nfs/{ => nfs3}/nfs3proc.c | 4 ++--
fs/nfs/{ => nfs3}/nfs3xdr.c | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
rename fs/nfs/{ => nfs3}/nfs3acl.c (99%)
rename fs/nfs/{ => nfs3}/nfs3proc.c (99%)
rename fs/nfs/{ => nfs3}/nfs3xdr.c (99%)

diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index b58613d..ac0e5df 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 nfs2xdr.o \
write.o namespace.o mount_clnt.o \
dns_resolve.o cache_lib.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
-nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
-nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
+nfs-$(CONFIG_NFS_V3) += nfs3/nfs3proc.o nfs3/nfs3xdr.o
+nfs-$(CONFIG_NFS_V3_ACL) += nfs3/nfs3acl.o
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
delegation.o idmap.o \
callback.o callback_xdr.o callback_proc.o \
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3/nfs3acl.c
similarity index 99%
rename from fs/nfs/nfs3acl.c
rename to fs/nfs/nfs3/nfs3acl.c
index 7ef2397..ac589ff 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3/nfs3acl.c
@@ -6,7 +6,7 @@
#include <linux/posix_acl_xattr.h>
#include <linux/nfsacl.h>

-#include "internal.h"
+#include "../internal.h"

#define NFSDBG_FACILITY NFSDBG_PROC

diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3/nfs3proc.c
similarity index 99%
rename from fs/nfs/nfs3proc.c
rename to fs/nfs/nfs3/nfs3proc.c
index d4bc9ed9..f37ddb9 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3/nfs3proc.c
@@ -18,8 +18,8 @@
#include <linux/lockd/bind.h>
#include <linux/nfs_mount.h>

-#include "iostat.h"
-#include "internal.h"
+#include "../iostat.h"
+#include "../internal.h"

#define NFSDBG_FACILITY NFSDBG_PROC

diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3/nfs3xdr.c
similarity index 99%
rename from fs/nfs/nfs3xdr.c
rename to fs/nfs/nfs3/nfs3xdr.c
index 183c6b1..be27fb8 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3/nfs3xdr.c
@@ -20,7 +20,7 @@
#include <linux/nfs3.h>
#include <linux/nfs_fs.h>
#include <linux/nfsacl.h>
-#include "internal.h"
+#include "../internal.h"

#define NFSDBG_FACILITY NFSDBG_XDR

--
1.7.7.4


2011-12-01 16:48:26

by Anna Schumaker

[permalink] [raw]
Subject: [RFC v2 1/4] NFS: Export symbols needed by an NFS v3 module

From: Bryan Schumaker <[email protected]>

These are functions and structures used by the NFS v3 code that needs to
be available once it has been moved to its own module.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/client.c | 1 +
fs/nfs/dir.c | 50 ++++++++++++++++++++++++++++++++------------------
fs/nfs/inode.c | 12 ++++++++++++
fs/nfs/nfs2xdr.c | 2 ++
4 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 873bf00..c32a21f 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -813,6 +813,7 @@ error:
dprintk("<-- nfs_init_client() = xerror %d\n", error);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_init_client);

/*
* Create a version 2 or 3 client
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ac28990..f7cb6b6 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -19,6 +19,7 @@

#include <linux/time.h>
#include <linux/errno.h>
+#include <linux/export.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/string.h>
@@ -46,15 +47,15 @@
static int nfs_opendir(struct inode *, struct file *);
static int nfs_closedir(struct inode *, struct file *);
static int nfs_readdir(struct file *, void *, filldir_t);
-static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
-static int nfs_create(struct inode *, struct dentry *, int, struct nameidata *);
-static int nfs_mkdir(struct inode *, struct dentry *, int);
-static int nfs_rmdir(struct inode *, struct dentry *);
-static int nfs_unlink(struct inode *, struct dentry *);
-static int nfs_symlink(struct inode *, struct dentry *, const char *);
-static int nfs_link(struct dentry *, struct inode *, struct dentry *);
-static int nfs_mknod(struct inode *, struct dentry *, int, dev_t);
-static int nfs_rename(struct inode *, struct dentry *,
+struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
+int nfs_create(struct inode *, struct dentry *, int, struct nameidata *);
+int nfs_mkdir(struct inode *, struct dentry *, int);
+int nfs_rmdir(struct inode *, struct dentry *);
+int nfs_unlink(struct inode *, struct dentry *);
+int nfs_symlink(struct inode *, struct dentry *, const char *);
+int nfs_link(struct dentry *, struct inode *, struct dentry *);
+int nfs_mknod(struct inode *, struct dentry *, int, dev_t);
+int nfs_rename(struct inode *, struct dentry *,
struct inode *, struct dentry *);
static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
@@ -1262,8 +1263,9 @@ const struct dentry_operations nfs_dentry_operations = {
.d_automount = nfs_d_automount,
.d_release = nfs_d_release,
};
+EXPORT_SYMBOL_GPL(nfs_dentry_operations);

-static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
{
struct dentry *res;
struct dentry *parent;
@@ -1326,6 +1328,7 @@ out:
nfs_free_fhandle(fhandle);
return res;
}
+EXPORT_SYMBOL_GPL(nfs_lookup);

#ifdef CONFIG_NFS_V4
static int nfs_open_revalidate(struct dentry *, struct nameidata *);
@@ -1668,6 +1671,7 @@ out_error:
dput(parent);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_instantiate);

/*
* Following a failed create operation, we drop the dentry rather
@@ -1675,7 +1679,7 @@ out_error:
* that the operation succeeded on the server, but an error in the
* reply path made it appear to have failed.
*/
-static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
+int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
struct nameidata *nd)
{
struct iattr attr;
@@ -1699,11 +1703,12 @@ out_err:
d_drop(dentry);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_create);

/*
* See comments for nfs_proc_create regarding failed operations.
*/
-static int
+int
nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
{
struct iattr attr;
@@ -1726,11 +1731,12 @@ out_err:
d_drop(dentry);
return status;
}
+EXPORT_SYMBOL_GPL(nfs_mknod);

/*
* See comments for nfs_proc_create regarding failed operations.
*/
-static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
struct iattr attr;
int error;
@@ -1749,6 +1755,7 @@ out_err:
d_drop(dentry);
return error;
}
+EXPORT_SYMBOL_GPL(nfs_mkdir);

static void nfs_dentry_handle_enoent(struct dentry *dentry)
{
@@ -1756,7 +1763,7 @@ static void nfs_dentry_handle_enoent(struct dentry *dentry)
d_delete(dentry);
}

-static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
+int nfs_rmdir(struct inode *dir, struct dentry *dentry)
{
int error;

@@ -1772,6 +1779,7 @@ static 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,
@@ -1815,7 +1823,7 @@ out:
*
* If sillyrename() returns 0, we do nothing, otherwise we unlink.
*/
-static int nfs_unlink(struct inode *dir, struct dentry *dentry)
+int nfs_unlink(struct inode *dir, struct dentry *dentry)
{
int error;
int need_rehash = 0;
@@ -1843,6 +1851,7 @@ static 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,
@@ -1859,7 +1868,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
* now have a new file handle and can instantiate an in-core NFS inode
* and move the raw page into its mapping.
*/
-static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
{
struct pagevec lru_pvec;
struct page *page;
@@ -1913,8 +1922,9 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym

return 0;
}
+EXPORT_SYMBOL_GPL(nfs_symlink);

-static int
+int
nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
{
struct inode *inode = old_dentry->d_inode;
@@ -1934,6 +1944,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
}
return error;
}
+EXPORT_SYMBOL_GPL(nfs_link);

/*
* RENAME
@@ -1959,7 +1970,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
* If these conditions are met, we can drop the dentries before doing
* the rename.
*/
-static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
struct inode *old_inode = old_dentry->d_inode;
@@ -2032,6 +2043,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);
@@ -2132,6 +2144,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)
{
@@ -2351,6 +2364,7 @@ out_notsup:
res = generic_permission(inode, mask);
goto out;
}
+EXPORT_SYMBOL_GPL(nfs_permission);

/*
* Local variables:
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 50a15fa..2a4f55d 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -184,6 +184,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)
{
@@ -191,6 +192,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.
@@ -444,6 +446,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
@@ -502,6 +505,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)
{
@@ -540,6 +544,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)
{
@@ -628,6 +633,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, struct rpc_cred *cred, fmode_t f_mode)
{
@@ -845,6 +851,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)
{
@@ -1020,6 +1027,7 @@ void nfs_fattr_init(struct nfs_fattr *fattr)
fattr->time_start = jiffies;
fattr->gencount = nfs_inc_attr_generation_counter();
}
+EXPORT_SYMBOL_GPL(nfs_fattr_init);

struct nfs_fattr *nfs_alloc_fattr(void)
{
@@ -1030,6 +1038,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)
{
@@ -1099,6 +1108,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)
{
@@ -1135,6 +1145,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
@@ -1186,6 +1197,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/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 792cb13..ce8d6c4 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -13,6 +13,7 @@
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/errno.h>
+#include <linux/export.h>
#include <linux/string.h>
#include <linux/in.h>
#include <linux/pagemap.h>
@@ -1120,6 +1121,7 @@ int nfs_stat_to_errno(enum nfs_stat status)
dprintk("NFS: Unrecognized nfs status value: %u\n", status);
return nfs_errtbl[i].errno;
}
+EXPORT_SYMBOL_GPL(nfs_stat_to_errno);

#define PROC(proc, argtype, restype, timer) \
[NFSPROC_##proc] = { \
--
1.7.7.4


2011-12-01 16:48:29

by Anna Schumaker

[permalink] [raw]
Subject: [RFC v2 4/4] NFS: Turn NFS v3 into a module

From: Bryan Schumaker <[email protected]>

This will allow users to unmap NFS v3 from the kernel memory if they
don't want to use it. This will also give us a place to put NFS v3
specific code so it doesn't clutter the generic NFS client.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Kconfig | 8 ++++-
fs/nfs/Makefile | 3 +-
fs/nfs/client.c | 8 ++---
fs/nfs/dir.c | 31 --------------------
fs/nfs/file.c | 12 -------
fs/nfs/internal.h | 10 ++++++
fs/nfs/nfs3/Makefile | 7 ++++
fs/nfs/nfs3/module.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
fs/nfs/nfs3/nfs3.h | 7 ++++
fs/nfs/nfs3/nfs3proc.c | 1 +
fs/nfs/nfs3/nfs3xdr.c | 1 +
11 files changed, 111 insertions(+), 52 deletions(-)
create mode 100644 fs/nfs/nfs3/Makefile
create mode 100644 fs/nfs/nfs3/module.c
create mode 100644 fs/nfs/nfs3/nfs3.h

diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index dbcd821..47195e0 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -29,15 +29,19 @@ config NFS_FS

If unsure, say N.

-config NFS_V3
- bool "NFS client support for NFS version 3"
+config NFS_VERSION_3
+ tristate "NFS client support for NFS version 3"
depends on NFS_FS
+ select NFS_V3
help
This option enables support for version 3 of the NFS protocol
(RFC 1813) in the kernel's NFS client.

If unsure, say Y.

+config NFS_V3
+ bool
+
config NFS_V3_ACL
bool "NFS client support for the NFSv3 ACL protocol extension"
depends on NFS_V3
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index ac0e5df..930913d 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 nfs2xdr.o \
write.o namespace.o mount_clnt.o \
dns_resolve.o cache_lib.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
-nfs-$(CONFIG_NFS_V3) += nfs3/nfs3proc.o nfs3/nfs3xdr.o
-nfs-$(CONFIG_NFS_V3_ACL) += nfs3/nfs3acl.o
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
delegation.o idmap.o \
callback.o callback_xdr.o callback_proc.o \
@@ -22,5 +20,6 @@ nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o

+obj-$(CONFIG_NFS_VERSION_3) += nfs3/
obj-$(CONFIG_PNFS_OBJLAYOUT) += objlayout/
obj-$(CONFIG_PNFS_BLOCK) += blocklayout/
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 9e77056..e4cb43b 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -97,7 +97,7 @@ static struct nfs_version_ops *nfs_version_ops[5] = {

static struct nfs_rpc_ops *nfs_ops[5] = {
[2] = &nfs_v2_clientops,
- [3] = &nfs_v3_clientops,
+ [3] = NULL,
[4] = &nfs_v4_clientops,
};

@@ -106,9 +106,7 @@ static struct nfs_rpc_ops *nfs_ops[5] = {
*/
static struct rpc_version *nfs_version[5] = {
[2] = &nfs_version2,
-#ifdef CONFIG_NFS_V3
- [3] = &nfs_version3,
-#endif
+ [3] = NULL,
#ifdef CONFIG_NFS_V4
[4] = &nfs_version4,
#endif
@@ -131,7 +129,7 @@ struct rpc_stat nfs_rpcstat = {
#ifdef CONFIG_NFS_V3_ACL
static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
static struct rpc_version * nfsacl_version[] = {
- [3] = &nfsacl_version3,
+ [3] = NULL,
};

struct rpc_program nfsacl_program = {
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f7cb6b6..25dbc54 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -47,16 +47,6 @@
static int nfs_opendir(struct inode *, struct file *);
static int nfs_closedir(struct inode *, struct file *);
static int nfs_readdir(struct file *, void *, filldir_t);
-struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
-int nfs_create(struct inode *, struct dentry *, int, struct nameidata *);
-int nfs_mkdir(struct inode *, struct dentry *, int);
-int nfs_rmdir(struct inode *, struct dentry *);
-int nfs_unlink(struct inode *, struct dentry *);
-int nfs_symlink(struct inode *, struct dentry *, const char *);
-int nfs_link(struct dentry *, struct inode *, struct dentry *);
-int nfs_mknod(struct inode *, struct dentry *, int, dev_t);
-int nfs_rename(struct inode *, struct dentry *,
- struct inode *, struct dentry *);
static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
static void nfs_readdir_clear_array(struct page*);
@@ -89,27 +79,6 @@ const struct address_space_operations nfs_dir_aops = {
.freepage = nfs_readdir_clear_array,
};

-#ifdef CONFIG_NFS_V3
-const struct inode_operations nfs3_dir_inode_operations = {
- .create = nfs_create,
- .lookup = nfs_lookup,
- .link = nfs_link,
- .unlink = nfs_unlink,
- .symlink = nfs_symlink,
- .mkdir = nfs_mkdir,
- .rmdir = nfs_rmdir,
- .mknod = nfs_mknod,
- .rename = nfs_rename,
- .permission = nfs_permission,
- .getattr = nfs_getattr,
- .setattr = nfs_setattr,
- .listxattr = nfs3_listxattr,
- .getxattr = nfs3_getxattr,
- .setxattr = nfs3_setxattr,
- .removexattr = nfs3_removexattr,
-};
-#endif /* CONFIG_NFS_V3 */
-
#ifdef CONFIG_NFS_V4

static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 90389ca..397e5e0 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -49,18 +49,6 @@ const struct inode_operations nfs_file_inode_operations = {
.setattr = nfs_setattr,
};

-#ifdef CONFIG_NFS_V3
-const struct inode_operations nfs3_file_inode_operations = {
- .permission = nfs_permission,
- .getattr = nfs_getattr,
- .setattr = nfs_setattr,
- .listxattr = nfs3_listxattr,
- .getxattr = nfs3_getxattr,
- .setxattr = nfs3_setxattr,
- .removexattr = nfs3_removexattr,
-};
-#endif /* CONFIG_NFS_v3 */
-
/* Hack for future NFS swap support */
#ifndef IS_SWAPFILE
# define IS_SWAPFILE(inode) (0)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 93a0ba2..e6256f9 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -83,6 +83,16 @@ void nfs_unregister_version(unsigned int);
void nfs_version_ref(unsigned int);
void nfs_version_unref(unsigned int);

+struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
+int nfs_create(struct inode *, struct dentry *, int, struct nameidata *);
+int nfs_mkdir(struct inode *, struct dentry *, int);
+int nfs_rmdir(struct inode *, struct dentry *);
+int nfs_unlink(struct inode *, struct dentry *);
+int nfs_symlink(struct inode *, struct dentry *, const char *);
+int nfs_link(struct dentry *, struct inode *, struct dentry *);
+int nfs_mknod(struct inode *, struct dentry *, int, dev_t);
+int nfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
+
/*
* Note: RFC 1813 doesn't limit the number of auth flavors that
* a server can return, so make something up.
diff --git a/fs/nfs/nfs3/Makefile b/fs/nfs/nfs3/Makefile
new file mode 100644
index 0000000..308123b
--- /dev/null
+++ b/fs/nfs/nfs3/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for NFS v3
+#
+obj-$(CONFIG_NFS_VERSION_3) += nfs3.o
+
+nfs3-y := module.o nfs3proc.o nfs3xdr.o
+nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
diff --git a/fs/nfs/nfs3/module.c b/fs/nfs/nfs3/module.c
new file mode 100644
index 0000000..9c67cd0
--- /dev/null
+++ b/fs/nfs/nfs3/module.c
@@ -0,0 +1,75 @@
+/*
+ * Initialize the NFS v3 module
+ */
+
+#include <linux/module.h>
+#include <linux/nfs_fs.h>
+
+#include "../internal.h"
+#include "nfs3.h"
+
+static void nfs_v3_ref(void)
+{
+ try_module_get(THIS_MODULE);
+}
+
+static void nfs_v3_unref(void)
+{
+ module_put(THIS_MODULE);
+}
+
+const struct inode_operations nfs3_file_inode_operations = {
+ .permission = nfs_permission,
+ .getattr = nfs_getattr,
+ .setattr = nfs_setattr,
+ .listxattr = nfs3_listxattr,
+ .getxattr = nfs3_getxattr,
+ .setxattr = nfs3_setxattr,
+ .removexattr = nfs3_removexattr,
+};
+
+const struct inode_operations nfs3_dir_inode_operations = {
+ .create = nfs_create,
+ .lookup = nfs_lookup,
+ .link = nfs_link,
+ .unlink = nfs_unlink,
+ .symlink = nfs_symlink,
+ .mkdir = nfs_mkdir,
+ .rmdir = nfs_rmdir,
+ .mknod = nfs_mknod,
+ .rename = nfs_rename,
+ .permission = nfs_permission,
+ .getattr = nfs_getattr,
+ .setattr = nfs_setattr,
+ .listxattr = nfs3_listxattr,
+ .getxattr = nfs3_getxattr,
+ .setxattr = nfs3_setxattr,
+ .removexattr = nfs3_removexattr,
+};
+
+struct nfs_version_ops nfs_v3_ops = {
+ .nfs_rpc = &nfs_version3,
+ .nfs_ops = &nfs_v3_clientops,
+#ifdef CONFIG_NFS_V3_ACL
+ .nfs_acl = &nfsacl_version3,
+#endif
+ .version_ref = nfs_v3_ref,
+ .version_unref = nfs_v3_unref,
+};
+
+static int __init init_nfs_v3(void)
+{
+ nfs_register_version(3, &nfs_v3_ops);
+ return 0;
+}
+
+static void __exit exit_nfs_v3(void)
+{
+ nfs_unregister_version(3);
+}
+
+MODULE_AUTHOR("Olaf Kirch <[email protected]>");
+MODULE_LICENSE("GPL");
+
+module_init(init_nfs_v3);
+module_exit(exit_nfs_v3);
diff --git a/fs/nfs/nfs3/nfs3.h b/fs/nfs/nfs3/nfs3.h
new file mode 100644
index 0000000..c1e7875
--- /dev/null
+++ b/fs/nfs/nfs3/nfs3.h
@@ -0,0 +1,7 @@
+#ifndef _FS_NFS_NFS3_H
+#define _FS_NFS_NFS3_H
+
+const extern struct inode_operations nfs3_file_inode_operations;
+const extern struct inode_operations nfs3_dir_inode_operations;
+
+#endif /* _FS_NFS_NFS3_H */
diff --git a/fs/nfs/nfs3/nfs3proc.c b/fs/nfs/nfs3/nfs3proc.c
index 593a44c..e574e82 100644
--- a/fs/nfs/nfs3/nfs3proc.c
+++ b/fs/nfs/nfs3/nfs3proc.c
@@ -20,6 +20,7 @@

#include "../iostat.h"
#include "../internal.h"
+#include "nfs3.h"

#define NFSDBG_FACILITY NFSDBG_PROC

diff --git a/fs/nfs/nfs3/nfs3xdr.c b/fs/nfs/nfs3/nfs3xdr.c
index be27fb8..d59d644 100644
--- a/fs/nfs/nfs3/nfs3xdr.c
+++ b/fs/nfs/nfs3/nfs3xdr.c
@@ -20,6 +20,7 @@
#include <linux/nfs3.h>
#include <linux/nfs_fs.h>
#include <linux/nfsacl.h>
+#include <linux/nfs_xdr.h>
#include "../internal.h"

#define NFSDBG_FACILITY NFSDBG_XDR
--
1.7.7.4


2012-01-10 17:58:07

by Anna Schumaker

[permalink] [raw]
Subject: Re: [RFC 0/4] NFS: Modularize NFS v3

On Tue Jan 10 12:42:52 2012, Stanislav Kinsbursky wrote:
> Hi, Bryan.
> Are you still on progress with this stuff?

Yeah, I'm still working on this. I'm taking a final pass over my
patches now to see if I need to change anything else before posting
them. They should be ready soon.

- Bryan

> I'm wondering, because I have to reorganize RPC versions and programs code in the way to collect statistics per container. I actually have few patches already, which implements functionality similar to your new versions adding.
> And thus it would be great to know, do i need to take your work into account or not.
>



2012-01-10 17:43:45

by Stanislav Kinsbursky

[permalink] [raw]
Subject: Re: [RFC 0/4] NFS: Modularize NFS v3

Hi, Bryan.
Are you still on progress with this stuff?
I'm wondering, because I have to reorganize RPC versions and programs code in
the way to collect statistics per container. I actually have few patches
already, which implements functionality similar to your new versions adding.
And thus it would be great to know, do i need to take your work into account or not.

--
Best regards,
Stanislav Kinsbursky