Skip to content

Commit

Permalink
NFSD: Hoist status code encoding into XDR encoder functions
Browse files Browse the repository at this point in the history
The original intent was presumably to reduce code duplication. The
trade-off was:

- No support for an NFSD proc function returning a non-success
  RPC accept_stat value.
- No support for void NFS replies to non-NULL procedures.
- Everyone pays for the deduplication with a few extra conditional
  branches in a hot path.

In addition, nfsd_dispatch() leaves *statp uninitialized in the
success path, unlike svc_generic_dispatch().

Address all of these problems by moving the logic for encoding
the NFS status code into the NFS XDR encoders themselves. Then
update the NFS .pc_func methods to return an RPC accept_stat
value.

Signed-off-by: Chuck Lever <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
  • Loading branch information
chucklever authored and J. Bruce Fields committed Oct 12, 2020
1 parent 4b74fd7 commit cc028a1
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 120 deletions.
19 changes: 12 additions & 7 deletions fs/nfsd/nfs2acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
static __be32
nfsacld_proc_null(struct svc_rqst *rqstp)
{
return nfs_ok;
return rpc_success;
}

/*
Expand Down Expand Up @@ -79,7 +79,7 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst *rqstp)

/* resp->acl_{access,default} are released in nfssvc_release_getacl. */
out:
return resp->status;
return rpc_success;

fail:
posix_acl_release(resp->acl_access);
Expand Down Expand Up @@ -131,7 +131,7 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp)
nfssvc_decode_setaclargs. */
posix_acl_release(argp->acl_access);
posix_acl_release(argp->acl_default);
return resp->status;
return rpc_success;

out_drop_lock:
fh_unlock(fh);
Expand All @@ -157,7 +157,7 @@ static __be32 nfsacld_proc_getattr(struct svc_rqst *rqstp)
goto out;
resp->status = fh_getattr(&resp->fh, &resp->stat);
out:
return resp->status;
return rpc_success;
}

/*
Expand All @@ -179,7 +179,7 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)
goto out;
resp->status = fh_getattr(&resp->fh, &resp->stat);
out:
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -275,6 +275,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
int n;
int w;

*p++ = resp->status;
if (resp->status != nfs_ok)
return xdr_ressize_check(rqstp, p);

Expand Down Expand Up @@ -317,10 +318,12 @@ static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p)
{
struct nfsd_attrstat *resp = rqstp->rq_resp;

*p++ = resp->status;
if (resp->status != nfs_ok)
return xdr_ressize_check(rqstp, p);
goto out;

p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat);
out:
return xdr_ressize_check(rqstp, p);
}

Expand All @@ -329,11 +332,13 @@ static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p)
{
struct nfsd3_accessres *resp = rqstp->rq_resp;

*p++ = resp->status;
if (resp->status != nfs_ok)
return xdr_ressize_check(rqstp, p);
goto out;

p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat);
*p++ = htonl(resp->access);
out:
return xdr_ressize_check(rqstp, p);
}

Expand Down
9 changes: 5 additions & 4 deletions fs/nfsd/nfs3acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
static __be32
nfsd3_proc_null(struct svc_rqst *rqstp)
{
return nfs_ok;
return rpc_success;
}

/*
Expand Down Expand Up @@ -71,7 +71,7 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst *rqstp)

/* resp->acl_{access,default} are released in nfs3svc_release_getacl. */
out:
return resp->status;
return rpc_success;

fail:
posix_acl_release(resp->acl_access);
Expand Down Expand Up @@ -118,7 +118,7 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp)
nfs3svc_decode_setaclargs. */
posix_acl_release(argp->acl_access);
posix_acl_release(argp->acl_default);
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -173,6 +173,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
struct nfsd3_getaclres *resp = rqstp->rq_resp;
struct dentry *dentry = resp->fh.fh_dentry;

*p++ = resp->status;
p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
if (resp->status == 0 && dentry && d_really_is_positive(dentry)) {
struct inode *inode = d_inode(dentry);
Expand Down Expand Up @@ -217,8 +218,8 @@ static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p)
{
struct nfsd3_attrstat *resp = rqstp->rq_resp;

*p++ = resp->status;
p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);

return xdr_ressize_check(rqstp, p);
}

Expand Down
44 changes: 22 additions & 22 deletions fs/nfsd/nfs3proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static int nfs3_ftypes[] = {
static __be32
nfsd3_proc_null(struct svc_rqst *rqstp)
{
return nfs_ok;
return rpc_success;
}

/*
Expand All @@ -55,7 +55,7 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp)

resp->status = fh_getattr(&resp->fh, &resp->stat);
out:
return resp->status;
return rpc_success;
}

/*
Expand All @@ -73,7 +73,7 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp)
fh_copy(&resp->fh, &argp->fh);
resp->status = nfsd_setattr(rqstp, &resp->fh, &argp->attrs,
argp->check_guard, argp->guardtime);
return resp->status;
return rpc_success;
}

/*
Expand All @@ -96,7 +96,7 @@ nfsd3_proc_lookup(struct svc_rqst *rqstp)
resp->status = nfsd_lookup(rqstp, &resp->dirfh,
argp->name, argp->len,
&resp->fh);
return resp->status;
return rpc_success;
}

/*
Expand All @@ -115,7 +115,7 @@ nfsd3_proc_access(struct svc_rqst *rqstp)
fh_copy(&resp->fh, &argp->fh);
resp->access = argp->access;
resp->status = nfsd_access(rqstp, &resp->fh, &resp->access, NULL);
return resp->status;
return rpc_success;
}

/*
Expand All @@ -133,7 +133,7 @@ nfsd3_proc_readlink(struct svc_rqst *rqstp)
fh_copy(&resp->fh, &argp->fh);
resp->len = NFS3_MAXPATHLEN;
resp->status = nfsd_readlink(rqstp, &resp->fh, argp->buffer, &resp->len);
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -163,7 +163,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp)
resp->status = nfsd_read(rqstp, &resp->fh, argp->offset,
rqstp->rq_vec, argp->vlen, &resp->count,
&resp->eof);
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -196,7 +196,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
resp->committed, resp->verf);
resp->count = cnt;
out:
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -234,7 +234,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp)
resp->status = do_nfsd_create(rqstp, dirfhp, argp->name, argp->len,
attr, newfhp, argp->createmode,
(u32 *)argp->verf, NULL, NULL);
return resp->status;
return rpc_success;
}

/*
Expand All @@ -257,7 +257,7 @@ nfsd3_proc_mkdir(struct svc_rqst *rqstp)
resp->status = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
&argp->attrs, S_IFDIR, 0, &resp->fh);
fh_unlock(&resp->dirfh);
return resp->status;
return rpc_success;
}

static __be32
Expand Down Expand Up @@ -294,7 +294,7 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp)
argp->flen, argp->tname, &resp->fh);
kfree(argp->tname);
out:
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -337,7 +337,7 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp)
&argp->attrs, type, rdev, &resp->fh);
fh_unlock(&resp->dirfh);
out:
return resp->status;
return rpc_success;
}

/*
Expand All @@ -359,7 +359,7 @@ nfsd3_proc_remove(struct svc_rqst *rqstp)
resp->status = nfsd_unlink(rqstp, &resp->fh, -S_IFDIR,
argp->name, argp->len);
fh_unlock(&resp->fh);
return resp->status;
return rpc_success;
}

/*
Expand All @@ -380,7 +380,7 @@ nfsd3_proc_rmdir(struct svc_rqst *rqstp)
resp->status = nfsd_unlink(rqstp, &resp->fh, S_IFDIR,
argp->name, argp->len);
fh_unlock(&resp->fh);
return resp->status;
return rpc_success;
}

static __be32
Expand All @@ -402,7 +402,7 @@ nfsd3_proc_rename(struct svc_rqst *rqstp)
fh_copy(&resp->tfh, &argp->tfh);
resp->status = nfsd_rename(rqstp, &resp->ffh, argp->fname, argp->flen,
&resp->tfh, argp->tname, argp->tlen);
return resp->status;
return rpc_success;
}

static __be32
Expand All @@ -422,7 +422,7 @@ nfsd3_proc_link(struct svc_rqst *rqstp)
fh_copy(&resp->tfh, &argp->tfh);
resp->status = nfsd_link(rqstp, &resp->tfh, argp->tname, argp->tlen,
&resp->fh);
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -481,7 +481,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
resp->offset = NULL;
}

return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -551,7 +551,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)
}

out:
return resp->status;
return rpc_success;
}

/*
Expand All @@ -568,7 +568,7 @@ nfsd3_proc_fsstat(struct svc_rqst *rqstp)

resp->status = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
fh_put(&argp->fh);
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -611,7 +611,7 @@ nfsd3_proc_fsinfo(struct svc_rqst *rqstp)
}

fh_put(&argp->fh);
return resp->status;
return rpc_success;
}

/*
Expand Down Expand Up @@ -653,7 +653,7 @@ nfsd3_proc_pathconf(struct svc_rqst *rqstp)
}

fh_put(&argp->fh);
return resp->status;
return rpc_success;
}

/*
Expand All @@ -679,7 +679,7 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)
resp->status = nfsd_commit(rqstp, &resp->fh, argp->offset,
argp->count, resp->verf);
out:
return resp->status;
return rpc_success;
}


Expand Down
Loading

0 comments on commit cc028a1

Please sign in to comment.