fix for named pipes over NFS

Ion Badulescu (ionut@moisil.cs.columbia.edu)
Mon, 7 Sep 1998 16:35:31 -0400 (EDT)


Hi Linus,

The patch below, which appeared briefly in 2.1.117 and was backed out in
2.1.118, allows the linux NFS client to handle named pipes residing on
non-linux NFSv2 servers. It has no other impact, and has been tested here
against a linux unfsd server and a solaris 2.5.1 server.

Details: the NFSv2 protocol has no provisions for handling named pipes,
and therefore they are encoded as character devices with major/minor = -1.
Linux uses a non-standard extention of the protocol, which is incompatible
with other servers - already existing pipes will appear as character
devices, and trying to create new ones will result in plain files. The
patch corrects this behavior, and also avoids breaking unfsd (which uses
the same non-standard extention) by retrying the operation in the old
style if the new style fails.

Thanks,
Ion

-- 
  It is better to keep your mouth shut and be thought a fool,
            than to open it and remove all doubt.
-------------------
--- v2.1.120/linux/fs/nfs/dir.c	Wed Jun 24 22:54:09 1998
+++ linux/fs/nfs/dir.c	Wed Aug 19 16:16:04 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 +703,10 @@
 	if (dentry->d_name.len > NFS_MAXNAMLEN)
 		return -ENAMETOOLONG;
 
-	sattr.mode = mode;
+	if (S_ISFIFO(mode))
+		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 +715,15 @@
 	nfs_invalidate_dircache(dir);
 	error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent),
 				dentry->d_name.name, &sattr, &fhandle, &fattr);
+	/*
+	 *	Retry invalid FIFO creates as the original object
+	 *	to cover for NFS servers that don't cope.
+	 */
+	if (error == -EINVAL && S_ISFIFO(mode)) {
+		sattr.mode = mode;
+		error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent),
+					dentry->d_name.name, &sattr, &fhandle, &fattr);
+	}
 	if (!error)
 		error = nfs_instantiate(dentry, &fhandle, &fattr);
 	if (error)
diff -u --recursive --new-file v2.1.120/linux/fs/nfs/mount_clnt.c linux/fs/nfs/mount_clnt.c
--- v2.1.120/linux/fs/nfs/nfs2xdr.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/nfs/nfs2xdr.c	Wed Aug 19 16:16: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.tux.org/lkml/faq.html