Re: NFS-ACL broken in 2.6.15/2.6.15.1

Andreas Gruenbacher <[email protected]> Thu, 19 Jan 2006 21:40:44 +0100
Newsgroups gmane.linux.file-systems.acl.devel
Organization SUSE LINUX Products GMBH
Message-ID <[email protected]>
--Boundary-00=_Ml/zD49IYN06ulw
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Wednesday 18 January 2006 23:08, Sven Geggus wrote:
> Hi there,
>
> updating our NFS Server to Kernel 2.6.15.1 from 2.6.14.6 completely broke
> NFS ACLs for NFS Version 3.

The attached patch fixes it.

Regards,
Andreas.

--Boundary-00=_Ml/zD49IYN06ulw
Content-Type: text/x-diff;
  charset="iso-8859-1";
  name="repair-nfsacl.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="repair-nfsacl.diff"

From: Andreas Gruenbacher <[email protected]>
Subject: Reenable nfsacl

This commit broke nfsacl by removing it from the the .pg_next list, and
by not setting up the nfsd_acl_program.pg_vers array in the same way as
nfsd_program.pg_vers is being set up.

> From: NeilBrown <[email protected]>
> Subject: [PATCH] knfsd: Allow run-time selection of NFS versions to export
> X-Git-Tag: v2.6.15-rc1
> X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=70c3b76c28b012452d63bb27f6d0517afb05d86f
> 
> [PATCH] knfsd: Allow run-time selection of NFS versions to export
> 
> Provide a file in the NFSD filesystem that allows setting and querying of
> which version of NFS are being exported.  Changes are only allowed while no
> server is running.

Signed-off-by: Andreas Gruenbacher <[email protected]>

Index: linux-2.6.15.orig/fs/nfsd/nfssvc.c
===================================================================
--- linux-2.6.15.orig.orig/fs/nfsd/nfssvc.c
+++ linux-2.6.15.orig/fs/nfsd/nfssvc.c
@@ -64,6 +64,32 @@ struct nfsd_list {
 };
 static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+static struct svc_stat	nfsd_acl_svcstats;
+static struct svc_version *	nfsd_acl_version[] = {
+	[2] = &nfsd_acl_version2,
+	[3] = &nfsd_acl_version3,
+};
+
+#define NFSD_ACL_MINVERS            2
+#define NFSD_ACL_NRVERS		(sizeof(nfsd_acl_version)/sizeof(nfsd_acl_version[0]))
+static struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS];
+
+static struct svc_program	nfsd_acl_program = {
+	.pg_prog		= NFS_ACL_PROGRAM,
+	.pg_nvers		= NFSD_ACL_NRVERS,
+	.pg_vers		= nfsd_acl_versions,
+	.pg_name		= "nfsd",
+	.pg_class		= "nfsd",
+	.pg_stats		= &nfsd_acl_svcstats,
+	.pg_authenticate	= &svc_set_client,
+};
+
+static struct svc_stat	nfsd_acl_svcstats = {
+	.program	= &nfsd_acl_program,
+};
+#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
+
 static struct svc_version *	nfsd_version[] = {
 	[2] = &nfsd_version2,
 #if defined(CONFIG_NFSD_V3)
@@ -79,6 +105,9 @@ static struct svc_version *	nfsd_version
 static struct svc_version *nfsd_versions[NFSD_NRVERS];
 
 struct svc_program		nfsd_program = {
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+	.pg_next		= &nfsd_acl_program,
+#endif
 	.pg_prog		= NFS_PROGRAM,		/* program number */
 	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
 	.pg_vers		= nfsd_versions,	/* version table */
@@ -147,6 +176,23 @@ nfsd_svc(unsigned short port, int nrserv
 				nfsd_program.pg_vers[i] = nfsd_version[i];
 		}
 
+		found_one = 0;
+
+		for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
+			if (NFSCTL_VERISSET(nfsd_versbits, i)) {
+				nfsd_acl_program.pg_vers[i] =
+					nfsd_acl_version[i];
+				found_one = 1;
+			} else
+				nfsd_acl_program.pg_vers[i] = NULL;
+		}
+
+		if (!found_one) {
+			for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
+				nfsd_acl_program.pg_vers[i] =
+					nfsd_acl_version[i];
+		}
+
 		atomic_set(&nfsd_busy, 0);
 		error = -ENOMEM;
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
@@ -411,30 +457,3 @@ nfsd_dispatch(struct svc_rqst *rqstp, u3
 	nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
 	return 1;
 }
-
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
-static struct svc_stat	nfsd_acl_svcstats;
-static struct svc_version *	nfsd_acl_version[] = {
-	[2] = &nfsd_acl_version2,
-	[3] = &nfsd_acl_version3,
-};
-
-#define NFSD_ACL_NRVERS		(sizeof(nfsd_acl_version)/sizeof(nfsd_acl_version[0]))
-static struct svc_program	nfsd_acl_program = {
-	.pg_prog		= NFS_ACL_PROGRAM,
-	.pg_nvers		= NFSD_ACL_NRVERS,
-	.pg_vers		= nfsd_acl_version,
-	.pg_name		= "nfsd",
-	.pg_class		= "nfsd",
-	.pg_stats		= &nfsd_acl_svcstats,
-	.pg_authenticate	= &svc_set_client,
-};
-
-static struct svc_stat	nfsd_acl_svcstats = {
-	.program	= &nfsd_acl_program,
-};