summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2012-06-20 15:53:46 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-06-29 11:46:46 -0400
commit6663ee7f8187708143255c057bc132bbc84c1894 (patch)
tree17e47c1be9da2b3e67d74155676fdba92f435efe
parentcdb7ecedec766861e7c4cc35a203518f92023bff (diff)
NFS: Create an alloc_client rpc_op
This gives NFS v4 a way to set up callbacks and sessions without v2 or v3 having to do them as well. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/client.c40
-rw-r--r--fs/nfs/internal.h1
-rw-r--r--fs/nfs/nfs3proc.c1
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4proc.c1
-rw-r--r--fs/nfs/proc.c1
-rw-r--r--include/linux/nfs_xdr.h2
7 files changed, 34 insertions, 14 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 82cb8a386a8..254719c4a57 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -147,7 +147,7 @@ struct nfs_client_initdata {
* Since these are allocated/deallocated very rarely, we don't
* bother putting them in a slab cache...
*/
-static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
+struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
{
struct nfs_client *clp;
struct rpc_cred *cred;
@@ -177,18 +177,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
clp->cl_proto = cl_init->proto;
clp->cl_net = get_net(cl_init->net);
-#ifdef CONFIG_NFS_V4
- err = nfs_get_cb_ident_idr(clp, cl_init->minorversion);
- if (err)
- goto error_cleanup;
-
- spin_lock_init(&clp->cl_lock);
- INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
- rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
- clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
- clp->cl_minorversion = cl_init->minorversion;
- clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
-#endif
cred = rpc_lookup_machine_cred("*");
if (!IS_ERR(cred))
clp->cl_machine_cred = cred;
@@ -218,6 +206,30 @@ static void nfs4_shutdown_session(struct nfs_client *clp)
}
#endif /* CONFIG_NFS_V4_1 */
+struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
+{
+ int err;
+ struct nfs_client *clp = nfs_alloc_client(cl_init);
+ if (IS_ERR(clp))
+ return clp;
+
+ err = nfs_get_cb_ident_idr(clp, cl_init->minorversion);
+ if (err)
+ goto error;
+
+ spin_lock_init(&clp->cl_lock);
+ INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
+ rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
+ clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
+ clp->cl_minorversion = cl_init->minorversion;
+ clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
+ return clp;
+
+error:
+ kfree(clp);
+ return ERR_PTR(err);
+}
+
/*
* Destroy the NFS4 callback service
*/
@@ -588,7 +600,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
spin_unlock(&nn->nfs_client_lock);
- new = nfs_alloc_client(cl_init);
+ new = cl_init->rpc_ops->alloc_client(cl_init);
} while (!IS_ERR(new));
dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n",
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 93b73252334..633af813984 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -148,6 +148,7 @@ extern void nfs_umount(const struct nfs_mount_request *info);
/* client.c */
extern const struct rpc_program nfs_program;
extern void nfs_clients_init(struct net *net);
+extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
extern void nfs_cleanup_cb_ident_idr(struct net *);
extern void nfs_put_client(struct nfs_client *);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 4ccb34bf173..77c7aac228b 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -934,6 +934,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
.close_context = nfs_close_context,
.have_delegation = nfs3_have_delegation,
.return_delegation = nfs3_return_delegation,
+ .alloc_client = nfs_alloc_client,
.init_client = nfs_init_client,
.free_client = nfs_free_client,
};
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 9889ee476e3..a0be2d1af04 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -303,6 +303,8 @@ extern const u32 nfs4_fs_locations_bitmap[2];
void nfs4_free_client(struct nfs_client *);
+struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *);
+
/* nfs4renewd.c */
extern void nfs4_schedule_state_renewal(struct nfs_client *);
extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f301c53926b..7f39e7ecde6 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6806,6 +6806,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.open_context = nfs4_atomic_open,
.have_delegation = nfs4_have_delegation,
.return_delegation = nfs4_inode_return_delegation,
+ .alloc_client = nfs4_alloc_client,
.init_client = nfs4_init_client,
.free_client = nfs4_free_client,
};
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 53620bf1096..99a002515df 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -790,6 +790,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
.close_context = nfs_close_context,
.have_delegation = nfs_have_delegation,
.return_delegation = nfs_return_delegation,
+ .alloc_client = nfs_alloc_client,
.init_client = nfs_init_client,
.free_client = nfs_free_client,
};
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index e61dc7235d5..4d62b774dda 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1353,6 +1353,7 @@ struct nfs_renamedata {
struct nfs_access_entry;
struct nfs_client;
struct rpc_timeout;
+struct nfs_client_initdata;
/*
* RPC procedure vector for NFSv2/NFSv3 demuxing
@@ -1424,6 +1425,7 @@ struct nfs_rpc_ops {
struct iattr *iattr);
int (*have_delegation)(struct inode *, fmode_t);
int (*return_delegation)(struct inode *);
+ struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *);
struct nfs_client *
(*init_client) (struct nfs_client *, const struct rpc_timeout *,
const char *, rpc_authflavor_t);