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) {
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));
kfree(buf);
out_fput:
fput(file);
- out_kill:
- deactivate_super(super);
out: ;
}
#endif