knfsd: Introduction - Assorted bugfixes
Subsystems (3)
PATCH 1/1 knfsd: Introduction - Assorted bugfixes
Following are 5 patches for kNFSd suitable for inclusion in 2.6.20.
A couple should go to 2.6.19-stable, but I'll send those separately.
NeilBrown
[PATCH 001 of 5] knfsd: Update email address and status for NFSD in MAINTAINERS. [PATCH 002 of 5] knfsd: Fix setting of ACL server versions.
[PATCH 003 of 5] knfsd: Fix an NFSD bug with full sized, non-page-aligned reads. [PATCH 004 of 5] knfsd: Replace some warning ins nfsfh.h with BUG_ON or WARN_ON [PATCH 005 of 5] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie.
PATCH 1/1 knfsd: Update email address and status for NFSD in MAINTAINERS.
### Diffstat output
./MAINTAINERS | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
MAINTAINERS +2 -3
@@ -1941,11 +1941,10 @@ S: Maintained KERNEL NFSD P: Neil Brown -M: [email protected] +M: [email protected] L: [email protected] W: http://nfs.sourceforge.net/ -W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/ -S: Maintained +S: Supported KERNEL VIRTUAL MACHINE (KVM) P: Avi Kivity
PATCH 1/1 knfsd: Fix setting of ACL server versions.
In reply to NeilBrownDue to silly typos, if the nfs versions are explicitly set, no NFSACL versions get enabled.
Also improve an error message that would have made this bug a little easier to find.
### Diffstat output
./fs/nfsd/nfssvc.c | 8 ++++---- ./net/sunrpc/svc.c | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-)
fs/nfsd/nfssvc.c +4 -4
@@ -72,7 +72,7 @@ static struct svc_program nfsd_acl_progr .pg_prog = NFS_ACL_PROGRAM, .pg_nvers = NFSD_ACL_NRVERS, .pg_vers = nfsd_acl_versions, - .pg_name = "nfsd", + .pg_name = "nfsacl", .pg_class = "nfsd", .pg_stats = &nfsd_acl_svcstats, .pg_authenticate = &svc_set_client,
@@ -118,16 +118,16 @@ int nfsd_vers(int vers, enum vers_op chaswitch (change) {case NFSD_SET : nfsd_versions[vers] = nfsd_version[vers]; -break ;#if defined(CONFIG_NFSD_V2_ACL ) || defined(CONFIG_NFSD_V3_ACL )if (vers <NFSD_ACL_NRVERS ) - nfsd_acl_version[vers] = nfsd_acl_version[vers]; + nfsd_acl_versions[vers] = nfsd_acl_version[vers];#endif +break ;case NFSD_CLEAR : nfsd_versions[vers] =NULL ;#if defined(CONFIG_NFSD_V2_ACL ) || defined(CONFIG_NFSD_V3_ACL )if (vers <NFSD_ACL_NRVERS ) - nfsd_acl_version[vers] =NULL ; + nfsd_acl_versions[vers] =NULL ;#endif break ;case NFSD_TEST :
net/sunrpc/svc.c +2 -1
@@ -910,7 +910,8 @@ err_bad_prog: err_bad_vers:#ifdef RPC_PARANOIA -printk ("svc: unknown version (%d)\n" , vers); +printk ("svc: unknown version (%d for prog %d, %s)\n" , + vers, prog, progp->pg_name);#endif serv->sv_stats->rpcbadfmt++;svc_putnl (resv,RPC_PROG_MISMATCH );
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Fix an NFSD bug with full sized, non-page-aligned reads.
In reply to NeilBrownNFSd assumes that largest number of pages that will be needed for a request+response is 2+N where N pages is the size of the largest permitted read/write request. The '2' are 1 for the non-data part of the request, and 1 for the non-data part of the reply.
However, when a read request is not page-aligned, and we choose to use ->sendfile to send it directly from the page cache, we may need N+1 pages to hold the whole reply. This can overflow and array and cause an Oops.
This patch increases size of the array for holding pages by one and makes sure that entry is NULL when it is not in use.
### Diffstat output
./fs/nfsd/vfs.c | 3 ++- ./include/linux/sunrpc/svc.h | 5 ++++- ./net/sunrpc/svcsock.c | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-)
fs/nfsd/vfs.c +2 -1
@@ -822,7 +822,8 @@ nfsd_read_actor(read_descriptor_t *desc, rqstp->rq_res.page_len = size; }else if (page != pp[-1 ]) {get_page (page); -put_page (*pp); +if (*pp) +put_page (*pp); *pp = page; rqstp->rq_resused++; rqstp->rq_res.page_len += size;
include/linux/sunrpc/svc.h +4 -1
@@ -144,8 +144,11 @@ extern u32 svc_max_payload(const struct* * Each request/reply pair can have at most one "payload", plus two pages, * one for the request, and one for the reply. +* We using ->sendfile to return read data, we might need one extra page +* if the request is not page-aligned. So add another '1'. */ -#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2) +#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE \ + + 2 + 1)static inline u32 svc_getnl (struct kvec *iov) {
net/sunrpc/svcsock.c +2 -0
@@ -1306,6 +1306,8 @@ svc_recv(struct svc_rqst *rqstp, long tischedule_timeout_uninterruptible (msecs_to_jiffies (500 )); rqstp->rq_pages[i] = p; } + rqstp->rq_pages[i++] =NULL ;/* this might be seen in nfs_read_actor */ +BUG_ON (pages >=RPCSVC_MAXPAGES );/* Make arg->head point to first page and arg->pages point to rest */ arg = &rqstp->rq_arg;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Replace some warning ins nfsfh.h with BUG_ON or WARN_ON
In reply to NeilBrownA couple of the warning will be followed by an Oops if they ever fire, so may as well be BUG_ON. Another isn't obviously fatal but has never been known to fire, so make it a WARN_ON.
### Diffstat output
./include/linux/nfsd/nfsfh.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
include/linux/nfsd/nfsfh.h +4 -11
@@ -217,11 +217,7 @@ void fh_put(struct svc_fh *);static __inline__struct svc_fh *fh_copy (struct svc_fh *dst,struct svc_fh *src) { -if (src->fh_dentry || src->fh_locked) { -struct dentry *dentry = src->fh_dentry; -printk (KERN_ERR "fh_copy: copying %s/%s, already verified!\n" , - dentry->d_parent->d_name.name, dentry->d_name.name); - } +WARN_ON (src->fh_dentry || src->fh_locked); *dst = *src;return dst;
@@ -300,10 +296,8 @@ fh_lock_nested(struct svc_fh *fhp, unsigdfprintk (FILEOP ,"nfsd: fh_lock(%s) locked = %d\n" ,SVCFH_fmt (fhp), fhp->fh_locked); -if (!fhp->fh_dentry) { -printk (KERN_ERR "fh_lock: fh not verified!\n" ); -return ; - } +BUG_ON (!dentry); +if (fhp->fh_locked) {printk (KERN_WARNING "fh_lock: %s/%s already locked!\n" , dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -328,8 +322,7 @@ fh_lock(struct svc_fh *fhp)static inline void fh_unlock (struct svc_fh *fhp) { -if (!fhp->fh_dentry) -printk (KERN_ERR "fh_unlock: fh not verified!\n" ); +BUG_ON (!fhp->fh_dentry);if (fhp->fh_locked) {fill_post_wcc (fhp);
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie.
In reply to NeilBrownFrom: Peter Staubach <[email protected]>
NFS V3 (and V4) support exclusive create by passing a 'cookie' which can get stored with the file. If the file exists but has exactly the right cookie stored, then we assume this is a retransmit and the exclusive create was successful.
The cookie is 64bits and is traditionally stored in the mtime and atime fields. This causes a problem with Solaris7 as negative mtime or atime confuse it. So we moved two bits into the mode word instead.
But inherited ACLs sometimes overwrite the mode word on create, so this is a problem.
So we give up and just store 62 of the 64 bits and assume that is close enough.
### Diffstat output
./fs/nfsd/vfs.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-)
fs/nfsd/vfs.c +5 -16
@@ -1249,7 +1249,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, s__be32 err;int host_err;__u32 v_mtime=0 , v_atime=0 ; -int v_mode=0 ; err = nfserr_perm;if (!flen)
@@ -1286,16 +1285,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, s goto out;if (createmode ==NFS3_CREATE_EXCLUSIVE ) { -/* while the verifier would fit in mtime+atime, -* solaris7 gets confused (bugid 4218508) if these have -* the high bit set, so we use the mode as well +/* solaris7 gets confused (bugid 4218508) if these have +* the high bit set, so just clear the high bits. */ v_mtime = verifier[0 ]&0x7fffffff ; v_atime = verifier[1 ]&0x7fffffff ; - v_mode =S_IFREG - | ((verifier[0 ]&0x80000000 ) >> (32 -7 ))/* u+x */ - | ((verifier[1 ]&0x80000000 ) >> (32 -9 ))/* u+r */ - ; }if (dchild->d_inode) {
@@ -1323,7 +1317,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, scase NFS3_CREATE_EXCLUSIVE :if ( dchild->d_inode->i_mtime.tv_sec == v_mtime && dchild->d_inode->i_atime.tv_sec == v_atime - && dchild->d_inode->i_mode == v_mode && dchild->d_inode->i_size ==0 )break ;/* fallthru */
@@ -1345,26 +1338,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, s }if (createmode ==NFS3_CREATE_EXCLUSIVE ) { -/* Cram the verifier into atime/mtime/mode */ +/* Cram the verifier into atime/mtime */ iap->ia_valid =ATTR_MTIME |ATTR_ATIME - |ATTR_MTIME_SET |ATTR_ATIME_SET - |ATTR_MODE ; + |ATTR_MTIME_SET |ATTR_ATIME_SET ;/* XXX someone who knows this better please fix it for nsec */ iap->ia_mtime.tv_sec = v_mtime; iap->ia_atime.tv_sec = v_atime; iap->ia_mtime.tv_nsec =0 ; iap->ia_atime.tv_nsec =0 ; - iap->ia_mode = v_mode; }/* Set file attributes. -* Mode has already been set but we might need to reset it -* for CREATE_EXCLUSIVE * Irix appears to send along the gid when it tries to * implement setgid directories via NFS. Clear out all that cruft. */ set_attr: -if ((iap->ia_valid &= ~(ATTR_UID |ATTR_GID )) !=0 ) { +if ((iap->ia_valid &= ~(ATTR_UID |ATTR_GID |ATTR_MODE )) !=0 ) {__be32 err2 =nfsd_setattr (rqstp, resfhp, iap,0 , (time_t )0 );if (err2) err = err2;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs