nfsd4: it's OK to return nfserr_symlink
authorJ. Bruce Fields <bfields@redhat.com>
Mon, 15 Aug 2011 22:39:32 +0000 (18:39 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 26 Aug 2011 22:22:50 +0000 (18:22 -0400)
The nfsd4 code has a bunch of special exceptions for error returns which
map nfserr_symlink to other errors.

In fact, the spec makes it clear that nfserr_symlink is to be preferred
over less specific errors where possible.

The patch that introduced it back in 2.6.4 is "kNFSd: correct symlink
related error returns.", which claims that these special exceptions are
represent an NFSv4 break from v2/v3 tradition--when in fact the symlink
error was introduced with v4.

I suspect what happened was pynfs tests were written that were overly
faithful to the (known-incomplete) rfc3530 error return lists, and then
code was fixed up mindlessly to make the tests pass.

Delete these unnecessary exceptions.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c

index d784ceb..479ffb1 100644 (file)
@@ -488,17 +488,12 @@ static __be32
 nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
             struct nfsd4_commit *commit)
 {
-       __be32 status;
-
        u32 *p = (u32 *)commit->co_verf.data;
        *p++ = nfssvc_boot.tv_sec;
        *p++ = nfssvc_boot.tv_usec;
 
-       status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
+       return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
                             commit->co_count);
-       if (status == nfserr_symlink)
-               status = nfserr_inval;
-       return status;
 }
 
 static __be32
@@ -513,8 +508,6 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR,
                           NFSD_MAY_CREATE);
-       if (status == nfserr_symlink)
-               status = nfserr_notdir;
        if (status)
                return status;
 
@@ -740,8 +733,6 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                return nfserr_grace;
        status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
                             remove->rm_name, remove->rm_namelen);
-       if (status == nfserr_symlink)
-               return nfserr_notdir;
        if (!status) {
                fh_unlock(&cstate->current_fh);
                set_change_info(&remove->rm_cinfo, &cstate->current_fh);
@@ -772,8 +763,6 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                   (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) &&
                    S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode)))
                status = nfserr_exist;
-       else if (status == nfserr_symlink)
-               status = nfserr_notdir;
 
        if (!status) {
                set_change_info(&rename->rn_sinfo, &cstate->current_fh);
@@ -913,8 +902,6 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        write->wr_bytes_written = cnt;
 
-       if (status == nfserr_symlink)
-               status = nfserr_inval;
        return status;
 }
 
index 3787ec1..aa0a36e 100644 (file)
@@ -4179,12 +4179,8 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid))
                goto out;
 
-       if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) {
-               dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
-               if (status == nfserr_symlink)
-                       status = nfserr_inval;
+       if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
                goto out;
-       }
 
        inode = cstate->current_fh.fh_dentry->d_inode;
        locks_init_lock(&file_lock);
index 51ec1f2..78c792f 100644 (file)
@@ -2778,8 +2778,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
                        read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
                        &maxcount);
 
-       if (nfserr == nfserr_symlink)
-               nfserr = nfserr_inval;
        if (nfserr)
                return nfserr;
        eof = (read->rd_offset + maxcount >=
@@ -2905,8 +2903,6 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
            readdir->common.err == nfserr_toosmall &&
            readdir->buffer == page) 
                nfserr = nfserr_toosmall;
-       if (nfserr == nfserr_symlink)
-               nfserr = nfserr_notdir;
        if (nfserr)
                goto err_no_verf;