aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2013-04-30 15:28:51 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-04-30 15:44:20 -0400
commit2a6cf944c2f8ad5a7ef599ed275b85fa56eba3fc (patch)
tree77fdb6c0ccc56fca8aa36086aa2f46c67fb559ce /fs
parentd28fcc830c2eadc526e43b0a5f6d2ed04e7421ef (diff)
nfsd4: don't remap EISDIR errors in rename
We're going out of our way here to remap an error to make rfc 3530 happy--but the rfc itself (nor rfc 1813, which has similar language) gives no justification. And disagrees with local filesystem behavior, with Linux and posix man pages, and knfsd's implemented behavior for v2 and v3. And the documented behavior seems better, in that it gives a little more information--you could implement the 3530 behavior using the posix behavior, but not the other way around. Also, the Linux client makes no attempt to remap this error in the v4 case, so it can end up just returning EEXIST to the application in a case where it should return EISDIR. So honestly I think the rfc's are just buggy here--or in any case it doesn't see worth the trouble to remap this error. Reported-by: Frank S Filz <ffilz@us.ibm.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4proc.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 5dee81141ab7..8ae5abfe6ba2 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -813,21 +813,11 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
813 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, 813 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
814 rename->rn_snamelen, &cstate->current_fh, 814 rename->rn_snamelen, &cstate->current_fh,
815 rename->rn_tname, rename->rn_tnamelen); 815 rename->rn_tname, rename->rn_tnamelen);
816 816 if (status)
817 /* the underlying filesystem returns different error's than required 817 return status;
818 * by NFSv4. both save_fh and current_fh have been verified.. */ 818 set_change_info(&rename->rn_sinfo, &cstate->current_fh);
819 if (status == nfserr_isdir) 819 set_change_info(&rename->rn_tinfo, &cstate->save_fh);
820 status = nfserr_exist; 820 return nfs_ok;
821 else if ((status == nfserr_notdir) &&
822 (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) &&
823 S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode)))
824 status = nfserr_exist;
825
826 if (!status) {
827 set_change_info(&rename->rn_sinfo, &cstate->current_fh);
828 set_change_info(&rename->rn_tinfo, &cstate->save_fh);
829 }
830 return status;
831} 821}
832 822
833static __be32 823static __be32