From a0fb7913bbd006f828f385f23dc97a8d137dfa81 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 26 Feb 2004 06:48:26 -0800 Subject: [PATCH] [PATCH] kNFSd: correct symlink related error returns. From: NeilBrown unlike v2/v3, nfsv4 returns nfserr_inval when attempting to read, write, commit or test lock a symlink. nfsv4 does return nfserr_symlink on lookup and open, so a simple fix in fh_verify() will not work. --- fs/nfsd/nfs4proc.c | 14 +++++++++++--- fs/nfsd/nfs4state.c | 2 ++ fs/nfsd/nfs4xdr.c | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 7fdaa1ef51422..1821092b21649 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -224,11 +224,16 @@ nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_acc static inline int nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit) { + int status; + u32 *p = (u32 *)commit->co_verf.data; *p++ = nfssvc_boot.tv_sec; *p++ = nfssvc_boot.tv_usec; - return nfsd_commit(rqstp, current_fh, commit->co_offset, commit->co_count); + status = nfsd_commit(rqstp, current_fh, commit->co_offset, commit->co_count); + if (status == nfserr_symlink) + status = nfserr_inval; + return status; } static inline int @@ -558,9 +563,12 @@ zero_stateid: *p++ = nfssvc_boot.tv_sec; *p++ = nfssvc_boot.tv_usec; - return (nfsd_write(rqstp, current_fh, write->wr_offset, + status = nfsd_write(rqstp, current_fh, write->wr_offset, write->wr_vec, write->wr_vlen, write->wr_buflen, - &write->wr_how_written)); + &write->wr_how_written); + if (status == nfserr_symlink) + status = nfserr_inval; + return status; out: nfs4_unlock_state(); return status; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c60449aec0b1c..f92464da97b1c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1974,6 +1974,8 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) { printk("NFSD: nfsd4_lockt: fh_verify() failed!\n"); + if (status == nfserr_symlink) + status = nfserr_inval; goto out; } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index d69ef5af8c9c1..3ced62b6031a0 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2005,6 +2005,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read read->rd_offset, read->rd_iov, read->rd_vlen, &maxcount); + if (nfserr == nfserr_symlink) + nfserr = nfserr_inval; if (nfserr) return nfserr; eof = (read->rd_offset + maxcount >= read->rd_fhp->fh_dentry->d_inode->i_size); -- 2.53.0