]> git.neil.brown.name Git - history.git/commitdiff
NFSv4: Convert SETCLIENTID and SETCLIENTID_CONFIRM to be
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Sat, 7 Feb 2004 15:56:12 +0000 (16:56 +0100)
committerTrond Myklebust <trond.myklebust@fys.uio.no>
Sat, 7 Feb 2004 15:56:12 +0000 (16:56 +0100)
standalone operations. Ensure that SETCLIENTID_CONFIRM always
returns the lease timeout length.

fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
include/linux/nfs4.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h

index 264ef919baeeb8560af761000a5bfab0df1ae2a6..8e8ac9cc08f6da9989b5402c8d12844b3cf11a71 100644 (file)
@@ -56,9 +56,6 @@ extern struct rpc_procinfo nfs4_procedures[];
 
 extern nfs4_stateid zero_stateid;
 
-static int nfs4_proc_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
-
-
 static void
 nfs4_setup_compound(struct nfs4_compound *cp, struct nfs4_op *ops,
                    struct nfs_server *server, char *tag)
@@ -397,41 +394,6 @@ nfs4_setup_savefh(struct nfs4_compound *cp)
         cp->req_nops++;
 }
 
-static void
-nfs4_setup_setclientid(struct nfs4_compound *cp, u32 program, unsigned short port)
-{
-       struct nfs4_setclientid *setclientid = GET_OP(cp, setclientid);
-       struct nfs_server *server = cp->server;
-       struct timespec tv;
-       u32 *p;
-
-       tv = CURRENT_TIME;
-       p = (u32 *)setclientid->sc_verifier.data;
-       *p++ = tv.tv_sec;
-       *p++ = tv.tv_nsec;
-       setclientid->sc_name = server->ip_addr;
-       sprintf(setclientid->sc_netid, "udp");
-       sprintf(setclientid->sc_uaddr, "%s.%d.%d", server->ip_addr, port >> 8, port & 255);
-       setclientid->sc_prog = program;
-       setclientid->sc_cb_ident = 0;
-       setclientid->sc_state = server->nfs4_state;
-       
-       OPNUM(cp) = OP_SETCLIENTID;
-       cp->req_nops++;
-}
-
-static void
-nfs4_setup_setclientid_confirm(struct nfs4_compound *cp)
-{
-       struct nfs4_client **client_state = GET_OP(cp, setclientid_confirm);
-
-       *client_state = cp->server->nfs4_state;
-
-       OPNUM(cp) = OP_SETCLIENTID_CONFIRM;
-       cp->req_nops++;
-       cp->renew_index = cp->req_nops;
-}
-
 static void
 renew_lease(struct nfs_server *server, unsigned long timestamp)
 {
@@ -701,51 +663,31 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
        struct nfs4_client      *clp;
        struct nfs4_compound    compound;
        struct nfs4_op          ops[4];
-       struct nfs_fsinfo       fsinfo;
        unsigned char *         p;
        struct qstr             q;
-       unsigned long           last_renewed;
        int                     status;
 
        clp = server->nfs4_state;
 
        down_write(&clp->cl_sem);
        /* Has the clientid already been initialized? */
-       if (clp->cl_state != NFS4CLNT_NEW) {
+       if (clp->cl_state != NFS4CLNT_NEW)
                /* Yep, so just read the root attributes and the lease time. */
-               fattr->valid = 0;
-               nfs4_setup_compound(&compound, ops, server, "getrootfh");
-               nfs4_setup_putrootfh(&compound);
-               nfs4_setup_getattr(&compound, fattr);
-               nfs4_setup_getfh(&compound, fhandle);
-               if ((status = nfs4_call_compound(&compound, NULL, 0)))
-                       goto out_unlock;
                goto no_setclientid;
-       }
 
        /* 
         * SETCLIENTID.
         * Until delegations are imported, we don't bother setting the program
         * number and port to anything meaningful.
         */
-       nfs4_setup_compound(&compound, ops, server, "setclientid");
-       nfs4_setup_setclientid(&compound, 0, 0);
-       last_renewed = jiffies;
-       if ((status = nfs4_call_compound(&compound, NULL, 0)))
+       if ((status = nfs4_proc_setclientid(clp, 0, 0)))
                goto out_unlock;
 
        /*
         * SETCLIENTID_CONFIRM, plus root filehandle.
         * We also get the lease time here.
         */
-       fattr->valid = 0;
-       nfs4_setup_compound(&compound, ops, server, "setclientid_confirm");
-       nfs4_setup_setclientid_confirm(&compound);
-       nfs4_setup_putrootfh(&compound);
-       nfs4_setup_getattr(&compound, fattr);
-       nfs4_setup_getfh(&compound, fhandle);
-       last_renewed = jiffies;
-       if ((status = nfs4_call_compound(&compound, NULL, 0)))
+       if ((status = nfs4_proc_setclientid_confirm(clp)))
                goto out_unlock;
 
        /*
@@ -754,10 +696,6 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
         * server.
         * FIXME: we only need one renewd daemon per server.
         */
-       if ((status = nfs4_proc_fsinfo(server, fhandle, &fsinfo)))
-               goto out_unlock;
-       clp->cl_lease_time = fsinfo.lease_time * HZ;
-       clp->cl_last_renewal = last_renewed;
        nfs4_schedule_state_renewal(clp);
        clp->cl_state = NFS4CLNT_OK;
 
@@ -770,6 +708,13 @@ no_setclientid:
         * catch an ERR_WRONGSEC if it occurs along the way...
         */
        p = server->mnt_path;
+       fattr->valid = 0;
+       nfs4_setup_compound(&compound, ops, server, "getrootfh");
+       nfs4_setup_putrootfh(&compound);
+       nfs4_setup_getattr(&compound, fattr);
+       nfs4_setup_getfh(&compound, fhandle);
+       if ((status = nfs4_call_compound(&compound, NULL, 0)))
+               goto out;
        for (;;) {
                while (*p == '/')
                        p++;
@@ -798,6 +743,7 @@ no_setclientid:
        return status;
 out_unlock:
        up_write(&clp->cl_sem);
+out:
        return status;
 }
 
@@ -1724,6 +1670,57 @@ nfs4_request_compatible(struct nfs_page *req, struct file *filp, struct page *pa
        return 1;
 }
 
+int
+nfs4_proc_setclientid(struct nfs4_client *clp,
+               u32 program, unsigned short port)
+{
+       u32 *p;
+       struct nfs4_setclientid setclientid;
+       struct timespec tv;
+       struct rpc_message msg = {
+               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
+               .rpc_argp = &setclientid,
+               .rpc_resp = clp,
+               .rpc_cred = clp->cl_cred,
+       };
+
+       tv = CURRENT_TIME;
+       p = (u32*)setclientid.sc_verifier.data;
+       *p++ = (u32)tv.tv_sec;
+       *p = (u32)tv.tv_nsec;
+       setclientid.sc_name = clp->cl_ipaddr;
+       sprintf(setclientid.sc_netid, "tcp");
+       sprintf(setclientid.sc_uaddr, "%s.%d.%d", clp->cl_ipaddr, port >> 8, port & 255);
+       setclientid.sc_prog = htonl(program);
+       setclientid.sc_cb_ident = 0;
+
+       return rpc_call_sync(clp->cl_rpcclient, &msg, 0);
+}
+
+int
+nfs4_proc_setclientid_confirm(struct nfs4_client *clp)
+{
+       struct nfs_fsinfo fsinfo;
+       struct rpc_message msg = {
+               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
+               .rpc_argp = clp,
+               .rpc_resp = &fsinfo,
+               .rpc_cred = clp->cl_cred,
+       };
+       unsigned long now;
+       int status;
+
+       now = jiffies;
+       status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
+       if (status == 0) {
+               spin_lock(&clp->cl_lock);
+               clp->cl_lease_time = fsinfo.lease_time * HZ;
+               clp->cl_last_renewal = now;
+               spin_unlock(&clp->cl_lock);
+       }
+       return status;
+}
+
 struct nfs_rpc_ops     nfs_v4_clientops = {
        .version        = 4,                    /* protocol version */
        .getroot        = nfs4_proc_get_root,
index ed79661601dd8215b3f8bcd6be190bd0bd269b14..cb96666b3831784411f4d2a2221404f839e82b3e 100644 (file)
@@ -73,6 +73,8 @@ extern int                    nfs_stat_to_errno(int);
 #define encode_putfh_maxsz     op_encode_hdr_maxsz + 1 + \
                                (NFS4_FHSIZE >> 2)
 #define decode_putfh_maxsz     op_decode_hdr_maxsz
+#define encode_putrootfh_maxsz op_encode_hdr_maxsz
+#define decode_putrootfh_maxsz op_decode_hdr_maxsz
 #define encode_getfh_maxsz      op_encode_hdr_maxsz
 #define decode_getfh_maxsz      op_decode_hdr_maxsz + 1 + \
                                 (NFS4_FHSIZE >> 2)
@@ -94,6 +96,21 @@ extern int                   nfs_stat_to_errno(int);
 #define decode_fsinfo_maxsz    op_decode_hdr_maxsz + 11
 #define encode_renew_maxsz     op_encode_hdr_maxsz + 3
 #define decode_renew_maxsz     op_decode_hdr_maxsz
+#define encode_setclientid_maxsz \
+                               op_encode_hdr_maxsz + \
+                               4 /*server->ip_addr*/ + \
+                               1 /*Netid*/ + \
+                               6 /*uaddr*/ + \
+                               6 + (NFS4_VERIFIER_SIZE >> 2)
+#define decode_setclientid_maxsz \
+                               op_decode_hdr_maxsz + \
+                               2 + \
+                               1024 /* large value for CLID_INUSE */
+#define encode_setclientid_confirm_maxsz \
+                               op_encode_hdr_maxsz + \
+                               3 + (NFS4_VERIFIER_SIZE >> 2)
+#define decode_setclientid_confirm_maxsz \
+                               op_decode_hdr_maxsz
 
 #define NFS4_enc_compound_sz   1024  /* XXX: large enough? */
 #define NFS4_dec_compound_sz   1024  /* XXX: large enough? */
@@ -173,6 +190,20 @@ extern int                 nfs_stat_to_errno(int);
                                encode_renew_maxsz
 #define NFS4_dec_renew_sz      compound_decode_hdr_maxsz + \
                                decode_renew_maxsz
+#define NFS4_enc_setclientid_sz        compound_encode_hdr_maxsz + \
+                               encode_setclientid_maxsz
+#define NFS4_dec_setclientid_sz        compound_decode_hdr_maxsz + \
+                               decode_setclientid_maxsz
+#define NFS4_enc_setclientid_confirm_sz \
+                               compound_encode_hdr_maxsz + \
+                               encode_setclientid_confirm_maxsz + \
+                               encode_putrootfh_maxsz + \
+                               encode_fsinfo_maxsz
+#define NFS4_dec_setclientid_confirm_sz \
+                               compound_decode_hdr_maxsz + \
+                               decode_setclientid_confirm_maxsz + \
+                               decode_putrootfh_maxsz + \
+                               decode_fsinfo_maxsz
 
 
 static struct {
@@ -918,12 +949,6 @@ encode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
                case OP_SAVEFH:
                        status = encode_savefh(xdr);
                        break;
-               case OP_SETCLIENTID:
-                       status = encode_setclientid(xdr, &cp->ops[i].u.setclientid);
-                       break;
-               case OP_SETCLIENTID_CONFIRM:
-                       status = encode_setclientid_confirm(xdr, cp->ops[i].u.setclientid_confirm);
-                       break;
                default:
                        BUG();
                }
@@ -1187,6 +1212,46 @@ nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp)
        return encode_renew(&xdr, clp);
 }
 
+/*
+ * a SETCLIENTID request
+ */
+static int
+nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p,
+               struct nfs4_setclientid *sc)
+{
+       struct xdr_stream xdr;
+       struct compound_hdr hdr = {
+               .nops   = 1,
+       };
+
+       xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+       encode_compound_hdr(&xdr, &hdr);
+       return encode_setclientid(&xdr, sc);
+}
+
+/*
+ * a SETCLIENTID_CONFIRM request
+ */
+static int
+nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p,
+               struct nfs4_client *clp)
+{
+       struct xdr_stream xdr;
+       struct compound_hdr hdr = {
+               .nops   = 3,
+       };
+       int status;
+
+       xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+       encode_compound_hdr(&xdr, &hdr);
+       status = encode_setclientid_confirm(&xdr, clp);
+       if (!status)
+               status = encode_putrootfh(&xdr);
+       if (!status)
+               status = encode_fsinfo(&xdr);
+       return status;
+}
+
 /*
  * START OF "GENERIC" DECODE ROUTINES.
  *   These may look a little ugly since they are imported from a "generic"
@@ -2098,7 +2163,7 @@ decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
 }
 
 static int
-decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid *setclientid)
+decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp)
 {
        uint32_t *p;
        uint32_t opnum;
@@ -2114,9 +2179,9 @@ decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid *setclientid)
        }
        READ32(nfserr);
        if (nfserr == NFS_OK) {
-               READ_BUF(8 + sizeof(setclientid->sc_state->cl_confirm.data));
-               READ64(setclientid->sc_state->cl_clientid);
-               COPYMEM(setclientid->sc_state->cl_confirm.data, sizeof(setclientid->sc_state->cl_confirm.data));
+               READ_BUF(8 + sizeof(clp->cl_confirm.data));
+               READ64(clp->cl_clientid);
+               COPYMEM(clp->cl_confirm.data, sizeof(clp->cl_confirm.data));
        } else if (nfserr == NFSERR_CLID_INUSE) {
                uint32_t len;
 
@@ -2231,12 +2296,6 @@ decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
                case OP_SAVEFH:
                        status = decode_savefh(xdr);
                        break;
-               case OP_SETCLIENTID:
-                       status = decode_setclientid(xdr, &op->u.setclientid);
-                       break;
-               case OP_SETCLIENTID_CONFIRM:
-                       status = decode_setclientid_confirm(xdr);
-                       break;
                default:
                        BUG();
                        return -EIO;
@@ -2513,6 +2572,49 @@ nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy)
        return status;
 }
 
+/*
+ * a SETCLIENTID request
+ */
+static int
+nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p,
+               struct nfs4_client *clp)
+{
+       struct xdr_stream xdr;
+       struct compound_hdr hdr;
+       int status;
+
+       xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+       status = decode_compound_hdr(&xdr, &hdr);
+       if (!status)
+               status = decode_setclientid(&xdr, clp);
+       if (!status)
+               status = -nfs_stat_to_errno(hdr.status);
+       return status;
+}
+
+/*
+ * a SETCLIENTID_CONFIRM request
+ */
+static int
+nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo)
+{
+       struct xdr_stream xdr;
+       struct compound_hdr hdr;
+       int status;
+
+       xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+       status = decode_compound_hdr(&xdr, &hdr);
+       if (!status)
+               status = decode_setclientid_confirm(&xdr);
+       if (!status)
+               status = decode_putrootfh(&xdr);
+       if (!status)
+               status = decode_fsinfo(&xdr, fsinfo);
+       if (!status)
+               status = -nfs_stat_to_errno(hdr.status);
+       return status;
+}
+
 uint32_t *
 nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
 {
@@ -2571,6 +2673,8 @@ struct rpc_procinfo       nfs4_procedures[] = {
   PROC(SETATTR,                enc_setattr,    dec_setattr),
   PROC(FSINFO,         enc_fsinfo,     dec_fsinfo),
   PROC(RENEW,          enc_renew,      dec_renew),
+  PROC(SETCLIENTID,    enc_setclientid,        dec_setclientid),
+  PROC(SETCLIENTID_CONFIRM,    enc_setclientid_confirm,        dec_setclientid_confirm),
 };
 
 struct rpc_version             nfs_version4 = {
index d535a46f7d4fd68950ad16e93b9e04b739805340..a601ae91de21435c1d9f3dc161c72dcd838f4f28 100644 (file)
@@ -223,6 +223,8 @@ enum {
        NFSPROC4_CLNT_SETATTR,
        NFSPROC4_CLNT_FSINFO,
        NFSPROC4_CLNT_RENEW,
+       NFSPROC4_CLNT_SETCLIENTID,
+       NFSPROC4_CLNT_SETCLIENTID_CONFIRM,
 };
 
 #endif
index 4996221041a482342f9db9a1bf5498f3135c15c3..fcaf3322cadfe5bb36f4f3f12049ad0c3ad31340 100644 (file)
@@ -552,6 +552,8 @@ struct nfs4_state {
 
 
 /* nfs4proc.c */
+extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
+extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
 extern int nfs4_proc_async_renew(struct nfs4_client *);
 extern int nfs4_do_close(struct inode *, struct nfs4_state *);
 
index 09c2dd2216d0e486873f6f06a58487bfad3d3213..244a430f83ef0a6db642e9ea0683f787b2d3b021 100644 (file)
@@ -555,8 +555,6 @@ struct nfs4_op {
                struct nfs4_rename      rename;
                struct nfs4_client *    renew;
                struct nfs4_setattr     setattr;
-               struct nfs4_setclientid setclientid;
-               struct nfs4_client *    setclientid_confirm;
        } u;
 };