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>
This commit is contained in:
Christoph Hellwig 2020-07-22 10:48:25 +02:00
parent e24ab0ef68
commit bcbacc4909

View File

@ -378,30 +378,8 @@ 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)
{
int err;
err = ksys_unshare(CLONE_NEWNS);
if (err)
goto out;
err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
if (err)
goto out;
ksys_chdir("/.."); /* will traverse into overmounted root */
ksys_chroot(".");
out:
*(int *)p = err;
complete(&setup_done);
return err;
}
static int devtmpfsd(void *p)
{
int err = devtmpfs_setup(p);
if (err)
return err;
while (1) {
spin_lock(&req_lock);
while (requests) {
@ -421,6 +399,38 @@ static int devtmpfsd(void *p)
spin_unlock(&req_lock);
schedule();
}
}
static int __init devtmpfs_setup(void *p)
{
int err;
err = ksys_unshare(CLONE_NEWNS);
if (err)
goto out;
err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
if (err)
goto out;
ksys_chdir("/.."); /* will traverse into overmounted root */
ksys_chroot(".");
out:
*(int *)p = err;
complete(&setup_done);
return err;
}
/*
* 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;
devtmpfs_work_loop();
return 0;
}