1
0
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:
Alexander Motin 2019-11-21 21:59:35 +00:00
parent 5d9861c835
commit 130fffa2a3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=354986
2 changed files with 49 additions and 16 deletions

View File

@ -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");
}

View File

@ -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);