]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/um/drivers/mconsole_kern.c
Merge branch 'for-linus-37rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
[karo-tx-linux.git] / arch / um / drivers / mconsole_kern.c
index 25e63fdd8028a0501b7fd05a0a08d2526e430263..79ccfe6c70787054c61d1116cb42449d562dfca8 100644 (file)
@@ -21,6 +21,9 @@
 #include <linux/un.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/file.h>
 #include <asm/uaccess.h>
 #include <asm/switch_to.h>
 
@@ -118,90 +121,38 @@ void mconsole_log(struct mc_request *req)
        mconsole_reply(req, "", 0, 0);
 }
 
-/* This is a more convoluted version of mconsole_proc, which has some stability
- * problems; however, we need it fixed, because it is expected that UML users
- * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
- * show the real procfs content, not the ones from hppfs.*/
-#if 0
 void mconsole_proc(struct mc_request *req)
 {
        struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
-       struct file *file;
-       int n;
-       char *ptr = req->request.data, *buf;
-       mm_segment_t old_fs = get_fs();
-
-       ptr += strlen("proc");
-       ptr = skip_spaces(ptr);
-
-       file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
-       if (IS_ERR(file)) {
-               mconsole_reply(req, "Failed to open file", 1, 0);
-               goto out;
-       }
-
-       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (buf == NULL) {
-               mconsole_reply(req, "Failed to allocate buffer", 1, 0);
-               goto out_fput;
-       }
-
-       if (file->f_op->read) {
-               do {
-                       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));
-                       }
-                       else {
-                               mconsole_reply(req, "Read of file failed",
-                                              1, 0);
-                               goto out_free;
-                       }
-               } while (n > 0);
-       }
-       else mconsole_reply(req, "", 0, 0);
-
- out_free:
-       kfree(buf);
- out_fput:
-       fput(file);
- out: ;
-}
-#endif
-
-void mconsole_proc(struct mc_request *req)
-{
-       char path[64];
        char *buf;
        int len;
-       int fd;
+       struct file *file;
        int first_chunk = 1;
        char *ptr = req->request.data;
 
        ptr += strlen("proc");
        ptr = skip_spaces(ptr);
-       snprintf(path, sizeof(path), "/proc/%s", ptr);
 
-       fd = sys_open(path, 0, 0);
-       if (fd < 0) {
+       file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
+       if (IS_ERR(file)) {
                mconsole_reply(req, "Failed to open file", 1, 0);
-               printk(KERN_ERR "open %s: %d\n",path,fd);
+               printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
                goto out;
        }
 
        buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
        if (buf == NULL) {
                mconsole_reply(req, "Failed to allocate buffer", 1, 0);
-               goto out_close;
+               goto out_fput;
        }
 
-       for (;;) {
-               len = sys_read(fd, buf, PAGE_SIZE-1);
+       do {
+               loff_t pos;
+               mm_segment_t old_fs = get_fs();
+               set_fs(KERNEL_DS);
+               len = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
+               set_fs(old_fs);
+               file->f_pos = pos;
                if (len < 0) {
                        mconsole_reply(req, "Read of file failed", 1, 0);
                        goto out_free;
@@ -211,22 +162,14 @@ void mconsole_proc(struct mc_request *req)
                        mconsole_reply(req, "\n", 0, 1);
                        first_chunk = 0;
                }
-               if (len == PAGE_SIZE-1) {
-                       buf[len] = '\0';
-                       mconsole_reply(req, buf, 0, 1);
-               } else {
-                       buf[len] = '\0';
-                       mconsole_reply(req, buf, 0, 0);
-                       break;
-               }
-       }
-
+               buf[len] = '\0';
+               mconsole_reply(req, buf, 0, (len > 0));
+       } while (len > 0);
  out_free:
        kfree(buf);
- out_close:
-       sys_close(fd);
- out:
-       /* nothing */;
+ out_fput:
+       fput(file);
+ out: ;
 }
 
 #define UML_MCONSOLE_HELPTEXT \
@@ -705,6 +648,7 @@ static void stack_proc(void *arg)
        struct task_struct *from = current, *to = arg;
 
        to->thread.saved_task = from;
+       rcu_switch(from, to);
        switch_to(from, to, from);
 }