Module Name:    src
Committed By:   pho
Date:           Sat Jan 22 07:35:26 UTC 2022

Modified Files:
        src/lib/libpuffs: Makefile puffs.3 puffs.c puffs_priv.h

Log Message:
Allow calling puffs_mount(3) before puffs_daemon(3)

puffs_daemon(3) creates a pipe before forking, and the parent process
waits for the child to either complete puffs_mount(3) or fail. If a
user calls puffs_daemon(3) after puffs_mount(3), the function
deadlocks. While this error-reporting functionality is really a nice
thing to have, deadlocking is not great. If the filesystem has already
been mounted, puffs_mount(3) should just daemonize the process and
return.

This became an issue because fuse_daemonize(3) in FUSE API had no such
requirement and some FUSE filesystems in the wild suffered deadlocks.


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/lib/libpuffs/Makefile
cvs rdiff -u -r1.66 -r1.67 src/lib/libpuffs/puffs.3
cvs rdiff -u -r1.127 -r1.128 src/lib/libpuffs/puffs.c
cvs rdiff -u -r1.45 -r1.46 src/lib/libpuffs/puffs_priv.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libpuffs/Makefile
diff -u src/lib/libpuffs/Makefile:1.26 src/lib/libpuffs/Makefile:1.27
--- src/lib/libpuffs/Makefile:1.26	Sat Jan 23 21:22:46 2016
+++ src/lib/libpuffs/Makefile	Sat Jan 22 07:35:26 2022
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.26 2016/01/23 21:22:46 christos Exp $
+#	$NetBSD: Makefile,v 1.27 2022/01/22 07:35:26 pho Exp $
 #
 
 .include <bsd.own.mk>
@@ -16,7 +16,6 @@ MAN=		puffs.3 puffs_cc.3 puffs_cred.3 pu
 		puffs_framebuf.3 puffs_node.3 puffs_ops.3 puffs_path.3
 INCS=		puffs.h puffsdump.h
 INCSDIR=	/usr/include
-CPPFLAGS+=	-D_KERNTYPES
 LINTFLAGS+=-S -w
 
 .include <bsd.lib.mk>

Index: src/lib/libpuffs/puffs.3
diff -u src/lib/libpuffs/puffs.3:1.66 src/lib/libpuffs/puffs.3:1.67
--- src/lib/libpuffs/puffs.3:1.66	Fri Dec  3 17:12:17 2021
+++ src/lib/libpuffs/puffs.3	Sat Jan 22 07:35:26 2022
@@ -1,4 +1,4 @@
-.\"	$NetBSD: puffs.3,v 1.66 2021/12/03 17:12:17 pho Exp $
+.\"	$NetBSD: puffs.3,v 1.67 2022/01/22 07:35:26 pho Exp $
 .\"
 .\" Copyright (c) 2006, 2007, 2008 Antti Kantee.  All rights reserved.
 .\"
@@ -455,11 +455,13 @@ is called
 .It Fn puffs_daemon pu nochdir noclose
 Detach from the console like
 .Fn daemon 3 .
-This call synchronizes with
+If it is called before
+.Fn puffs_mount ,
+this call synchronizes with
 .Fn puffs_mount
 and the foreground process does not exit before the file system mount
 call has returned from the kernel.
-Since this routine internally calls fork, it has to be called
+Since this routine internally calls fork, it is highly recommended to call it
 .Em before
 .Fn puffs_mount .
 .It Fn puffs_mainloop pu flags

Index: src/lib/libpuffs/puffs.c
diff -u src/lib/libpuffs/puffs.c:1.127 src/lib/libpuffs/puffs.c:1.128
--- src/lib/libpuffs/puffs.c:1.127	Fri Dec  3 17:12:17 2021
+++ src/lib/libpuffs/puffs.c	Sat Jan 22 07:35:26 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs.c,v 1.127 2021/12/03 17:12:17 pho Exp $	*/
+/*	$NetBSD: puffs.c,v 1.128 2022/01/22 07:35:26 pho Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #if !defined(lint)
-__RCSID("$NetBSD: puffs.c,v 1.127 2021/12/03 17:12:17 pho Exp $");
+__RCSID("$NetBSD: puffs.c,v 1.128 2022/01/22 07:35:26 pho Exp $");
 #endif /* !lint */
 
 #include <sys/param.h>
@@ -440,9 +440,12 @@ puffs_daemon(struct puffs_usermount *pu,
 {
 	long int n;
 	int parent, value, fd;
+	bool is_beforemount;
 
-	if (pipe(pu->pu_dpipe) == -1)
-		return -1;
+	is_beforemount = (puffs_getstate(pu) < PUFFS_STATE_RUNNING);
+	if (is_beforemount)
+		if (pipe(pu->pu_dpipe) == -1)
+			return -1;
 
 	switch (fork()) {
 	case -1:
@@ -454,18 +457,21 @@ puffs_daemon(struct puffs_usermount *pu,
 		parent = 1;
 		break;
 	}
-	pu->pu_state |= PU_PUFFSDAEMON;
+	if (is_beforemount)
+		PU_SETSFLAG(pu, PU_PUFFSDAEMON);
 
 	if (parent) {
-		close(pu->pu_dpipe[1]);
-		n = read(pu->pu_dpipe[0], &value, sizeof(int));
-		if (n == -1)
-			err(1, "puffs_daemon");
-		if (n != sizeof(value))
-			errx(1, "puffs_daemon got %ld bytes", n);
-		if (value) {
-			errno = value;
-			err(1, "puffs_daemon");
+		if (is_beforemount) {
+			close(pu->pu_dpipe[1]);
+			n = read(pu->pu_dpipe[0], &value, sizeof(int));
+			if (n == -1)
+				err(1, "puffs_daemon");
+			if (n != sizeof(value))
+				errx(1, "puffs_daemon got %ld bytes", n);
+			if (value) {
+				errno = value;
+				err(1, "puffs_daemon");
+			}
 		}
 		exit(0);
 	} else {
@@ -489,8 +495,10 @@ puffs_daemon(struct puffs_usermount *pu,
 	}
 
  fail:
-	n = write(pu->pu_dpipe[1], &errno, sizeof(int));
-	assert(n == 4);
+	if (is_beforemount) {
+		n = write(pu->pu_dpipe[1], &errno, sizeof(int));
+		assert(n == 4);
+	}
 	return -1;
 }
 
@@ -614,7 +622,7 @@ do {									\
 	free(pu->pu_kargp);
 	pu->pu_kargp = NULL;
 
-	if (pu->pu_state & PU_PUFFSDAEMON)
+	if (PU_GETSFLAG(pu, PU_PUFFSDAEMON))
 		shutdaemon(pu, sverrno);
 
 	errno = sverrno;
@@ -706,8 +714,8 @@ puffs_init(struct puffs_ops *pops, const
 void
 puffs_cancel(struct puffs_usermount *pu, int error)
 {
-
 	assert(puffs_getstate(pu) < PUFFS_STATE_RUNNING);
+	assert(PU_GETSFLAG(pu, PU_PUFFSDAEMON));
 	shutdaemon(pu, error);
 	free(pu);
 }

Index: src/lib/libpuffs/puffs_priv.h
diff -u src/lib/libpuffs/puffs_priv.h:1.45 src/lib/libpuffs/puffs_priv.h:1.46
--- src/lib/libpuffs/puffs_priv.h:1.45	Wed Apr 18 00:57:22 2012
+++ src/lib/libpuffs/puffs_priv.h	Sat Jan 22 07:35:26 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_priv.h,v 1.45 2012/04/18 00:57:22 manu Exp $	*/
+/*	$NetBSD: puffs_priv.h,v 1.46 2022/01/22 07:35:26 pho Exp $	*/
 
 /*
  * Copyright (c) 2006, 2007, 2008 Antti Kantee.  All Rights Reserved.
@@ -113,6 +113,7 @@ struct puffs_usermount {
 #define PU_DONEXIT	0x2000
 #define PU_SETSTATE(pu, s) (pu->pu_state = (s) | (pu->pu_state & ~PU_STATEMASK))
 #define PU_SETSFLAG(pu, s) (pu->pu_state |= (s))
+#define PU_GETSFLAG(pu, s) (pu->pu_state & (s))
 #define PU_CLRSFLAG(pu, s) \
     (pu->pu_state = ((pu->pu_state & ~(s)) | (pu->pu_state & PU_STATEMASK)))
 	int			pu_dpipe[2];

Reply via email to