From 01573e231f18eb2d99162747186f59511f56b64d Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 08 Dec 2023 10:40:48 +0000
Subject: [PATCH] 移去rt
---
kernel/drivers/base/devtmpfs.c | 151 +++++++++++++++++++++++++++++++-------------------
1 files changed, 94 insertions(+), 57 deletions(-)
diff --git a/kernel/drivers/base/devtmpfs.c b/kernel/drivers/base/devtmpfs.c
index f776807..b5cbaa6 100644
--- a/kernel/drivers/base/devtmpfs.c
+++ b/kernel/drivers/base/devtmpfs.c
@@ -25,15 +25,13 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/kthread.h>
+#include <linux/init_syscalls.h>
+#include <uapi/linux/mount.h>
#include "base.h"
static struct task_struct *thread;
-#if defined CONFIG_DEVTMPFS_MOUNT
-static int mount_dev = 1;
-#else
-static int mount_dev;
-#endif
+static int __initdata mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT);
static DEFINE_SPINLOCK(req_lock);
@@ -55,20 +53,39 @@
}
__setup("devtmpfs.mount=", mount_param);
-static struct dentry *dev_mount(struct file_system_type *fs_type, int flags,
+static struct vfsmount *mnt;
+
+static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{
-#ifdef CONFIG_TMPFS
- return mount_single(fs_type, flags, data, shmem_fill_super);
-#else
- return mount_single(fs_type, flags, data, ramfs_fill_super);
-#endif
+ struct super_block *s = mnt->mnt_sb;
+ int err;
+
+ atomic_inc(&s->s_active);
+ down_write(&s->s_umount);
+ err = reconfigure_single(s, flags, data);
+ if (err < 0) {
+ deactivate_locked_super(s);
+ return ERR_PTR(err);
+ }
+ return dget(s->s_root);
}
+
+static struct file_system_type internal_fs_type = {
+ .name = "devtmpfs",
+#ifdef CONFIG_TMPFS
+ .init_fs_context = shmem_init_fs_context,
+ .parameters = shmem_fs_parameters,
+#else
+ .init_fs_context = ramfs_init_fs_context,
+ .parameters = ramfs_fs_parameters,
+#endif
+ .kill_sb = kill_litter_super,
+};
static struct file_system_type dev_fs_type = {
.name = "devtmpfs",
- .mount = dev_mount,
- .kill_sb = kill_litter_super,
+ .mount = public_dev_mount,
};
#ifdef CONFIG_BLOCK
@@ -79,6 +96,23 @@
#else
static inline int is_blockdev(struct device *dev) { return 0; }
#endif
+
+static int devtmpfs_submit_req(struct req *req, const char *tmp)
+{
+ init_completion(&req->done);
+
+ spin_lock(&req_lock);
+ req->next = requests;
+ requests = req;
+ spin_unlock(&req_lock);
+
+ wake_up_process(thread);
+ wait_for_completion(&req->done);
+
+ kfree(tmp);
+
+ return req->err;
+}
int devtmpfs_create_node(struct device *dev)
{
@@ -104,19 +138,7 @@
req.dev = dev;
- init_completion(&req.done);
-
- spin_lock(&req_lock);
- req.next = requests;
- requests = &req;
- spin_unlock(&req_lock);
-
- wake_up_process(thread);
- wait_for_completion(&req.done);
-
- kfree(tmp);
-
- return req.err;
+ return devtmpfs_submit_req(&req, tmp);
}
int devtmpfs_delete_node(struct device *dev)
@@ -134,18 +156,7 @@
req.mode = 0;
req.dev = dev;
- init_completion(&req.done);
-
- spin_lock(&req_lock);
- req.next = requests;
- requests = &req;
- spin_unlock(&req_lock);
-
- wake_up_process(thread);
- wait_for_completion(&req.done);
-
- kfree(tmp);
- return req.err;
+ return devtmpfs_submit_req(&req, tmp);
}
static int dev_mkdir(const char *name, umode_t mode)
@@ -252,7 +263,7 @@
static int delete_path(const char *nodepath)
{
- const char *path;
+ char *path;
int err = 0;
path = kstrdup(nodepath, GFP_KERNEL);
@@ -346,7 +357,7 @@
* If configured, or requested by the commandline, devtmpfs will be
* auto-mounted after the kernel mounted the root filesystem.
*/
-int devtmpfs_mount(const char *mntdir)
+int __init devtmpfs_mount(void)
{
int err;
@@ -356,8 +367,7 @@
if (!thread)
return 0;
- err = ksys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT,
- NULL);
+ err = init_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
if (err)
printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
else
@@ -376,19 +386,8 @@
return handle_remove(name, dev);
}
-static int devtmpfsd(void *p)
+static void __noreturn devtmpfs_work_loop(void)
{
- char options[] = "mode=0755";
- int *err = p;
- *err = ksys_unshare(CLONE_NEWNS);
- if (*err)
- goto out;
- *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options);
- if (*err)
- goto out;
- ksys_chdir("/.."); /* will traverse into overmounted root */
- ksys_chroot(".");
- complete(&setup_done);
while (1) {
spin_lock(&req_lock);
while (requests) {
@@ -408,10 +407,39 @@
spin_unlock(&req_lock);
schedule();
}
- return 0;
+}
+
+static int __init devtmpfs_setup(void *p)
+{
+ int err;
+
+ err = ksys_unshare(CLONE_NEWNS);
+ if (err)
+ goto out;
+ err = init_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
+ if (err)
+ goto out;
+ init_chdir("/.."); /* will traverse into overmounted root */
+ init_chroot(".");
out:
+ *(int *)p = err;
+ 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);
+
complete(&setup_done);
- return *err;
+ if (err)
+ return err;
+ devtmpfs_work_loop();
+ return 0;
}
/*
@@ -420,7 +448,16 @@
*/
int __init devtmpfs_init(void)
{
- int err = register_filesystem(&dev_fs_type);
+ char opts[] = "mode=0755";
+ int err;
+
+ mnt = vfs_kern_mount(&internal_fs_type, 0, "devtmpfs", opts);
+ if (IS_ERR(mnt)) {
+ printk(KERN_ERR "devtmpfs: unable to create devtmpfs %ld\n",
+ PTR_ERR(mnt));
+ return PTR_ERR(mnt);
+ }
+ err = register_filesystem(&dev_fs_type);
if (err) {
printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
"type %i\n", err);
--
Gitblit v1.6.2