]> git.hungrycats.org Git - linux/commitdiff
NFSv4: Split out the code for retrieving static server
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Sat, 7 Feb 2004 15:54:20 +0000 (16:54 +0100)
committerTrond Myklebust <trond.myklebust@fys.uio.no>
Sat, 7 Feb 2004 15:54:20 +0000 (16:54 +0100)
information out of the GETATTR compound.

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

index a3ac8370ba3c76b13a325dba38cc44fdd2b7f170..264ef919baeeb8560af761000a5bfab0df1ae2a6 100644 (file)
@@ -56,6 +56,9 @@ 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)
@@ -177,44 +180,16 @@ u32 nfs4_statfs_bitmap[2] = {
        | FATTR4_WORD1_SPACE_TOTAL
 };
 
-u32 nfs4_fsinfo_bitmap[2] = {
-       FATTR4_WORD0_MAXFILESIZE
-       | FATTR4_WORD0_MAXREAD
-        | FATTR4_WORD0_MAXWRITE
-       | FATTR4_WORD0_LEASE_TIME,
-       0
-};
-
 u32 nfs4_pathconf_bitmap[2] = {
        FATTR4_WORD0_MAXLINK
        | FATTR4_WORD0_MAXNAME,
        0
 };
 
-/* mount bitmap: fattr bitmap + lease time */
-u32 nfs4_mount_bitmap[2] = {
-       FATTR4_WORD0_TYPE
-       | FATTR4_WORD0_CHANGE
-       | FATTR4_WORD0_SIZE
-       | FATTR4_WORD0_FSID
-       | FATTR4_WORD0_FILEID
-       | FATTR4_WORD0_LEASE_TIME,
-       FATTR4_WORD1_MODE
-       | FATTR4_WORD1_NUMLINKS
-       | FATTR4_WORD1_OWNER
-       | FATTR4_WORD1_OWNER_GROUP
-       | FATTR4_WORD1_RAWDEV
-       | FATTR4_WORD1_SPACE_USED
-       | FATTR4_WORD1_TIME_ACCESS
-       | FATTR4_WORD1_TIME_METADATA
-       | FATTR4_WORD1_TIME_MODIFY
-};
-
 static inline void
 __nfs4_setup_getattr(struct nfs4_compound *cp, u32 *bitmap,
                     struct nfs_fattr *fattr,
                     struct nfs_fsstat *fsstat,
-                    struct nfs_fsinfo *fsinfo,
                     struct nfs_pathconf *pathconf)
 {
         struct nfs4_getattr *getattr = GET_OP(cp, getattr);
@@ -222,7 +197,6 @@ __nfs4_setup_getattr(struct nfs4_compound *cp, u32 *bitmap,
         getattr->gt_bmval = bitmap;
         getattr->gt_attrs = fattr;
        getattr->gt_fsstat = fsstat;
-       getattr->gt_fsinfo = fsinfo;
        getattr->gt_pathconf = pathconf;
 
         OPNUM(cp) = OP_GETATTR;
@@ -234,16 +208,7 @@ nfs4_setup_getattr(struct nfs4_compound *cp,
                struct nfs_fattr *fattr)
 {
        __nfs4_setup_getattr(cp, nfs4_fattr_bitmap, fattr,
-                       NULL, NULL, NULL);
-}
-
-static void
-nfs4_setup_getrootattr(struct nfs4_compound *cp,
-               struct nfs_fattr *fattr,
-               struct nfs_fsinfo *fsinfo)
-{
-       __nfs4_setup_getattr(cp, nfs4_mount_bitmap,
-                       fattr, NULL, fsinfo, NULL);
+                       NULL, NULL);
 }
 
 static void
@@ -251,15 +216,7 @@ nfs4_setup_statfs(struct nfs4_compound *cp,
                struct nfs_fsstat *fsstat)
 {
        __nfs4_setup_getattr(cp, nfs4_statfs_bitmap,
-                       NULL, fsstat, NULL, NULL);
-}
-
-static void
-nfs4_setup_fsinfo(struct nfs4_compound *cp,
-               struct nfs_fsinfo *fsinfo)
-{
-       __nfs4_setup_getattr(cp, nfs4_fsinfo_bitmap,
-                       NULL, NULL, fsinfo, NULL);
+                       NULL, fsstat, NULL);
 }
 
 static void
@@ -267,7 +224,7 @@ nfs4_setup_pathconf(struct nfs4_compound *cp,
                struct nfs_pathconf *pathconf)
 {
        __nfs4_setup_getattr(cp, nfs4_pathconf_bitmap,
-                       NULL, NULL, NULL, pathconf);
+                       NULL, NULL, pathconf);
 }
 
 static void
@@ -759,7 +716,7 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
                fattr->valid = 0;
                nfs4_setup_compound(&compound, ops, server, "getrootfh");
                nfs4_setup_putrootfh(&compound);
-               nfs4_setup_getrootattr(&compound, fattr, &fsinfo);
+               nfs4_setup_getattr(&compound, fattr);
                nfs4_setup_getfh(&compound, fhandle);
                if ((status = nfs4_call_compound(&compound, NULL, 0)))
                        goto out_unlock;
@@ -785,7 +742,7 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
        nfs4_setup_compound(&compound, ops, server, "setclientid_confirm");
        nfs4_setup_setclientid_confirm(&compound);
        nfs4_setup_putrootfh(&compound);
-       nfs4_setup_getrootattr(&compound, fattr, &fsinfo);
+       nfs4_setup_getattr(&compound, fattr);
        nfs4_setup_getfh(&compound, fhandle);
        last_renewed = jiffies;
        if ((status = nfs4_call_compound(&compound, NULL, 0)))
@@ -797,6 +754,8 @@ 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);
@@ -1434,14 +1393,14 @@ static int
 nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
                 struct nfs_fsinfo *fsinfo)
 {
-       struct nfs4_compound compound;
-       struct nfs4_op ops[2];
+       struct rpc_message msg = {
+               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO],
+               .rpc_argp = fhandle,
+               .rpc_resp = fsinfo,
+       };
 
        memset(fsinfo, 0, sizeof(*fsinfo));
-       nfs4_setup_compound(&compound, ops, server, "statfs");
-       nfs4_setup_putfh(&compound, fhandle);
-       nfs4_setup_fsinfo(&compound, fsinfo);
-       return nfs4_call_compound(&compound, NULL, 0);
+       return rpc_call_sync(server->client, &msg, 0);
 }
 
 static int
index add338c9be56e8c587f065a190c9cb999333ae8d..ed79661601dd8215b3f8bcd6be190bd0bd269b14 100644 (file)
@@ -90,6 +90,8 @@ extern int                    nfs_stat_to_errno(int);
 #define decode_pre_write_getattr_maxsz op_decode_hdr_maxsz + 5
 #define encode_post_write_getattr_maxsz        op_encode_hdr_maxsz + 2
 #define decode_post_write_getattr_maxsz        op_decode_hdr_maxsz + 13
+#define encode_fsinfo_maxsz    op_encode_hdr_maxsz + 2
+#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
 
@@ -161,6 +163,12 @@ extern int                 nfs_stat_to_errno(int);
 #define NFS4_dec_setattr_sz     compound_decode_hdr_maxsz + \
                                 decode_putfh_maxsz + \
                                 op_decode_hdr_maxsz + 3
+#define NFS4_enc_fsinfo_sz     compound_encode_hdr_maxsz + \
+                               encode_putfh_maxsz + \
+                               encode_fsinfo_maxsz
+#define NFS4_dec_fsinfo_sz     compound_decode_hdr_maxsz + \
+                               decode_putfh_maxsz + \
+                               decode_fsinfo_maxsz
 #define NFS4_enc_renew_sz      compound_encode_hdr_maxsz + \
                                encode_renew_maxsz
 #define NFS4_dec_renew_sz      compound_decode_hdr_maxsz + \
@@ -506,6 +514,15 @@ encode_post_write_getattr(struct xdr_stream *xdr)
                        FATTR4_WORD1_TIME_MODIFY);
 }
 
+static int
+encode_fsinfo(struct xdr_stream *xdr)
+{
+       return encode_getattr_one(xdr, FATTR4_WORD0_MAXFILESIZE
+                       | FATTR4_WORD0_MAXREAD
+                       | FATTR4_WORD0_MAXWRITE
+                       | FATTR4_WORD0_LEASE_TIME);
+}
+
 static int
 encode_getfh(struct xdr_stream *xdr)
 {
@@ -1134,6 +1151,26 @@ out:
        return status;
 }
 
+/*
+ * FSINFO request
+ */
+static int
+nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, void *fhandle)
+{
+       struct xdr_stream xdr;
+       struct compound_hdr hdr = {
+               .nops   = 2,
+       };
+       int status;
+
+       xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+       encode_compound_hdr(&xdr, &hdr);
+       status = encode_putfh(&xdr, fhandle);
+       if (!status)
+               status = encode_fsinfo(&xdr);
+       return status;
+}
+
 /*
  * a RENEW request
  */
@@ -1312,7 +1349,6 @@ decode_create(struct xdr_stream *xdr, struct nfs4_create *create)
 }
 
 extern uint32_t nfs4_fattr_bitmap[2];
-extern uint32_t nfs4_fsinfo_bitmap[2];
 extern uint32_t nfs4_fsstat_bitmap[2];
 extern uint32_t nfs4_pathconf_bitmap[2];
 
@@ -1322,7 +1358,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
 {
        struct nfs_fattr *nfp = getattr->gt_attrs;
        struct nfs_fsstat *fsstat = getattr->gt_fsstat;
-       struct nfs_fsinfo *fsinfo = getattr->gt_fsinfo;
        struct nfs_pathconf *pathconf = getattr->gt_pathconf;
        uint32_t attrlen, dummy32, bmlen,
                 bmval0 = 0,
@@ -1368,11 +1403,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
                nfp->nlink = 1;
                nfp->timestamp = jiffies;
        }
-       if (fsinfo) {
-               fsinfo->rtmult = fsinfo->wtmult = 512;  /* ??? */
-               fsinfo->lease_time = 60;
-       }
-
         if (bmval0 & FATTR4_WORD0_TYPE) {
                 READ_BUF(4);
                 len += 4;
@@ -1406,12 +1436,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
                        (long long)nfp->fsid_u.nfs4.major,
                        (long long)nfp->fsid_u.nfs4.minor);
         }
-        if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
-                READ_BUF(4);
-                len += 4;
-                READ32(fsinfo->lease_time);
-                dprintk("read_attrs: lease_time=%d\n", fsinfo->lease_time);
-        }
         if (bmval0 & FATTR4_WORD0_FILEID) {
                 READ_BUF(8);
                 len += 8;
@@ -1436,12 +1460,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
                 READ64(fsstat->tfiles);
                 dprintk("read_attrs: files_tot=0x%Lx\n", (long long) fsstat->tfiles);
         }
-        if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
-                READ_BUF(8);
-                len += 8;
-                READ64(fsinfo->maxfilesize);
-                dprintk("read_attrs: maxfilesize=0x%Lx\n", (long long) fsinfo->maxfilesize);
-        }
        if (bmval0 & FATTR4_WORD0_MAXLINK) {
                READ_BUF(4);
                len += 4;
@@ -1454,20 +1472,6 @@ decode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr,
                 READ32(pathconf->max_namelen);
                 dprintk("read_attrs: maxname=%d\n", pathconf->max_namelen);
         }
-        if (bmval0 & FATTR4_WORD0_MAXREAD) {
-                READ_BUF(8);
-                len += 8;
-                READ64(fsinfo->rtmax);
-               fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax;
-                dprintk("read_attrs: maxread=%d\n", fsinfo->rtmax);
-        }
-        if (bmval0 & FATTR4_WORD0_MAXWRITE) {
-                READ_BUF(8);
-                len += 8;
-                READ64(fsinfo->wtmax);
-               fsinfo->wtpref = fsinfo->wtmax;
-                dprintk("read_attrs: maxwrite=%d\n", fsinfo->wtmax);
-        }
        
         if (bmval1 & FATTR4_WORD1_MODE) {
                 READ_BUF(4);
@@ -1709,6 +1713,74 @@ out_bad_bitmap:
 }
 
 
+static int
+decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
+{
+       uint32_t *p;
+       uint32_t len, attrlen, bmlen, bmval0 = 0, bmval1 = 0;
+       int status;
+
+       status = decode_op_hdr(xdr, OP_GETATTR);
+       if (status)
+               return status;
+       READ_BUF(4);
+       READ32(bmlen);
+       if (bmlen < 1)
+               return -EIO;
+       READ_BUF(bmlen << 2);
+       READ32(bmval0);
+       if (bmval0 & ~(FATTR4_WORD0_MAXFILESIZE|FATTR4_WORD0_MAXREAD|
+                               FATTR4_WORD0_MAXWRITE|FATTR4_WORD0_LEASE_TIME))
+               goto out_bad_bitmap;
+       if (bmlen > 1) {
+               READ32(bmval1);
+               if (bmval1 != 0 || bmlen > 2)
+                       goto out_bad_bitmap;
+       }
+       READ_BUF(4);
+       READ32(attrlen);
+       READ_BUF(attrlen);
+       fsinfo->rtmult = fsinfo->wtmult = 512;  /* ??? */
+       fsinfo->lease_time = 60;
+       len = attrlen;
+
+       if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
+               len -= 4;
+               READ32(fsinfo->lease_time);
+               dprintk("read_attrs: lease_time=%d\n", fsinfo->lease_time);
+       }
+       if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
+               len -= 8;
+               READ64(fsinfo->maxfilesize);
+               dprintk("read_attrs: maxfilesize=0x%Lx\n", (long long) fsinfo->maxfilesize);
+       }
+       if (bmval0 & FATTR4_WORD0_MAXREAD) {
+               len -= 8;
+               READ64(fsinfo->rtmax);
+               fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax;
+               dprintk("read_attrs: maxread=%d\n", fsinfo->rtmax);
+       }
+       if (bmval0 & FATTR4_WORD0_MAXWRITE) {
+               len -= 8;
+               READ64(fsinfo->wtmax);
+               fsinfo->wtpref = fsinfo->wtmax;
+               dprintk("read_attrs: maxwrite=%d\n", fsinfo->wtmax);
+       }
+       if (len != 0)
+               goto out_bad_attrlen;
+       return 0;
+out_bad_attrlen:
+       printk(KERN_NOTICE "%s: server attribute length %u does not match bitmap 0x%x/0x%x\n",
+                       __FUNCTION__, (unsigned int)attrlen,
+                       (unsigned int) bmval0, (unsigned int)bmval1);
+       return -EIO;
+out_bad_bitmap:
+       printk(KERN_NOTICE "%s: server returned bad attribute bitmap 0x%x/0x%x\n",
+                       __FUNCTION__,
+                       (unsigned int)bmval0, (unsigned int)bmval1);
+       return -EIO;
+}
+
 static int
 decode_getfh(struct xdr_stream *xdr, struct nfs4_getfh *getfh)
 {
@@ -2403,6 +2475,27 @@ out:
        return status;
 }
 
+/*
+ * FSINFO request
+ */
+static int
+nfs4_xdr_dec_fsinfo(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_putfh(&xdr);
+       if (!status)
+               status = decode_fsinfo(&xdr, fsinfo);
+       if (!status)
+               status = -nfs_stat_to_errno(hdr.status);
+       return status;
+}
+
 /*
  * Decode RENEW response
  */
@@ -2476,6 +2569,7 @@ struct rpc_procinfo       nfs4_procedures[] = {
   PROC(OPEN_CONFIRM,   enc_open_confirm,       dec_open_confirm),
   PROC(CLOSE,          enc_close,      dec_close),
   PROC(SETATTR,                enc_setattr,    dec_setattr),
+  PROC(FSINFO,         enc_fsinfo,     dec_fsinfo),
   PROC(RENEW,          enc_renew,      dec_renew),
 };
 
index 1598d1b3c739c78f289c41738a11f219b1ee9dcd..d535a46f7d4fd68950ad16e93b9e04b739805340 100644 (file)
@@ -221,6 +221,7 @@ enum {
        NFSPROC4_CLNT_OPEN_CONFIRM,
        NFSPROC4_CLNT_CLOSE,
        NFSPROC4_CLNT_SETATTR,
+       NFSPROC4_CLNT_FSINFO,
        NFSPROC4_CLNT_RENEW,
 };
 
index 5bc59e4db5e373e288ea3b8e500844e0cd797302..09c2dd2216d0e486873f6f06a58487bfad3d3213 100644 (file)
@@ -449,7 +449,6 @@ struct nfs4_getattr {
         u32 *                          gt_bmval;          /* request */
         struct nfs_fattr *             gt_attrs;          /* response */
        struct nfs_fsstat *             gt_fsstat;         /* response */
-       struct nfs_fsinfo *             gt_fsinfo;         /* response */
        struct nfs_pathconf *           gt_pathconf;       /* response */
 };