aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-08-19 13:00:49 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-26 21:09:56 -0400
commit723a1d77431b0c568730ffac4dd0bcbbd3400031 (patch)
treea1335933759ac8de11eb8004568ac2301339c0fc /arch/um/drivers
parent483ce1d4b8c3b82bc9c9a1dd9dbc44f50b3aaf5a (diff)
um: resurrect the right variant of mconsole_proc()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/mconsole_kern.c99
1 files changed, 21 insertions, 78 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 664a60e8dfb4..495e5a725aa1 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -21,6 +21,9 @@
21#include <linux/un.h> 21#include <linux/un.h>
22#include <linux/workqueue.h> 22#include <linux/workqueue.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/fs.h>
25#include <linux/mount.h>
26#include <linux/file.h>
24#include <asm/uaccess.h> 27#include <asm/uaccess.h>
25#include <asm/switch_to.h> 28#include <asm/switch_to.h>
26 29
@@ -118,90 +121,38 @@ void mconsole_log(struct mc_request *req)
118 mconsole_reply(req, "", 0, 0); 121 mconsole_reply(req, "", 0, 0);
119} 122}
120 123
121/* This is a more convoluted version of mconsole_proc, which has some stability
122 * problems; however, we need it fixed, because it is expected that UML users
123 * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
124 * show the real procfs content, not the ones from hppfs.*/
125#if 0
126void mconsole_proc(struct mc_request *req) 124void mconsole_proc(struct mc_request *req)
127{ 125{
128 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt; 126 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
129 struct file *file;
130 int n;
131 char *ptr = req->request.data, *buf;
132 mm_segment_t old_fs = get_fs();
133
134 ptr += strlen("proc");
135 ptr = skip_spaces(ptr);
136
137 file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
138 if (IS_ERR(file)) {
139 mconsole_reply(req, "Failed to open file", 1, 0);
140 goto out;
141 }
142
143 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
144 if (buf == NULL) {
145 mconsole_reply(req, "Failed to allocate buffer", 1, 0);
146 goto out_fput;
147 }
148
149 if (file->f_op->read) {
150 do {
151 loff_t pos;
152 set_fs(KERNEL_DS);
153 n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
154 file_pos_write(file, pos);
155 set_fs(old_fs);
156 if (n >= 0) {
157 buf[n] = '\0';
158 mconsole_reply(req, buf, 0, (n > 0));
159 }
160 else {
161 mconsole_reply(req, "Read of file failed",
162 1, 0);
163 goto out_free;
164 }
165 } while (n > 0);
166 }
167 else mconsole_reply(req, "", 0, 0);
168
169 out_free:
170 kfree(buf);
171 out_fput:
172 fput(file);
173 out: ;
174}
175#endif
176
177void mconsole_proc(struct mc_request *req)
178{
179 char path[64];
180 char *buf; 127 char *buf;
181 int len; 128 int len;
182 int fd; 129 struct file *file;
183 int first_chunk = 1; 130 int first_chunk = 1;
184 char *ptr = req->request.data; 131 char *ptr = req->request.data;
185 132
186 ptr += strlen("proc"); 133 ptr += strlen("proc");
187 ptr = skip_spaces(ptr); 134 ptr = skip_spaces(ptr);
188 snprintf(path, sizeof(path), "/proc/%s", ptr);
189 135
190 fd = sys_open(path, 0, 0); 136 file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
191 if (fd < 0) { 137 if (IS_ERR(file)) {
192 mconsole_reply(req, "Failed to open file", 1, 0); 138 mconsole_reply(req, "Failed to open file", 1, 0);
193 printk(KERN_ERR "open %s: %d\n",path,fd); 139 printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
194 goto out; 140 goto out;
195 } 141 }
196 142
197 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 143 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
198 if (buf == NULL) { 144 if (buf == NULL) {
199 mconsole_reply(req, "Failed to allocate buffer", 1, 0); 145 mconsole_reply(req, "Failed to allocate buffer", 1, 0);
200 goto out_close; 146 goto out_fput;
201 } 147 }
202 148
203 for (;;) { 149 do {
204 len = sys_read(fd, buf, PAGE_SIZE-1); 150 loff_t pos;
151 mm_segment_t old_fs = get_fs();
152 set_fs(KERNEL_DS);
153 len = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
154 set_fs(old_fs);
155 file->f_pos = pos;
205 if (len < 0) { 156 if (len < 0) {
206 mconsole_reply(req, "Read of file failed", 1, 0); 157 mconsole_reply(req, "Read of file failed", 1, 0);
207 goto out_free; 158 goto out_free;
@@ -211,22 +162,14 @@ void mconsole_proc(struct mc_request *req)
211 mconsole_reply(req, "\n", 0, 1); 162 mconsole_reply(req, "\n", 0, 1);
212 first_chunk = 0; 163 first_chunk = 0;
213 } 164 }
214 if (len == PAGE_SIZE-1) { 165 buf[len] = '\0';
215 buf[len] = '\0'; 166 mconsole_reply(req, buf, 0, (len > 0));
216 mconsole_reply(req, buf, 0, 1); 167 } while (len > 0);
217 } else {
218 buf[len] = '\0';
219 mconsole_reply(req, buf, 0, 0);
220 break;
221 }
222 }
223
224 out_free: 168 out_free:
225 kfree(buf); 169 kfree(buf);
226 out_close: 170 out_fput:
227 sys_close(fd); 171 fput(file);
228 out: 172 out: ;
229 /* nothing */;
230} 173}
231 174
232#define UML_MCONSOLE_HELPTEXT \ 175#define UML_MCONSOLE_HELPTEXT \