Author: mav
Date: Tue Dec  3 17:06:48 2019
New Revision: 355342
URL: https://svnweb.freebsd.org/changeset/base/355342

Log:
  MFC r354986: Add variant of root_mount_hold() without allocation.
  
  It allows to use this KPI in non-sleepable contexts.

Modified:
  stable/12/sys/kern/vfs_mountroot.c
  stable/12/sys/sys/systm.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/kern/vfs_mountroot.c
==============================================================================
--- stable/12/sys/kern/vfs_mountroot.c  Tue Dec  3 16:52:39 2019        
(r355341)
+++ stable/12/sys/kern/vfs_mountroot.c  Tue Dec  3 17:06:48 2019        
(r355342)
@@ -110,14 +110,9 @@ 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 TAILQ_HEAD(, root_hold_token)   root_holds =
+    TAILQ_HEAD_INITIALIZER(root_holds);
 
-static LIST_HEAD(, root_hold_token)    root_holds =
-    LIST_HEAD_INITIALIZER(root_holds);
-
 enum action {
        A_CONTINUE,
        A_PANIC,
@@ -125,6 +120,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;
@@ -154,8 +155,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);
        }
@@ -174,27 +175,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);
-       free(h, M_DEVBUF);
+       if (h->flags == RH_ALLOC) {
+               free(h, M_DEVBUF);
+       } else
+               h->flags = RH_FREE;
 }
 
 int
@@ -961,13 +989,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");
                }

Modified: stable/12/sys/sys/systm.h
==============================================================================
--- stable/12/sys/sys/systm.h   Tue Dec  3 16:52:39 2019        (r355341)
+++ stable/12/sys/sys/systm.h   Tue Dec  3 17:06:48 2019        (r355342)
@@ -503,9 +503,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);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to