Commit 74f1778d authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] knfsd: nfsd4 encode_dirent cleanup

No sensible client is ever going to request only the RDATTR_ERROR attribute, so
there's no point optimizing for that case.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 831804e6
......@@ -1805,73 +1805,62 @@ nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen,
*/
bmval0 = cd->rd_bmval[0];
bmval1 = cd->rd_bmval[1];
if ((bmval0 & ~(FATTR4_WORD0_RDATTR_ERROR)) || bmval1) {
/*
* "Heavyweight" case: we have no choice except to
* call nfsd4_encode_fattr().
*/
dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
if (IS_ERR(dentry)) {
nfserr = nfserrno(PTR_ERR(dentry));
goto error;
}
exp_get(exp);
if (d_mountpoint(dentry)) {
if ((nfserr = nfsd_cross_mnt(cd->rd_rqstp, &dentry,
&exp))) {
/*
* -EAGAIN is the only error returned from
* nfsd_cross_mnt() and it indicates that an
* up-call has been initiated to fill in the export
* options on exp. When the answer comes back,
* this call will be retried.
*/
dput(dentry);
exp_put(exp);
nfserr = nfserr_dropit;
goto error;
}
}
nfserr = nfsd4_encode_fattr(NULL, exp,
dentry, p, &buflen, cd->rd_bmval,
cd->rd_rqstp);
dput(dentry);
exp_put(exp);
if (!nfserr) {
p += buflen;
goto out;
}
if (nfserr == nfserr_resource)
goto nospc;
dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
if (IS_ERR(dentry)) {
nfserr = nfserrno(PTR_ERR(dentry));
goto error;
}
error:
exp_get(exp);
if (d_mountpoint(dentry)) {
if ((nfserr = nfsd_cross_mnt(cd->rd_rqstp, &dentry,
&exp))) {
/*
* If we get here, we experienced a miscellaneous
* failure while writing the attributes. If the
* client requested the RDATTR_ERROR attribute,
* we stuff the error code into this attribute
* and continue. If this attribute was not requested,
* then in accordance with the spec, we fail the
* entire READDIR operation(!)
* -EAGAIN is the only error returned from
* nfsd_cross_mnt() and it indicates that an
* up-call has been initiated to fill in the export
* options on exp. When the answer comes back,
* this call will be retried.
*/
if (!(bmval0 & FATTR4_WORD0_RDATTR_ERROR)) {
cd->common.err = nfserr;
return -EINVAL;
dput(dentry);
exp_put(exp);
nfserr = nfserr_dropit;
goto error;
}
bmval0 = FATTR4_WORD0_RDATTR_ERROR;
bmval1 = 0;
/* falling through here will do the right thing... */
}
nfserr = nfsd4_encode_fattr(NULL, exp,
dentry, p, &buflen, cd->rd_bmval,
cd->rd_rqstp);
dput(dentry);
exp_put(exp);
if (!nfserr) {
p += buflen;
goto out;
}
if (nfserr == nfserr_resource)
goto nospc;
error:
/*
* In the common "lightweight" case, we avoid
* the overhead of nfsd4_encode_fattr() by assembling
* a small fattr by hand.
* If we get here, we experienced a miscellaneous
* failure while writing the attributes. If the
* client requested the RDATTR_ERROR attribute,
* we stuff the error code into this attribute
* and continue. If this attribute was not requested,
* then in accordance with the spec, we fail the
* entire READDIR operation(!)
*/
if (!(bmval0 & FATTR4_WORD0_RDATTR_ERROR)) {
cd->common.err = nfserr;
return -EINVAL;
}
bmval0 = FATTR4_WORD0_RDATTR_ERROR;
bmval1 = 0;
if (buflen < 6)
goto nospc;
*p++ = htonl(2);
......@@ -1879,8 +1868,7 @@ nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen,
*p++ = htonl(bmval1);
attrlenp = p++;
if (bmval0 & FATTR4_WORD0_RDATTR_ERROR)
*p++ = nfserr; /* no htonl */
*p++ = nfserr; /* no htonl */
*attrlenp = htonl((char *)p - (char *)attrlenp - 4);
out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment