Subject: S_IFREG support to mknod(2)
To: None <tech-kern@netbsd.org>
From: Antti Kantee <pooka@cs.hut.fi>
List: tech-kern
Date: 02/16/2007 01:19:04
Heya,

Some FUSE file systems use mknod(2) to implement the counterpart
of VOP_CREATE.  The mknod(2) on Linux can take S_IFREG or'd to mode
for creating regular files.  This is also explicitly noted as allowed
non-portable behaviour by SUS.  And e.g. Solaris supports this also.

The following adds the same functionality to our sys_mknod().
Any opposed?

  - antti

p.s. by reading this email you agree to provide a better solution to
the problem if you are opposed

Index: vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.299
diff -u -r1.299 vfs_syscalls.c
--- vfs_syscalls.c	4 Feb 2007 20:33:02 -0000	1.299
+++ vfs_syscalls.c	15 Feb 2007 23:06:24 -0000
@@ -1758,8 +1758,7 @@
 	struct vnode *vp;
 	struct mount *mp;
 	struct vattr vattr;
-	int error;
-	int whiteout = 0;
+	int error, optype;
 	struct nameidata nd;
 
 	if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MKNOD,
@@ -1777,7 +1776,7 @@
 		vattr.va_mode =
 		    (SCARG(uap, mode) & ALLPERMS) &~ p->p_cwdi->cwdi_cmask;
 		vattr.va_rdev = SCARG(uap, dev);
-		whiteout = 0;
+		optype = VOP_MKNOD_DESCOFFSET;
 
 		switch (SCARG(uap, mode) & S_IFMT) {
 		case S_IFMT:	/* used by badsect to flag bad sectors */
@@ -1790,7 +1789,12 @@
 			vattr.va_type = VBLK;
 			break;
 		case S_IFWHT:
-			whiteout = 1;
+			optype = VOP_WHITEOUT_DESCOFFSET;
+			break;
+		case S_IFREG:
+			vattr.va_type = VREG;
+			vattr.va_rdev = 0;
+			optype = VOP_CREATE_DESCOFFSET;
 			break;
 		default:
 			error = EINVAL;
@@ -1812,16 +1816,27 @@
 	}
 	if (!error) {
 		VOP_LEASE(nd.ni_dvp, l, l->l_cred, LEASE_WRITE);
-		if (whiteout) {
+		switch (optype) {
+		case VOP_WHITEOUT_DESCOFFSET:
 			error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
 			if (error)
 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 			vput(nd.ni_dvp);
-		} else {
+			break;
+
+		case VOP_MKNOD_DESCOFFSET:
 			error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
 						&nd.ni_cnd, &vattr);
 			if (error == 0)
 				vput(nd.ni_vp);
+			break;
+
+		case VOP_CREATE_DESCOFFSET:
+			error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp,
+						&nd.ni_cnd, &vattr);
+			if (error == 0)
+				vput(nd.ni_vp);
+			break;
 		}
 	} else {
 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);

-- 
Antti Kantee <pooka@iki.fi>                     Of course he runs NetBSD
http://www.iki.fi/pooka/                          http://www.NetBSD.org/
    "la qualité la plus indispensable du cuisinier est l'exactitude"