]> git.baikalelectronics.ru Git - kernel.git/commitdiff
NFSD: Update the GETATTR3res encoder to use struct xdr_stream
authorChuck Lever <chuck.lever@oracle.com>
Wed, 21 Oct 2020 15:58:41 +0000 (11:58 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 22 Mar 2021 14:18:51 +0000 (10:18 -0400)
As an additional clean up, some renaming is done to more closely
reflect the data type and variable names used in the NFSv3 XDR
definition provided in RFC 1813. "attrstat" is an NFSv2 thingie.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfsfh.c
fs/nfsd/nfsfh.h
fs/nfsd/xdr3.h

index 8675851199f8dde167394d3f3d524b8f13244acf..76a84481d526c42e40673390580aa6a11f9e03b8 100644 (file)
@@ -736,7 +736,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
        [NFS3PROC_GETATTR] = {
                .pc_func = nfsd3_proc_getattr,
                .pc_decode = nfs3svc_decode_fhandleargs,
-               .pc_encode = nfs3svc_encode_attrstatres,
+               .pc_encode = nfs3svc_encode_getattrres,
                .pc_release = nfs3svc_release_fhandle,
                .pc_argsize = sizeof(struct nfsd_fhandle),
                .pc_ressize = sizeof(struct nfsd3_attrstatres),
index 9d9a01ce0b270835129cfc90d40f6cbb54b0c3c0..75739861d235e71dd0990a6f9071aae8fe137529 100644 (file)
@@ -20,7 +20,7 @@
 /*
  * Mapping of S_IF* types to NFS file types
  */
-static u32     nfs3_ftypes[] = {
+static const u32 nfs3_ftypes[] = {
        NF3NON,  NF3FIFO, NF3CHR, NF3BAD,
        NF3DIR,  NF3BAD,  NF3BLK, NF3BAD,
        NF3REG,  NF3BAD,  NF3LNK, NF3BAD,
@@ -39,6 +39,15 @@ encode_time3(__be32 *p, struct timespec64 *time)
        return p;
 }
 
+static __be32 *
+encode_nfstime3(__be32 *p, const struct timespec64 *time)
+{
+       *p++ = cpu_to_be32((u32)time->tv_sec);
+       *p++ = cpu_to_be32(time->tv_nsec);
+
+       return p;
+}
+
 static bool
 svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep)
 {
@@ -82,6 +91,19 @@ svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp)
        return true;
 }
 
+static bool
+svcxdr_encode_nfsstat3(struct xdr_stream *xdr, __be32 status)
+{
+       __be32 *p;
+
+       p = xdr_reserve_space(xdr, sizeof(status));
+       if (!p)
+               return false;
+       *p = status;
+
+       return true;
+}
+
 static __be32 *
 encode_fh(__be32 *p, struct svc_fh *fhp)
 {
@@ -253,6 +275,58 @@ svcxdr_decode_devicedata3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
                svcxdr_decode_specdata3(xdr, args);
 }
 
+static bool
+svcxdr_encode_fattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
+                    const struct svc_fh *fhp, const struct kstat *stat)
+{
+       struct user_namespace *userns = nfsd_user_namespace(rqstp);
+       __be32 *p;
+       u64 fsid;
+
+       p = xdr_reserve_space(xdr, XDR_UNIT * 21);
+       if (!p)
+               return false;
+
+       *p++ = cpu_to_be32(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
+       *p++ = cpu_to_be32((u32)(stat->mode & S_IALLUGO));
+       *p++ = cpu_to_be32((u32)stat->nlink);
+       *p++ = cpu_to_be32((u32)from_kuid_munged(userns, stat->uid));
+       *p++ = cpu_to_be32((u32)from_kgid_munged(userns, stat->gid));
+       if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN)
+               p = xdr_encode_hyper(p, (u64)NFS3_MAXPATHLEN);
+       else
+               p = xdr_encode_hyper(p, (u64)stat->size);
+
+       /* used */
+       p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
+
+       /* rdev */
+       *p++ = cpu_to_be32((u32)MAJOR(stat->rdev));
+       *p++ = cpu_to_be32((u32)MINOR(stat->rdev));
+
+       switch(fsid_source(fhp)) {
+       case FSIDSOURCE_FSID:
+               fsid = (u64)fhp->fh_export->ex_fsid;
+               break;
+       case FSIDSOURCE_UUID:
+               fsid = ((u64 *)fhp->fh_export->ex_uuid)[0];
+               fsid ^= ((u64 *)fhp->fh_export->ex_uuid)[1];
+               break;
+       default:
+               fsid = (u64)huge_encode_dev(fhp->fh_dentry->d_sb->s_dev);
+       }
+       p = xdr_encode_hyper(p, fsid);
+
+       /* fileid */
+       p = xdr_encode_hyper(p, stat->ino);
+
+       p = encode_nfstime3(p, &stat->atime);
+       p = encode_nfstime3(p, &stat->mtime);
+       encode_nfstime3(p, &stat->ctime);
+
+       return true;
+}
+
 static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp)
 {
        u64 f;
@@ -713,17 +787,22 @@ nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p)
 
 /* GETATTR */
 int
-nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p)
+nfs3svc_encode_getattrres(struct svc_rqst *rqstp, __be32 *p)
 {
+       struct xdr_stream *xdr = &rqstp->rq_res_stream;
        struct nfsd3_attrstat *resp = rqstp->rq_resp;
 
-       *p++ = resp->status;
-       if (resp->status == 0) {
-               lease_get_mtime(d_inode(resp->fh.fh_dentry),
-                               &resp->stat.mtime);
-               p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat);
+       if (!svcxdr_encode_nfsstat3(xdr, resp->status))
+               return 0;
+       switch (resp->status) {
+       case nfs_ok:
+               lease_get_mtime(d_inode(resp->fh.fh_dentry), &resp->stat.mtime);
+               if (!svcxdr_encode_fattr3(rqstp, xdr, &resp->fh, &resp->stat))
+                       return 0;
+               break;
        }
-       return xdr_ressize_check(rqstp, p);
+
+       return 1;
 }
 
 /* SETATTR, REMOVE, RMDIR */
index 10b44421eacec3172d6e79d84769406be8b122bf..c475d2271f9c503bb05e4073ba6661ebb8371e38 100644 (file)
@@ -711,7 +711,7 @@ char * SVCFH_fmt(struct svc_fh *fhp)
        return buf;
 }
 
-enum fsid_source fsid_source(struct svc_fh *fhp)
+enum fsid_source fsid_source(const struct svc_fh *fhp)
 {
        if (fhp->fh_handle.fh_version != 1)
                return FSIDSOURCE_DEV;
index f58933519f3806d159939d0295f3f9601aa38625..aff2cda5c6c3372b616bead9e5a90cd7e40b5197 100644 (file)
@@ -82,7 +82,7 @@ enum fsid_source {
        FSIDSOURCE_FSID,
        FSIDSOURCE_UUID,
 };
-extern enum fsid_source fsid_source(struct svc_fh *fhp);
+extern enum fsid_source fsid_source(const struct svc_fh *fhp);
 
 
 /*
index 3e1578953f544c6257f3a26d4e70bff3d781937b..0822981c61b935b95738e3a879b32bf0f179bfc3 100644 (file)
@@ -280,7 +280,7 @@ int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *);
-int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *);
+int nfs3svc_encode_getattrres(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *);