devtmpfs: refactor devtmpfsd()
authorChristoph Hellwig <hch@lst.de>
Wed, 22 Jul 2020 08:48:25 +0000 (10:48 +0200)
committerChristoph Hellwig <hch@lst.de>
Fri, 31 Jul 2020 06:17:51 +0000 (08:17 +0200)
Split the main worker loop into a separate function.  This allows
devtmpfsd_setup to be marked __init, which will allows us to call
__init routines for the setup work.  devtmpfѕ itself needs a __ref
marker for that to work, and a comment explaining why it works.

Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/base/devtmpfs.c

index c9017e0..d697634 100644 (file)
@@ -378,7 +378,30 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid,
                return handle_remove(name, dev);
 }
 
-static int devtmpfs_setup(void *p)
+static void __noreturn devtmpfs_work_loop(void)
+{
+       while (1) {
+               spin_lock(&req_lock);
+               while (requests) {
+                       struct req *req = requests;
+                       requests = NULL;
+                       spin_unlock(&req_lock);
+                       while (req) {
+                               struct req *next = req->next;
+                               req->err = handle(req->name, req->mode,
+                                                 req->uid, req->gid, req->dev);
+                               complete(&req->done);
+                               req = next;
+                       }
+                       spin_lock(&req_lock);
+               }
+               __set_current_state(TASK_INTERRUPTIBLE);
+               spin_unlock(&req_lock);
+               schedule();
+       }
+}
+
+static int __init devtmpfs_setup(void *p)
 {
        int err;
 
@@ -396,31 +419,18 @@ out:
        return err;
 }
 
-static int devtmpfsd(void *p)
+/*
+ * The __ref is because devtmpfs_setup needs to be __init for the routines it
+ * calls.  That call is done while devtmpfs_init, which is marked __init,
+ * synchronously waits for it to complete.
+ */
+static int __ref devtmpfsd(void *p)
 {
        int err = devtmpfs_setup(p);
 
        if (err)
                return err;
-       while (1) {
-               spin_lock(&req_lock);
-               while (requests) {
-                       struct req *req = requests;
-                       requests = NULL;
-                       spin_unlock(&req_lock);
-                       while (req) {
-                               struct req *next = req->next;
-                               req->err = handle(req->name, req->mode,
-                                                 req->uid, req->gid, req->dev);
-                               complete(&req->done);
-                               req = next;
-                       }
-                       spin_lock(&req_lock);
-               }
-               __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock(&req_lock);
-               schedule();
-       }
+       devtmpfs_work_loop();
        return 0;
 }