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];