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.
This commit is contained in:
parent
f6ce8c39be
commit
0585557a98
|
@ -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 puffs_flush.3 \
|
|||
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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, int nochdir, int noclose)
|
|||
{
|
||||
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, int nochdir, int noclose)
|
|||
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, int nochdir, int noclose)
|
|||
}
|
||||
|
||||
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 char *mntfromname,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue