Skip to contentSkip to conversation

kNFSd - 0 of 11 - Introduction

PATCH New NeilBrown 2 participants 13 messages May 31, 2004

Subsystems (4)
lore
Share & tools
lore

NeilBrown

author
#0 lore raw

PATCH 1/1 kNFSd - 0 of 11 - Introduction

11 patches for knfsd and related code in 2.6.7-rc1-mm1 follow.

The first is significant is it fixes a oopsable bug in nfsv3. Others a minor tidyups and improvements and a couple of NFSv4 server bugs.

Thanks,
NeilBrown

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#1 lore raw

PATCH 1/1 kNFSd - 1 of 11 - Fix nfs3 dentry encoding

The "offset" in an entry in an nfs3 readdir response is 64 bits long and as it has only a 32 bit alignment, it fall half in one page of the response and half in another.

This patch adds a second offset pointer (offset1) which points to the second half in the unusual case of the offset being split between pages, and sets and uses it accordingly.

From: Olaf Kirch <[email protected]>

----------- Diffstat output ------------

 ./fs/nfsd/nfs3proc.c        |    1 -
 ./fs/nfsd/nfs3xdr.c         |   39 ++++++++++++++++++++++++++++++++-------
 ./include/linux/nfsd/xdr3.h |    1 +
 3 files changed, 33 insertions(+), 8 deletions(-)
fs/nfsd/nfs3proc.c renamed from fs/nfsd/nfs3proc.c~current~ +0 -1
diff ./fs/nfsd/nfs3proc.c~current~ ./fs/nfsd/nfs3proc.c
@@ -436,7 +436,6 @@ nfsd3_proc_readdir(struct svc_rqst *rqst
 	resp->buflen = count;
 	resp->common.err = nfs_ok;
 	resp->buffer = argp->buffer;
-	resp->offset = NULL;
 	resp->rqstp = rqstp;
 	nfserr = nfsd_readdir(rqstp, &resp->fh, (loff_t*) &argp->cookie, 
 					&resp->common, nfs3svc_encode_entry);
fs/nfsd/nfs3xdr.c renamed from fs/nfsd/nfs3xdr.c~current~ +32 -7
diff ./fs/nfsd/nfs3xdr.c~current~ ./fs/nfsd/nfs3xdr.c
@@ -847,8 +847,18 @@ encode_entry(struct readdir_cd *ccd, con
 	int		elen;		/* estimated entry length in words */
 	int		num_entry_words = 0;	/* actual number of words */
 
-	if (cd->offset)
-		xdr_encode_hyper(cd->offset, (u64) offset);
+	if (cd->offset) {
+		u64 offset64 = offset;
+
+		if (unlikely(cd->offset1)) {
+			/* we ended up with offset on a page boundary */
+			*cd->offset = htonl(offset64 >> 32);
+			*cd->offset1 = htonl(offset64 & 0xffffffff);
+			cd->offset1 = NULL;
+		} else {
+			xdr_encode_hyper(cd->offset, (u64) offset);
+		}
+	}
 
 	/*
 	dprintk("encode_entry(%.*s @%ld%s)\n",
@@ -929,17 +939,32 @@ encode_entry(struct readdir_cd *ccd, con
 			/* update offset */
 			cd->offset = cd->buffer + (cd->offset - tmp);
 		} else {
+			unsigned int offset_r = (cd->offset - tmp) << 2;
+
+			/* update pointer to offset location.
+			 * This is a 64bit quantity, so we need to
+			 * deal with 3 cases:
+			 *  -	entirely in first page
+			 *  -	entirely in second page
+			 *  -	4 bytes in each page
+			 */
+			if (offset_r + 8 <= len1) {
+				cd->offset = p + (cd->offset - tmp);
+			} else if (offset_r >= len1) {
+				cd->offset -= len1 >> 2;
+			} else {
+				/* sitting on the fence */
+				BUG_ON(offset_r != len1 - 4);
+				cd->offset = p + (cd->offset - tmp);
+				cd->offset1 = tmp;
+			}
+
 			len2 = (num_entry_words << 2) - len1;
 
 			/* move from temp page to current and next pages */
 			memmove(p, tmp, len1);
 			memmove(tmp, (caddr_t)tmp+len1, len2);
 
-			/* update offset */
-			if (((cd->offset - tmp) << 2) < len1)
-				cd->offset = p + (cd->offset - tmp);
-			else
-				cd->offset -= len1 >> 2;
 			p = tmp + (len2 >> 2);
 		}
 	}
include/linux/nfsd/xdr3.h renamed from include/linux/nfsd/xdr3.h~current~ +1 -0
diff ./include/linux/nfsd/xdr3.h~current~ ./include/linux/nfsd/xdr3.h
@@ -170,6 +170,7 @@ struct nfsd3_readdirres {
 	u32 *			buffer;
 	int			buflen;
 	u32 *			offset;
+	u32 *			offset1;
 	struct svc_rqst *	rqstp;
 
 };

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#2 lore raw

PATCH 1/1 kNFSd - 2 of 11 - nfsd_exp_remove_null_check.patch

In reply to NeilBrown

If ek = exp_find_key() is not an error, then ek->ek_export should be set; no point in checking if it's NULL.

From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./include/linux/nfsd/export.h |    3 +--
 1 files changed, 1 insertion(+), 2 deletions(-)
include/linux/nfsd/export.h renamed from include/linux/nfsd/export.h~current~ +1 -2
diff ./include/linux/nfsd/export.h~current~ ./include/linux/nfsd/export.h
@@ -124,8 +124,7 @@ exp_find(struct auth_domain *clp, int fs
 		int err;
 		exp_get(exp);
 		expkey_put(&ek->h, &svc_expkey_cache);
-		if (exp &&
-		    (err = cache_check(&svc_export_cache, &exp->h, reqp)))
+		if ((err = cache_check(&svc_export_cache, &exp->h, reqp)))
 			exp = ERR_PTR(err);
 		return exp;
 	} else

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#3 lore raw

PATCH 1/1 kNFSd - 10 of 11 - nfsd-create-fix.patch

In reply to NeilBrown

Fix error return in create. (See comment in xdr for createtype4 at end of rfc3530.)

From: Andy Adamson <[email protected]>
From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./fs/nfsd/nfs4proc.c |    2 +-
 ./fs/nfsd/nfs4xdr.c  |    3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)
fs/nfsd/nfs4proc.c renamed from fs/nfsd/nfs4proc.c~current~ +1 -1
diff ./fs/nfsd/nfs4proc.c~current~ ./fs/nfsd/nfs4proc.c
@@ -389,7 +389,7 @@ nfsd4_create(struct svc_rqst *rqstp, str
 		break;
 
 	default:
-		BUG();
+		status = nfserr_badtype;
 	}
 
 	if (!status) {
fs/nfsd/nfs4xdr.c renamed from fs/nfsd/nfs4xdr.c~current~ +1 -2
diff ./fs/nfsd/nfs4xdr.c~current~ ./fs/nfsd/nfs4xdr.c
@@ -538,9 +538,8 @@ nfsd4_decode_create(struct nfsd4_compoun
 	case NF4SOCK:
 	case NF4FIFO:
 	case NF4DIR:
-		break;
 	default:
-		goto xdr_error;
+		break;
 	}
 
 	READ_BUF(4);

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#4 lore raw

PATCH 1/1 kNFSd - 9 of 11 - nfsd-setclientid-fix.patch

In reply to NeilBrown

Fix a somewhat bizarre corner case in clid processing: a clientid match isn't required for case 3.

From: Andy Adamson <[email protected]>
From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./fs/nfsd/nfs4state.c |    4 +---
 1 files changed, 1 insertion(+), 3 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +1 -3
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
@@ -495,15 +495,13 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		gen_clid(new);
 		gen_confirm(new);
 		add_to_unconfirmed(new, strhashval);
-	} else if (!cmp_clid(&conf->cl_clientid, &unconf->cl_clientid) &&
-	      !cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
+	} else if (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
 		/*	
 		 * CASE3:
 		 * confirmed found (name, principal match)
 		 * confirmed verifier does not match input clverifier
 		 *
 		 * unconfirmed found (name match)
-		 * confirmed->cl_clientid != unconfirmed->cl_clientid and
 		 * confirmed->cl_confirm != unconfirmed->cl_confirm
 		 *
 		 * remove unconfirmed.

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#5 lore raw

PATCH 1/1 kNFSd - 8 of 11 - nfsd-getattr-fix.patch

In reply to NeilBrown

Oops: we were claiming to support the TIME_CREATE attribute, when we don't

really.

From: Andy Adamson <[email protected]>
From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./include/linux/nfsd/nfsd.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
include/linux/nfsd/nfsd.h renamed from include/linux/nfsd/nfsd.h~current~ +1 -1
diff ./include/linux/nfsd/nfsd.h~current~ ./include/linux/nfsd/nfsd.h
@@ -281,7 +281,7 @@ static inline int is_fsid(struct svc_fh 
  | FATTR4_WORD1_OWNER	        | FATTR4_WORD1_OWNER_GROUP  | FATTR4_WORD1_RAWDEV           \
  | FATTR4_WORD1_SPACE_AVAIL     | FATTR4_WORD1_SPACE_FREE   | FATTR4_WORD1_SPACE_TOTAL      \
  | FATTR4_WORD1_SPACE_USED      | FATTR4_WORD1_TIME_ACCESS  | FATTR4_WORD1_TIME_ACCESS_SET  \
- | FATTR4_WORD1_TIME_CREATE     | FATTR4_WORD1_TIME_DELTA   | FATTR4_WORD1_TIME_METADATA    \
+ | FATTR4_WORD1_TIME_DELTA   | FATTR4_WORD1_TIME_METADATA    \
  | FATTR4_WORD1_TIME_MODIFY     | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID)
 
 /* These will return ERR_INVAL if specified in GETATTR or READDIR. */

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#6 lore raw

PATCH 1/1 kNFSd - 11 of 11 - exporting_doc_typos.patch

In reply to NeilBrown

Fix minor typos.

From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./Documentation/filesystems/Exporting |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)
Documentation/filesystems/Exporting renamed from Documentation/filesystems/Exporting~current~ +12 -12
diff ./Documentation/filesystems/Exporting~current~ ./Documentation/filesystems/Exporting
@@ -32,7 +32,7 @@ tree.  This means that if any filesystem
 all of the ancestors of that filesystem object are also in the dcache.
 As normal access is by filename this prefix is created naturally and
 maintained easily (by each object maintaining a reference count on
-it's parent).
+its parent).
 
 However when objects are included into the dcache by interpreting a
 filehandle fragment, there is no automatic creation of a path prefix
@@ -44,15 +44,15 @@ the dcache that are not needed for norma
 2/ The dcache must be prepared for a newly found (via ->lookup) directory
    to already have a (non-connected) dentry, and must be able to move
    that dentry into place (based on the parent and name in the
-   ->lookup).   This is particuarly needed for directories as
+   ->lookup).   This is particularly needed for directories as
    it is a dcache invariant that directories only have one dentry.
 
 To implement these features, the dcache has:
 
-a/ A dentry flag  DCACHE_DISCONNECTED which is set on
-   and dentry that might not be part of the proper prefix.
+a/ A dentry flag DCACHE_DISCONNECTED which is set on
+   any dentry that might not be part of the proper prefix.
    This is set when anonymous dentries are created, and cleared when a
-   dentry is noticed to be a child on a dentry which is in the proper
+   dentry is noticed to be a child of a dentry which is in the proper
    prefix. 
 
 b/ A per-superblock list "s_anon" of dentries which are the roots of
@@ -123,9 +123,9 @@ filesystem:
   get_name.  When given a parent dentry and a child dentry, this
     should find a name in the directory identified by the parent
     dentry, which leads to the object identified by the child dentry.
-    If no get_name function is supplied, a default implementation
-    which used vfs_readdir to find potential names, and matches inode
-    numbers to find the correct match.
+    If no get_name function is supplied, a default implementation is
+    provided which uses vfs_readdir to find potential names, and
+    matches inode numbers to find the correct match.
 
   get_parent.  When given a dentry for a directory, this should return 
     a dentry for the parent.  Quite possibly the parent dentry will
@@ -135,7 +135,7 @@ filesystem:
     ->lookup("..") is *not* used as a default as it can leave ".."
     entries in the dcache which are too messy to work with.
 
-  get_dentry.  When given a opaque datum, this should find the
+  get_dentry.  When given an opaque datum, this should find the
     implied object and create a dentry for it (possibly with
     d_alloc_anon). 
     The opaque datum is whatever is passed down by the decode_fh
@@ -143,7 +143,7 @@ filesystem:
     fragment.
     decode_fh passes two datums through find_exported_dentry.  One that 
     should be used to identify the target object, and one that can be
-    used to identify the objects parent, should that be necessary.
+    used to identify the object's parent, should that be necessary.
     The default get_dentry function assumes that the datum contains an
     inode number and a generation number, and it attempts to get the
     inode using "iget" and check it's validity by matching the
@@ -164,8 +164,8 @@ filehandle assuming the format used by t
 passed them to find_exported_dentry.
 
 
-A filehandle fragment consists of an array of 1 or more 4byte words.
-Together with a one byte "type".
+A filehandle fragment consists of an array of 1 or more 4byte words,
+together with a one byte "type".
 The decode_fh routine should not depend on the stated size that is
 passed to it.  This size may be larger than the original filehandle
 generated by encode_fh, in which case it will have been padded with

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#7 lore raw

PATCH 1/1 kNFSd - 5 of 11 - gss_svc_module_ref.patch

In reply to NeilBrown

The server sunrpc code should take a reference on the relevant module before calling any authentication code.

Also, it looks to me like the table of authops needs some locking.

Finally, gss_svc_init wasn't checking the status of svc_auth_register, and gss_svc_shutdown wasn't calling svc_auth_unregister.

From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./include/linux/sunrpc/svcauth.h    |    1 +
 ./net/sunrpc/auth_gss/svcauth_gss.c |   12 ++++++++----
 ./net/sunrpc/svcauth.c              |   25 +++++++++++++++++++------
 ./net/sunrpc/svcauth_unix.c         |    3 +++
 4 files changed, 31 insertions(+), 10 deletions(-)
include/linux/sunrpc/svcauth.h renamed from include/linux/sunrpc/svcauth.h~current~ +1 -0
diff ./include/linux/sunrpc/svcauth.h~current~ ./include/linux/sunrpc/svcauth.h
@@ -87,6 +87,7 @@ struct auth_domain {
  */
 struct auth_ops {
 	char *	name;
+	struct module *owner;
 	int	flavour;
 	int	(*accept)(struct svc_rqst *rq, u32 *authp);
 	int	(*release)(struct svc_rqst *rq);
net/sunrpc/auth_gss/svcauth_gss.c renamed from net/sunrpc/auth_gss/svcauth_gss.c~current~ +8 -4
diff ./net/sunrpc/auth_gss/svcauth_gss.c~current~ ./net/sunrpc/auth_gss/svcauth_gss.c
@@ -1045,6 +1045,7 @@ svcauth_gss_domain_release(struct auth_d
 
 struct auth_ops svcauthops_gss = {
 	.name		= "rpcsec_gss",
+	.owner		= THIS_MODULE,
 	.flavour	= RPC_AUTH_GSS,
 	.accept		= svcauth_gss_accept,
 	.release	= svcauth_gss_release,
@@ -1054,10 +1055,12 @@ struct auth_ops svcauthops_gss = {
 int
 gss_svc_init(void)
 {
-	cache_register(&rsc_cache);
-	cache_register(&rsi_cache);
-	svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
-	return 0;
+	int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
+	if (rv == 0) {
+		cache_register(&rsc_cache);
+		cache_register(&rsi_cache);
+	}
+	return rv;
 }
 
 void
@@ -1065,4 +1068,5 @@ gss_svc_shutdown(void)
 {
 	cache_unregister(&rsc_cache);
 	cache_unregister(&rsi_cache);
+	svc_auth_unregister(RPC_AUTH_GSS);
 }
net/sunrpc/svcauth.c renamed from net/sunrpc/svcauth.c~current~ +19 -6
diff ./net/sunrpc/svcauth.c~current~ ./net/sunrpc/svcauth.c
@@ -11,6 +11,7 @@
 
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/svcsock.h>
@@ -27,6 +28,7 @@
 extern struct auth_ops svcauth_null;
 extern struct auth_ops svcauth_unix;
 
+static spinlock_t authtab_lock = SPIN_LOCK_UNLOCKED;
 static struct auth_ops	*authtab[RPC_AUTH_MAXFLAVOR] = {
 	[0] = &svcauth_null,
 	[1] = &svcauth_unix,
@@ -43,10 +45,15 @@ svc_authenticate(struct svc_rqst *rqstp,
 	flavor = ntohl(svc_getu32(&rqstp->rq_arg.head[0]));
 
 	dprintk("svc: svc_authenticate (%d)\n", flavor);
-	if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor])) {
+
+	spin_lock(&authtab_lock);
+	if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor])
+			|| !try_module_get(aops->owner)) {
+		spin_unlock(&authtab_lock);
 		*authp = rpc_autherr_badcred;
 		return SVC_DENIED;
 	}
+	spin_unlock(&authtab_lock);
 
 	rqstp->rq_authop = aops;
 	return aops->accept(rqstp, authp);
@@ -66,24 +73,30 @@ int svc_authorise(struct svc_rqst *rqstp
 	if (aops) 
 		rv = aops->release(rqstp);
 
-	/* FIXME should I count and release authops */
+	module_put(aops->owner);
 	return rv;
 }
 
 int
 svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
 {
-	if (flavor >= RPC_AUTH_MAXFLAVOR || authtab[flavor])
-		return -EINVAL;
-	authtab[flavor] = aops;
-	return 0;
+	int rv = -EINVAL;
+	spin_lock(&authtab_lock);
+	if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] != NULL) {
+		authtab[flavor] = aops;
+		rv = 0;
+	}
+	spin_unlock(&authtab_lock);
+	return rv;
 }
 
 void
 svc_auth_unregister(rpc_authflavor_t flavor)
 {
+	spin_lock(&authtab_lock);
 	if (flavor < RPC_AUTH_MAXFLAVOR)
 		authtab[flavor] = NULL;
+	spin_unlock(&authtab_lock);
 }
 
 /**************************************************
net/sunrpc/svcauth_unix.c renamed from net/sunrpc/svcauth_unix.c~current~ +3 -0
diff ./net/sunrpc/svcauth_unix.c~current~ ./net/sunrpc/svcauth_unix.c
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/svcsock.h>
@@ -411,6 +412,7 @@ svcauth_null_release(struct svc_rqst *rq
 
 struct auth_ops svcauth_null = {
 	.name		= "null",
+	.owner		= THIS_MODULE,
 	.flavour	= RPC_AUTH_NULL,
 	.accept 	= svcauth_null_accept,
 	.release	= svcauth_null_release,
@@ -515,6 +517,7 @@ svcauth_unix_release(struct svc_rqst *rq
 
 struct auth_ops svcauth_unix = {
 	.name		= "unix",
+	.owner		= THIS_MODULE,
 	.flavour	= RPC_AUTH_UNIX,
 	.accept 	= svcauth_unix_accept,
 	.release	= svcauth_unix_release,

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#8 lore raw

Re: [PATCH] kNFSd - 5 of 11 - gss_svc_module_ref.patch

Quoted 3 lines · NeilBrown

The server sunrpc code should take a reference on the relevant module before calling any authentication code.

That patch has two small but critical typos; could you also apply the following? Thanks.--Bruce Fields

Fix a null deference if svc_authorise is called twice for a request, and fix the test in svcauth_register which otherwise causes initialization of the gss module to fail.

 net/sunrpc/svcauth.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff -puN net/sunrpc/auth_gss/svcauth_gss.c~gss_svc_module_ref_fix net/sunrpc/auth_gss/svcauth_gss.c

net/sunrpc/svcauth.c renamed from net/sunrpc/svcauth.c~gss_svc_module_ref_fix +4 -4
diff -puN net/sunrpc/svcauth.c~gss_svc_module_ref_fix net/sunrpc/svcauth.c
@@ -70,10 +70,10 @@ int svc_authorise(struct svc_rqst *rqstp
 
 	rqstp->rq_authop = NULL;
 	
-	if (aops) 
+	if (aops) {
 		rv = aops->release(rqstp);
-
-	module_put(aops->owner);
+		module_put(aops->owner);
+	}
 	return rv;
 }
 
@@ -82,7 +82,7 @@ svc_auth_register(rpc_authflavor_t flavo
 {
 	int rv = -EINVAL;
 	spin_lock(&authtab_lock);
-	if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] != NULL) {
+	if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) {
 		authtab[flavor] = aops;
 		rv = 0;
 	}

_

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#9 lore raw

PATCH 1/1 kNFSd - 6 of 11 - nfsd_gss_rsc_lookup_free.patch

In reply to NeilBrown

rsc_lookup is a bit complicated: it either takes responsibility for the memory pointed to by handle.data and sets handle.data to NULL, or it leaves handle.data unchanged, in which case the caller is responsible for freeing handle.data. I forgot that the possibility of inserting a negative cache entry into the cache meant that this could happen even when rsc_lookup is called with set == 0.

Note that the ip_map code has the same bug, not that it seems to matter much, since the memory in question in that case is always just a statically allocated string.

From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./net/sunrpc/auth_gss/svcauth_gss.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)
net/sunrpc/auth_gss/svcauth_gss.c renamed from net/sunrpc/auth_gss/svcauth_gss.c~current~ +5 -1
diff ./net/sunrpc/auth_gss/svcauth_gss.c~current~ ./net/sunrpc/auth_gss/svcauth_gss.c
@@ -333,6 +333,7 @@ rsc_init(struct rsc *new, struct rsc *tm
 	new->handle.data = tmp->handle.data;
 	tmp->handle.data = NULL;
 	new->mechctx = NULL;
+	new->cred.cr_group_info = NULL;
 }
 
 static inline void
@@ -453,8 +454,11 @@ gss_svc_searchbyctx(struct xdr_netobj *h
 	struct rsc rsci;
 	struct rsc *found;
 
-	rsci.handle = *handle;
+	memset(&rsci, 0, sizeof(rsci));
+	if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
+		return NULL;
 	found = rsc_lookup(&rsci, 0);
+	rsc_free(&rsci);
 	if (!found)
 		return NULL;
 	if (cache_check(&rsc_cache, &found->h, NULL))

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#10 lore raw

PATCH 1/1 kNFSd - 4 of 11 - nfsd_xdr_name_encoding.patch

In reply to NeilBrown

Encode names directly into xdr buffer; this optimizes out a data copy, reduces stack usage, and will make life simpler when doing acls.

From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./fs/nfsd/nfs4xdr.c |   80 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 51 insertions(+), 29 deletions(-)
fs/nfsd/nfs4xdr.c renamed from fs/nfsd/nfs4xdr.c~current~ +51 -29
diff ./fs/nfsd/nfs4xdr.c~current~ ./fs/nfsd/nfs4xdr.c
@@ -1289,6 +1289,49 @@ static u32 nfs4_ftypes[16] = {
         NF4SOCK, NF4BAD,  NF4LNK, NF4BAD,
 };
 
+static inline int
+xdr_padding(int l)
+{
+       return 3 - ((l - 1) & 3); /* smallest i>=0 such that (l+i)%4 = 0 */
+}
+
+static int
+nfsd4_encode_name(struct svc_rqst *rqstp, int group, uid_t id,
+			u32 **p, int *buflen)
+{
+	int status;
+	u32 len;
+
+	if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
+		return nfserr_resource;
+	if (group)
+		status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
+	else
+		status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
+	if (status < 0)
+		return nfserrno(status);
+	len = (unsigned)status;
+	*(*p)++ = htonl(len);
+	memset((u8 *)*p + len, 0, xdr_padding(len));
+	*p += XDR_QUADLEN(len);
+	*buflen -= (XDR_QUADLEN(len) << 2) + 4;
+	BUG_ON(*buflen < 0);
+	return 0;
+}
+
+static inline int
+nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen)
+{
+	return nfsd4_encode_name(rqstp, uid, 0, p, buflen);
+}
+
+static inline int
+nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen)
+{
+	return nfsd4_encode_name(rqstp, gid, 1, p, buflen);
+}
+
+
 /*
  * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
  * ourselves.
@@ -1304,10 +1347,6 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
 	u32 bmval0 = bmval[0];
 	u32 bmval1 = bmval[1];
 	struct kstat stat;
-	char owner[IDMAP_NAMESZ];
-	u32 ownerlen = 0;
-	char group[IDMAP_NAMESZ];
-	u32 grouplen = 0;
 	struct svc_fh tempfh;
 	struct kstatfs statfs;
 	int buflen = *countp << 2;
@@ -1338,23 +1377,6 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
 			goto out;
 		fhp = &tempfh;
 	}
-	if (bmval1 & FATTR4_WORD1_OWNER) {
-		int temp = nfsd_map_uid_to_name(rqstp, stat.uid, owner);
-		if (temp < 0) {
-			status = temp;
-			goto out_nfserr;
-		}
-		ownerlen = (unsigned) temp;
-	}
-	if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
-		int temp = nfsd_map_gid_to_name(rqstp, stat.gid, group);
-		if (temp < 0) {
-			status = temp;
-			goto out_nfserr;
-		}
-		grouplen = (unsigned) temp;
-	}
-
 	if ((buflen -= 16) < 0)
 		goto out_resource;
 
@@ -1536,18 +1558,18 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
 		WRITE32(stat.nlink);
 	}
 	if (bmval1 & FATTR4_WORD1_OWNER) {
-		buflen -= (XDR_QUADLEN(ownerlen) << 2) + 4;
-		if (buflen < 0)
+		status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
+		if (status == nfserr_resource)
 			goto out_resource;
-		WRITE32(ownerlen);
-		WRITEMEM(owner, ownerlen);
+		if (status)
+			goto out;
 	}
 	if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
-		buflen -= (XDR_QUADLEN(grouplen) << 2) + 4;
-		if (buflen < 0)
+		status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
+		if (status == nfserr_resource)
 			goto out_resource;
-		WRITE32(grouplen);
-		WRITEMEM(group, grouplen);
+		if (status)
+			goto out;
 	}
 	if (bmval1 & FATTR4_WORD1_RAWDEV) {
 		if ((buflen -= 8) < 0)

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#11 lore raw

PATCH 1/1 kNFSd - 7 of 11 - nfsd-releaselkowner.patch

In reply to NeilBrown

Fix oops in release_lockowner.
We need to break out to two loops, not just one, and if the loop finds nothing, 'local' won't be NULL. So just put the body of the 'if' inside the loop.

From: Andy Adamson <[email protected]>
From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./fs/nfsd/nfs4state.c |   41 ++++++++++++++++++++---------------------
 1 files changed, 20 insertions(+), 21 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +20 -21
diff ./fs/nfsd/nfs4state.c~current~ ./fs/nfsd/nfs4state.c
@@ -2334,28 +2334,27 @@ nfsd4_release_lockowner(struct svc_rqst 
 
 	/* find the lockowner */
         status = nfs_ok;
-	for (i=0; i < LOCK_HASH_SIZE; i++) {
-		list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash) {
-			if(cmp_owner_str(local, owner, clid))
-				break;
-		}
-	}
-	if (local) {
-		struct nfs4_stateid *stp;
-
-		/* check for any locks held by any stateid associated with the
-		 * (lock) stateowner */
-		status = nfserr_locks_held;
-		list_for_each_entry(stp, &local->so_perfilestate, st_perfilestate) {
-			if(stp->st_vfs_set) {
-				if (check_for_locks(&stp->st_vfs_file, local))
-					goto out;
+	for (i=0; i < LOCK_HASH_SIZE; i++)
+		list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash)
+			if(cmp_owner_str(local, owner, clid)) {
+				struct nfs4_stateid *stp;
+
+				/* check for any locks held by any stateid 
+				 * associated with the (lock) stateowner */
+				status = nfserr_locks_held;
+				list_for_each_entry(stp, &local->so_perfilestate,
+						    st_perfilestate) {
+					if(stp->st_vfs_set) {
+						if (check_for_locks(&stp->st_vfs_file,
+								    local))
+							goto out;
+					}
+				}
+				/* no locks held by (lock) stateowner */
+				status = nfs_ok;
+				release_stateowner(local);
+				goto out;
 			}
-		}
-		/* no locks held by (lock) stateowner */
-		status = nfs_ok;
-		release_stateowner(local);
-	}
 out:
 	nfs4_unlock_state();
 	return status;

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

author
#12 lore raw

PATCH 1/1 kNFSd - 3 of 11 - nfsd_acceptable_typo.patch

In reply to NeilBrown

there's a small typo in nfsd_acceptable. It calls

	err = permission(parent->d_inode, S_IXOTH, NULL);

It really wants to use MAY_EXEC instead of S_IXOTH. Those happen to be the same at the moment, but may not do so forever.

From: Olaf Kirch <[email protected]>:
From: "J. Bruce Fields" <[email protected]>

----------- Diffstat output ------------

 ./fs/nfsd/nfsfh.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfsfh.c renamed from fs/nfsd/nfsfh.c~current~ +1 -1
diff ./fs/nfsd/nfsfh.c~current~ ./fs/nfsd/nfsfh.c
@@ -56,7 +56,7 @@ int nfsd_acceptable(void *expv, struct d
 		/* make sure parents give x permission to user */
 		int err;
 		parent = dget_parent(tdentry);
-		err = permission(parent->d_inode, S_IXOTH, NULL);
+		err = permission(parent->d_inode, MAY_EXEC, NULL);
 		if (err < 0) {
 			dput(parent);
 			break;

-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs