Unrot uml mconsole a bit
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
7b264fc2be
Коммит
4ecf09fd3a
|
@ -125,50 +125,36 @@ void mconsole_log(struct mc_request *req)
|
||||||
void mconsole_proc(struct mc_request *req)
|
void mconsole_proc(struct mc_request *req)
|
||||||
{
|
{
|
||||||
struct nameidata nd;
|
struct nameidata nd;
|
||||||
struct file_system_type *proc;
|
struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
|
||||||
struct super_block *super;
|
|
||||||
struct file *file;
|
struct file *file;
|
||||||
int n, err;
|
int n, err;
|
||||||
char *ptr = req->request.data, *buf;
|
char *ptr = req->request.data, *buf;
|
||||||
|
mm_segment_t old_fs = get_fs();
|
||||||
|
|
||||||
ptr += strlen("proc");
|
ptr += strlen("proc");
|
||||||
ptr = skip_spaces(ptr);
|
ptr = skip_spaces(ptr);
|
||||||
|
|
||||||
proc = get_fs_type("proc");
|
err = vfs_path_lookup(mnt->mnt_root, mnt, ptr, LOOKUP_FOLLOW, &nd);
|
||||||
if (proc == NULL) {
|
|
||||||
mconsole_reply(req, "procfs not registered", 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);
|
|
||||||
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) {
|
if (err) {
|
||||||
mconsole_reply(req, "Failed to look up file", 1, 0);
|
mconsole_reply(req, "Failed to look up file", 1, 0);
|
||||||
goto out_kill;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
|
file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
|
||||||
current_cred());
|
current_cred());
|
||||||
|
err = PTR_ERR(file);
|
||||||
if (IS_ERR(file)) {
|
if (IS_ERR(file)) {
|
||||||
mconsole_reply(req, "Failed to open file", 1, 0);
|
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);
|
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
|
@ -176,10 +162,13 @@ void mconsole_proc(struct mc_request *req)
|
||||||
goto out_fput;
|
goto out_fput;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((file->f_op != NULL) && (file->f_op->read != NULL)) {
|
if (file->f_op->read) {
|
||||||
do {
|
do {
|
||||||
n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
|
loff_t pos;
|
||||||
&file->f_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) {
|
if (n >= 0) {
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
mconsole_reply(req, buf, 0, (n > 0));
|
mconsole_reply(req, buf, 0, (n > 0));
|
||||||
|
@ -197,8 +186,6 @@ void mconsole_proc(struct mc_request *req)
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
out_fput:
|
out_fput:
|
||||||
fput(file);
|
fput(file);
|
||||||
out_kill:
|
|
||||||
deactivate_super(super);
|
|
||||||
out: ;
|
out: ;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче