
From: Andreas Gruenbacher <agruen@suse.de>

Set umask correctly for nfsd kernel threads

This fixes bug #721, <http://www.osdl.net/show_bug.cgi?id=721>.



 25-akpm/fs/nfsd/nfssvc.c |   15 +++++++++++++++
 25-akpm/kernel/ksyms.c   |    3 +++
 2 files changed, 18 insertions(+)

diff -puN fs/nfsd/nfssvc.c~knfsd-umask-fix fs/nfsd/nfssvc.c
--- 25/fs/nfsd/nfssvc.c~knfsd-umask-fix	Mon Jul  7 14:06:26 2003
+++ 25-akpm/fs/nfsd/nfssvc.c	Mon Jul  7 14:06:26 2003
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/fs_struct.h>
 
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/stats.h>
@@ -168,6 +169,7 @@ static void
 nfsd(struct svc_rqst *rqstp)
 {
 	struct svc_serv	*serv = rqstp->rq_server;
+	struct fs_struct *fsp;
 	int		err;
 	struct nfsd_list me;
 	sigset_t shutdown_mask, allowed_mask;
@@ -178,6 +180,18 @@ nfsd(struct svc_rqst *rqstp)
 	daemonize("nfsd");
 	current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 
+	/* After daemonize() this kernel thread shares current->fs
+	 * with the init process. We need to create files with a
+	 * umask of 0 instead of init's umask. */
+	fsp = copy_fs_struct(current->fs);
+	if (!fsp) {
+		printk("Unable to start nfsd thread: out of memory\n");
+		goto out;
+	}
+	exit_fs(current);
+	current->fs = fsp;
+	current->fs->umask = 0;
+
 	siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS);
 	siginitsetinv(&allowed_mask, ALLOWED_SIGS);
 
@@ -262,6 +276,7 @@ nfsd(struct svc_rqst *rqstp)
 	list_del(&me.list);
 	nfsdstats.th_cnt --;
 
+out:
 	/* Release the thread */
 	svc_exit_thread(rqstp);
 
diff -puN kernel/ksyms.c~knfsd-umask-fix kernel/ksyms.c
--- 25/kernel/ksyms.c~knfsd-umask-fix	Mon Jul  7 14:06:26 2003
+++ 25-akpm/kernel/ksyms.c	Mon Jul  7 14:06:26 2003
@@ -41,6 +41,7 @@
 #include <linux/capability.h>
 #include <linux/highuid.h>
 #include <linux/fs.h>
+#include <linux/fs_struct.h>
 #include <linux/uio.h>
 #include <linux/tty.h>
 #include <linux/in6.h>
@@ -76,6 +77,8 @@ EXPORT_SYMBOL(do_mmap_pgoff);
 EXPORT_SYMBOL(do_munmap);
 EXPORT_SYMBOL(do_brk);
 EXPORT_SYMBOL(exit_mm);
+EXPORT_SYMBOL_GPL(exit_fs);
+EXPORT_SYMBOL_GPL(copy_fs_struct);
 
 /* internal kernel memory management */
 EXPORT_SYMBOL(__alloc_pages);

_
