Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ecf09fd authored by Al Viro's avatar Al Viro
Browse files

Unrot uml mconsole a bit



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 7b264fc2
Loading
Loading
Loading
Loading
+18 −31
Original line number Diff line number Diff line
@@ -125,50 +125,36 @@ void mconsole_log(struct mc_request *req)
void mconsole_proc(struct mc_request *req)
{
	struct nameidata nd;
	struct file_system_type *proc;
	struct super_block *super;
	struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
	struct file *file;
	int n, err;
	char *ptr = req->request.data, *buf;
	mm_segment_t old_fs = get_fs();

	ptr += strlen("proc");
	ptr = skip_spaces(ptr);

	proc = get_fs_type("proc");
	if (proc == NULL) {
		mconsole_reply(req, "procfs not registered", 1, 0);
	err = vfs_path_lookup(mnt->mnt_root, mnt, ptr, LOOKUP_FOLLOW, &nd);
	if (err) {
		mconsole_reply(req, "Failed to look up file", 1, 0);
		goto out;
	}

	super = (*proc->get_sb)(proc, 0, NULL, NULL);
	put_filesystem(proc);
	if (super == NULL) {
		mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
	err = may_open(&nd.path, MAY_READ, FMODE_READ);
	if (result) {
		mconsole_reply(req, "Failed to open file", 1, 0);
		path_put(&nd.path);
		goto out;
	}
	up_write(&super->s_umount);

	nd.path.dentry = super->s_root;
	nd.path.mnt = NULL;
	nd.flags = O_RDONLY + 1;
	nd.last_type = LAST_ROOT;

	/* START: it was experienced that the stability problems are closed
	 * if commenting out these two calls + the below read cycle. To
	 * make UML crash again, it was enough to readd either one.*/
	err = link_path_walk(ptr, &nd);
	if (err) {
		mconsole_reply(req, "Failed to look up file", 1, 0);
		goto out_kill;
	}

	file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
			   current_cred());
	err = PTR_ERR(file);
	if (IS_ERR(file)) {
		mconsole_reply(req, "Failed to open file", 1, 0);
		goto out_kill;
		path_put(&nd.path);
		goto out;
	}
	/*END*/

	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (buf == NULL) {
@@ -176,10 +162,13 @@ void mconsole_proc(struct mc_request *req)
		goto out_fput;
	}

	if ((file->f_op != NULL) && (file->f_op->read != NULL)) {
	if (file->f_op->read) {
		do {
			n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
						&file->f_pos);
			loff_t pos;
			set_fs(KERNEL_DS);
			n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
			file_pos_write(file, pos);
			set_fs(old_fs);
			if (n >= 0) {
				buf[n] = '\0';
				mconsole_reply(req, buf, 0, (n > 0));
@@ -197,8 +186,6 @@ void mconsole_proc(struct mc_request *req)
	kfree(buf);
 out_fput:
	fput(file);
 out_kill:
	deactivate_super(super);
 out: ;
}
#endif