Re: small NFS problem

Ion Badulescu (ionut@moisil.cs.columbia.edu)
Tue, 4 Aug 1998 10:20:34 -0400


On Mon, 03 Aug 1998 04:07:53 EDT, David Howells wrote:
>
> I've come across a small NFS inconsistency - We have here a Solaris box NFS
> exporting a filesystem, upon which exists a pipe special file. When this is
> mounted on another Solaris/Hpux/Sco box, this appears as a pipe special file,
> but on my box running Linux 2.1.108, this appears as a character device
> special file, with major/minor numbers of 255/255.
>
> I tried to see if this happens on 2.1.112, but this hung just about the time
> init should have been started.

Yes, it happens in all the kernels, 2.0.x included.

Here are two patches, one for 2.1.114 and one for 2.0.36. The 2.0 patch was
tested against a Solaris 2.5.1 box and a Linux 2.1 box w/ unfsd, the 2.1 patch
is untested (b/c 2.1.114-vanilla is unusable on my box, it hangs amd) but very
similar.

The code in mknod really bends backwards to avoid breaking unfsd which -
unsurprisingly - is fine with the old code and rejects the new one. Oh, the
wonders of NFS... In any case, unfsd (knfsd seems fine at a first look over
the code) needs to be fixed as well. If I have some time this evening I might
give it a try.

Alan, it's up to you whether to include the 2.0 patch into 2.0.36pre. The 2.1
bug was I believe on your showstopper list -- let's hope we can remove it. :)

Thanks,
Ion

-- 
  It is better to keep your mouth shut and be thought a fool,
            than to open it and remove all doubt.
---------------------------
--- linux-2.0.35/fs/nfs/proc.c.bak	Mon Apr  6 16:47:21 1998
+++ linux-2.0.35/fs/nfs/proc.c	Tue Aug  4 10:02:23 1998
@@ -24,6 +24,11 @@
  */
 
 /*
+ * Fixes:
+ *    Ion Badulescu <ionut@cs.columbia.edu>     : FIFO's need special handling in NFSv2
+ */
+
+/*
  * Defining NFS_PROC_DEBUG causes a lookup of a file named
  * "xyzzy" to toggle debugging.  Just cd to an NFS-mounted
  * filesystem and type 'ls xyzzy' to turn on debugging.
@@ -180,6 +185,11 @@
 	fattr->mtime.useconds = ntohl(*p++);
 	fattr->ctime.seconds = ntohl(*p++);
 	fattr->ctime.useconds = ntohl(*p++);
+	if (fattr->type == NFCHR && fattr->rdev == NFS_FIFO_DEV) {
+		fattr->type = NFFIFO;
+		fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
+		fattr->rdev = 0;
+	}
 	return p;
 }
 
--- linux-2.0.35/fs/nfs/dir.c.bak	Tue Jun 30 23:35:34 1998
+++ linux-2.0.35/fs/nfs/dir.c	Tue Aug  4 10:05:23 1998
@@ -8,6 +8,11 @@
  * 10 Apr 1996	Added silly rename for unlink	--okir
  */
 
+/*
+ * Fixes:
+ *    Ion Badulescu <ionut@cs.columbia.edu>     : FIFO's need special handling in NFSv2
+ */
+
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
@@ -443,7 +448,10 @@
 		iput(dir);
 		return -ENAMETOOLONG;
 	}
-	sattr.mode = mode;
+	if (mode & S_IFIFO)
+		sattr.mode = (mode & ~S_IFMT) | S_IFCHR;
+	else
+		sattr.mode = mode;
 	sattr.uid = sattr.gid = (unsigned) -1;
 	if (S_ISCHR(mode) || S_ISBLK(mode))
 		sattr.size = rdev; /* get out your barf bag */
@@ -452,6 +460,11 @@
 	sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
 	error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
 		name, &sattr, &fhandle, &fattr);
+	if (error == -EINVAL && (mode & S_IFIFO)) {
+		sattr.mode = mode;
+		error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
+					name, &sattr, &fhandle, &fattr);
+	}
 	if (!error)
 	{
 		nfs_lookup_cache_add(dir, name, &fhandle, &fattr);

------------------------------------- --- linux-2.1.114/fs/nfs/dir.c.bak Wed Jun 24 17:30:10 1998 +++ linux-2.1.114/fs/nfs/dir.c Tue Aug 4 10:10:14 1998 @@ -14,6 +14,8 @@ * Following Linus comments on my original hack, this version * depends only on the dcache stuff and doesn't touch the inode * layer (iput() and friends). + * 04 Aug 1998 Ion Badulescu <ionut@cs.columbia.edu> + * FIFO's need special handling in NFSv2 */ #include <linux/sched.h> @@ -684,7 +686,10 @@ if (dentry->d_name.len > NFS_MAXNAMLEN) return -ENAMETOOLONG; - sattr.mode = mode; + if (mode & S_IFIFO) + sattr.mode = (mode & ~S_IFMT) | S_IFCHR; + else + sattr.mode = mode; sattr.uid = sattr.gid = sattr.size = (unsigned) -1; if (S_ISCHR(mode) || S_ISBLK(mode)) sattr.size = rdev; /* get out your barf bag */ @@ -693,6 +698,11 @@ nfs_invalidate_dircache(dir); error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent), dentry->d_name.name, &sattr, &fhandle, &fattr); + if (error == -EINVAL && (mode & S_IFIFO)) { + sattr.mode = mode; + error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), + name, &sattr, &fhandle, &fattr); + } if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); if (error) --- linux-2.1.114/fs/nfs/nfs2xdr.c.bak Tue Mar 10 16:26:56 1998 +++ linux-2.1.114/fs/nfs/nfs2xdr.c Tue Aug 4 10:19:04 1998 @@ -5,6 +5,9 @@ * * Copyright (C) 1992, 1993, 1994 Rick Sladkey * Copyright (C) 1996 Olaf Kirch + * + * 04 Aug 1998 Ion Badulescu <ionut@cs.columbia.edu> + * FIFO's need special handling in NFSv2 */ #define NFS_NEED_XDR_TYPES @@ -114,6 +117,11 @@ fattr->mtime.useconds = ntohl(*p++); fattr->ctime.seconds = ntohl(*p++); fattr->ctime.useconds = ntohl(*p++); + if (fattr->type == NFCHR && fattr->rdev == NFS_FIFO_DEV) { + fattr->type = NFFIFO; + fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO; + fattr->rdev = 0; + } return p; }

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html