summaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2020-07-22 10:48:25 +0200
committerChristoph Hellwig <hch@lst.de>2020-07-31 08:17:51 +0200
commitbcbacc4909f1b93242ba2894d0282c151c9d0e68 (patch)
tree510b897f756f8c2e7b1f9c2bf6b3b32b119671b2 /drivers/base
parente24ab0ef689de43649327f54cd1088f3dad25bb3 (diff)
downloadlinux-bcbacc4909f1b93242ba2894d0282c151c9d0e68.tar.bz2
devtmpfs: refactor devtmpfsd()
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>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/devtmpfs.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index c9017e0584c0..d697634bc0d4 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -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;
}