mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-18 15:30:21 +00:00
Add variant of root_mount_hold() without allocation.
It allows to use this KPI in non-sleepable contexts. MFC after: 2 weeks Sponsored by: iXsystems, Inc.
This commit is contained in:
parent
5d9861c835
commit
130fffa2a3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=354986
@ -111,13 +111,8 @@ char *rootdevnames[2] = {NULL, NULL};
|
||||
struct mtx root_holds_mtx;
|
||||
MTX_SYSINIT(root_holds, &root_holds_mtx, "root_holds", MTX_DEF);
|
||||
|
||||
struct root_hold_token {
|
||||
const char *who;
|
||||
LIST_ENTRY(root_hold_token) list;
|
||||
};
|
||||
|
||||
static LIST_HEAD(, root_hold_token) root_holds =
|
||||
LIST_HEAD_INITIALIZER(root_holds);
|
||||
static TAILQ_HEAD(, root_hold_token) root_holds =
|
||||
TAILQ_HEAD_INITIALIZER(root_holds);
|
||||
|
||||
enum action {
|
||||
A_CONTINUE,
|
||||
@ -126,6 +121,12 @@ enum action {
|
||||
A_RETRY
|
||||
};
|
||||
|
||||
enum rh_flags {
|
||||
RH_FREE,
|
||||
RH_ALLOC,
|
||||
RH_ARG,
|
||||
};
|
||||
|
||||
static enum action root_mount_onfail = A_CONTINUE;
|
||||
|
||||
static int root_mount_mddev;
|
||||
@ -155,8 +156,8 @@ sysctl_vfs_root_mount_hold(SYSCTL_HANDLER_ARGS)
|
||||
sbuf_new(&sb, NULL, 256, SBUF_AUTOEXTEND | SBUF_INCLUDENUL);
|
||||
|
||||
mtx_lock(&root_holds_mtx);
|
||||
LIST_FOREACH(h, &root_holds, list) {
|
||||
if (h != LIST_FIRST(&root_holds))
|
||||
TAILQ_FOREACH(h, &root_holds, list) {
|
||||
if (h != TAILQ_FIRST(&root_holds))
|
||||
sbuf_putc(&sb, ' ');
|
||||
sbuf_printf(&sb, "%s", h->who);
|
||||
}
|
||||
@ -175,27 +176,54 @@ root_mount_hold(const char *identifier)
|
||||
struct root_hold_token *h;
|
||||
|
||||
h = malloc(sizeof *h, M_DEVBUF, M_ZERO | M_WAITOK);
|
||||
h->flags = RH_ALLOC;
|
||||
h->who = identifier;
|
||||
mtx_lock(&root_holds_mtx);
|
||||
TSHOLD("root mount");
|
||||
LIST_INSERT_HEAD(&root_holds, h, list);
|
||||
TAILQ_INSERT_TAIL(&root_holds, h, list);
|
||||
mtx_unlock(&root_holds_mtx);
|
||||
return (h);
|
||||
}
|
||||
|
||||
void
|
||||
root_mount_hold_token(const char *identifier, struct root_hold_token *h)
|
||||
{
|
||||
#ifdef INVARIANTS
|
||||
struct root_hold_token *t;
|
||||
#endif
|
||||
|
||||
h->flags = RH_ARG;
|
||||
h->who = identifier;
|
||||
mtx_lock(&root_holds_mtx);
|
||||
#ifdef INVARIANTS
|
||||
TAILQ_FOREACH(t, &root_holds, list) {
|
||||
if (t == h) {
|
||||
panic("Duplicate mount hold by '%s' on %p",
|
||||
identifier, h);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
TSHOLD("root mount");
|
||||
TAILQ_INSERT_TAIL(&root_holds, h, list);
|
||||
mtx_unlock(&root_holds_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
root_mount_rel(struct root_hold_token *h)
|
||||
{
|
||||
|
||||
if (h == NULL)
|
||||
if (h == NULL || h->flags == RH_FREE)
|
||||
return;
|
||||
|
||||
mtx_lock(&root_holds_mtx);
|
||||
LIST_REMOVE(h, list);
|
||||
TAILQ_REMOVE(&root_holds, h, list);
|
||||
TSRELEASE("root mount");
|
||||
wakeup(&root_holds);
|
||||
mtx_unlock(&root_holds_mtx);
|
||||
if (h->flags == RH_ALLOC) {
|
||||
free(h, M_DEVBUF);
|
||||
} else
|
||||
h->flags = RH_FREE;
|
||||
}
|
||||
|
||||
int
|
||||
@ -964,13 +992,13 @@ vfs_mountroot_wait(void)
|
||||
while (1) {
|
||||
g_waitidle();
|
||||
mtx_lock(&root_holds_mtx);
|
||||
if (LIST_EMPTY(&root_holds)) {
|
||||
if (TAILQ_EMPTY(&root_holds)) {
|
||||
mtx_unlock(&root_holds_mtx);
|
||||
break;
|
||||
}
|
||||
if (ppsratecheck(&lastfail, &curfail, 1)) {
|
||||
printf("Root mount waiting for:");
|
||||
LIST_FOREACH(h, &root_holds, list)
|
||||
TAILQ_FOREACH(h, &root_holds, list)
|
||||
printf(" %s", h->who);
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -536,9 +536,14 @@ int poll_no_poll(int events);
|
||||
void DELAY(int usec);
|
||||
|
||||
/* Root mount holdback API */
|
||||
struct root_hold_token;
|
||||
struct root_hold_token {
|
||||
int flags;
|
||||
const char *who;
|
||||
TAILQ_ENTRY(root_hold_token) list;
|
||||
};
|
||||
|
||||
struct root_hold_token *root_mount_hold(const char *identifier);
|
||||
void root_mount_hold_token(const char *identifier, struct root_hold_token *h);
|
||||
void root_mount_rel(struct root_hold_token *h);
|
||||
int root_mounted(void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user