aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorBenny Halevy <bhalevy@panasas.com>2009-04-01 09:22:29 -0400
committerBenny Halevy <bhalevy@panasas.com>2009-06-17 15:23:57 -0400
commit99fe60d062cfecf382c036065b3278b82b6c5eff (patch)
treeb4451fc4bb42c0915c4f736cc5fdae9e818b55d4 /fs/nfs/nfs4proc.c
parent938e10109115a71cc69d475122f21cf75e5046cd (diff)
nfs41: exchange_id operation
Implement the exchange_id operation conforming to http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26 Unlike NFSv4.0, NFSv4.1 requires machine credentials. RPC_AUTH_GSS machine credentials will be passed into the kernel at mount time to be available for the exchange_id operation. RPC_AUTH_UNIX root mounts can use the UNIX root credential. Store the root credential in the nfs_client struct. Without a credential, NFSv4.1 state renewal fails. [nfs41: establish clientid via exchange id only if cred != NULL] Signed-off-by: Andy Adamson<andros@umich.edu> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfsd41: move nfstime4 from under CONFIG_NFS_V4_1] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: do not wait a lease time in exchange id] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: pass *session in seq_args and seq_res] Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> [nfs41: Ignoring impid in decode_exchange_id is missing a READ_BUF] Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: fix Xcode_exchange_id's xdr Xcoding pointer type] [nfs41: get rid of unused struct nfs41_exchange_id_res members] Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index dc0feb5837b1..6f384e290753 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -48,6 +48,7 @@
48#include <linux/smp_lock.h> 48#include <linux/smp_lock.h>
49#include <linux/namei.h> 49#include <linux/namei.h>
50#include <linux/mount.h> 50#include <linux/mount.h>
51#include <linux/module.h>
51 52
52#include "nfs4_fs.h" 53#include "nfs4_fs.h"
53#include "delegation.h" 54#include "delegation.h"
@@ -433,11 +434,13 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
433 spin_unlock(&tbl->slot_tbl_lock); 434 spin_unlock(&tbl->slot_tbl_lock);
434 435
435 slot = tbl->slots + slotid; 436 slot = tbl->slots + slotid;
437 args->sa_session = session;
436 args->sa_slotid = slotid; 438 args->sa_slotid = slotid;
437 args->sa_cache_this = cache_reply; 439 args->sa_cache_this = cache_reply;
438 440
439 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr); 441 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr);
440 442
443 res->sr_session = session;
441 res->sr_slotid = slotid; 444 res->sr_slotid = slotid;
442 res->sr_renewal_time = jiffies; 445 res->sr_renewal_time = jiffies;
443 /* 446 /*
@@ -4128,6 +4131,64 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4128} 4131}
4129 4132
4130#ifdef CONFIG_NFS_V4_1 4133#ifdef CONFIG_NFS_V4_1
4134/*
4135 * nfs4_proc_exchange_id()
4136 *
4137 * Since the clientid has expired, all compounds using sessions
4138 * associated with the stale clientid will be returning
4139 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
4140 * be in some phase of session reset.
4141 */
4142static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4143{
4144 nfs4_verifier verifier;
4145 struct nfs41_exchange_id_args args = {
4146 .client = clp,
4147 .flags = clp->cl_exchange_flags,
4148 };
4149 struct nfs41_exchange_id_res res = {
4150 .client = clp,
4151 };
4152 int status;
4153 struct rpc_message msg = {
4154 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
4155 .rpc_argp = &args,
4156 .rpc_resp = &res,
4157 .rpc_cred = cred,
4158 };
4159 __be32 *p;
4160
4161 dprintk("--> %s\n", __func__);
4162 BUG_ON(clp == NULL);
4163 p = (u32 *)verifier.data;
4164 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4165 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
4166 args.verifier = &verifier;
4167
4168 while (1) {
4169 args.id_len = scnprintf(args.id, sizeof(args.id),
4170 "%s/%s %u",
4171 clp->cl_ipaddr,
4172 rpc_peeraddr2str(clp->cl_rpcclient,
4173 RPC_DISPLAY_ADDR),
4174 clp->cl_id_uniquifier);
4175
4176 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
4177
4178 if (status != NFS4ERR_CLID_INUSE)
4179 break;
4180
4181 if (signalled())
4182 break;
4183
4184 if (++clp->cl_id_uniquifier == 0)
4185 break;
4186 }
4187
4188 dprintk("<-- %s status= %d\n", __func__, status);
4189 return status;
4190}
4191
4131/* Destroy the slot table */ 4192/* Destroy the slot table */
4132static void nfs4_destroy_slot_table(struct nfs4_session *session) 4193static void nfs4_destroy_slot_table(struct nfs4_session *session)
4133{ 4194{