diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-12-24 00:44:44 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-01-14 09:05:26 -0500 |
commit | 4ecf09fd3a7c8858198875171b684c73338fad83 (patch) | |
tree | 3e14954a67e438be9a1bad29a6817ab3ddeff81f /arch/um | |
parent | 7b264fc2bef4a3de8bc5ff1a6c5b9e890b069a04 (diff) |
Unrot uml mconsole a bit
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/drivers/mconsole_kern.c | 49 |
1 files changed, 18 insertions, 31 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 51069245b79..3b3c36601a7 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -125,50 +125,36 @@ void mconsole_log(struct mc_request *req) | |||
125 | void mconsole_proc(struct mc_request *req) | 125 | void mconsole_proc(struct mc_request *req) |
126 | { | 126 | { |
127 | struct nameidata nd; | 127 | struct nameidata nd; |
128 | struct file_system_type *proc; | 128 | struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt; |
129 | struct super_block *super; | ||
130 | struct file *file; | 129 | struct file *file; |
131 | int n, err; | 130 | int n, err; |
132 | char *ptr = req->request.data, *buf; | 131 | char *ptr = req->request.data, *buf; |
132 | mm_segment_t old_fs = get_fs(); | ||
133 | 133 | ||
134 | ptr += strlen("proc"); | 134 | ptr += strlen("proc"); |
135 | ptr = skip_spaces(ptr); | 135 | ptr = skip_spaces(ptr); |
136 | 136 | ||
137 | proc = get_fs_type("proc"); | 137 | err = vfs_path_lookup(mnt->mnt_root, mnt, ptr, LOOKUP_FOLLOW, &nd); |
138 | if (proc == NULL) { | 138 | if (err) { |
139 | mconsole_reply(req, "procfs not registered", 1, 0); | 139 | mconsole_reply(req, "Failed to look up file", 1, 0); |
140 | goto out; | 140 | goto out; |
141 | } | 141 | } |
142 | 142 | ||
143 | super = (*proc->get_sb)(proc, 0, NULL, NULL); | 143 | err = may_open(&nd.path, MAY_READ, FMODE_READ); |
144 | put_filesystem(proc); | 144 | if (result) { |
145 | if (super == NULL) { | 145 | mconsole_reply(req, "Failed to open file", 1, 0); |
146 | mconsole_reply(req, "Failed to get procfs superblock", 1, 0); | 146 | path_put(&nd.path); |
147 | goto out; | 147 | goto out; |
148 | } | 148 | } |
149 | up_write(&super->s_umount); | ||
150 | |||
151 | nd.path.dentry = super->s_root; | ||
152 | nd.path.mnt = NULL; | ||
153 | nd.flags = O_RDONLY + 1; | ||
154 | nd.last_type = LAST_ROOT; | ||
155 | |||
156 | /* START: it was experienced that the stability problems are closed | ||
157 | * if commenting out these two calls + the below read cycle. To | ||
158 | * make UML crash again, it was enough to readd either one.*/ | ||
159 | err = link_path_walk(ptr, &nd); | ||
160 | if (err) { | ||
161 | mconsole_reply(req, "Failed to look up file", 1, 0); | ||
162 | goto out_kill; | ||
163 | } | ||
164 | 149 | ||
165 | file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY, | 150 | file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY, |
166 | current_cred()); | 151 | current_cred()); |
152 | err = PTR_ERR(file); | ||
167 | if (IS_ERR(file)) { | 153 | if (IS_ERR(file)) { |
168 | mconsole_reply(req, "Failed to open file", 1, 0); | 154 | mconsole_reply(req, "Failed to open file", 1, 0); |
169 | goto out_kill; | 155 | path_put(&nd.path); |
156 | goto out; | ||
170 | } | 157 | } |
171 | /*END*/ | ||
172 | 158 | ||
173 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 159 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
174 | if (buf == NULL) { | 160 | if (buf == NULL) { |
@@ -176,10 +162,13 @@ void mconsole_proc(struct mc_request *req) | |||
176 | goto out_fput; | 162 | goto out_fput; |
177 | } | 163 | } |
178 | 164 | ||
179 | if ((file->f_op != NULL) && (file->f_op->read != NULL)) { | 165 | if (file->f_op->read) { |
180 | do { | 166 | do { |
181 | n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, | 167 | loff_t pos; |
182 | &file->f_pos); | 168 | set_fs(KERNEL_DS); |
169 | n = vfs_read(file, buf, PAGE_SIZE - 1, &pos); | ||
170 | file_pos_write(file, pos); | ||
171 | set_fs(old_fs); | ||
183 | if (n >= 0) { | 172 | if (n >= 0) { |
184 | buf[n] = '\0'; | 173 | buf[n] = '\0'; |
185 | mconsole_reply(req, buf, 0, (n > 0)); | 174 | mconsole_reply(req, buf, 0, (n > 0)); |
@@ -197,8 +186,6 @@ void mconsole_proc(struct mc_request *req) | |||
197 | kfree(buf); | 186 | kfree(buf); |
198 | out_fput: | 187 | out_fput: |
199 | fput(file); | 188 | fput(file); |
200 | out_kill: | ||
201 | deactivate_super(super); | ||
202 | out: ; | 189 | out: ; |
203 | } | 190 | } |
204 | #endif | 191 | #endif |