aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/fd.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/fd.c')
-rw-r--r--fs/proc/fd.c114
1 files changed, 48 insertions, 66 deletions
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index d7a4a28ef630..75f2890abbd8 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -167,11 +167,10 @@ static int proc_fd_link(struct dentry *dentry, struct path *path)
167 return ret; 167 return ret;
168} 168}
169 169
170static struct dentry * 170static int
171proc_fd_instantiate(struct inode *dir, struct dentry *dentry, 171proc_fd_instantiate(struct inode *dir, struct dentry *dentry,
172 struct task_struct *task, const void *ptr) 172 struct task_struct *task, const void *ptr)
173{ 173{
174 struct dentry *error = ERR_PTR(-ENOENT);
175 unsigned fd = (unsigned long)ptr; 174 unsigned fd = (unsigned long)ptr;
176 struct proc_inode *ei; 175 struct proc_inode *ei;
177 struct inode *inode; 176 struct inode *inode;
@@ -194,9 +193,9 @@ proc_fd_instantiate(struct inode *dir, struct dentry *dentry,
194 193
195 /* Close the race of the process dying before we return the dentry */ 194 /* Close the race of the process dying before we return the dentry */
196 if (tid_fd_revalidate(dentry, 0)) 195 if (tid_fd_revalidate(dentry, 0))
197 error = NULL; 196 return 0;
198 out: 197 out:
199 return error; 198 return -ENOENT;
200} 199}
201 200
202static struct dentry *proc_lookupfd_common(struct inode *dir, 201static struct dentry *proc_lookupfd_common(struct inode *dir,
@@ -204,7 +203,7 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,
204 instantiate_t instantiate) 203 instantiate_t instantiate)
205{ 204{
206 struct task_struct *task = get_proc_task(dir); 205 struct task_struct *task = get_proc_task(dir);
207 struct dentry *result = ERR_PTR(-ENOENT); 206 int result = -ENOENT;
208 unsigned fd = name_to_int(dentry); 207 unsigned fd = name_to_int(dentry);
209 208
210 if (!task) 209 if (!task)
@@ -216,77 +215,61 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,
216out: 215out:
217 put_task_struct(task); 216 put_task_struct(task);
218out_no_task: 217out_no_task:
219 return result; 218 return ERR_PTR(result);
220} 219}
221 220
222static int proc_readfd_common(struct file * filp, void * dirent, 221static int proc_readfd_common(struct file *file, struct dir_context *ctx,
223 filldir_t filldir, instantiate_t instantiate) 222 instantiate_t instantiate)
224{ 223{
225 struct dentry *dentry = filp->f_path.dentry; 224 struct task_struct *p = get_proc_task(file_inode(file));
226 struct inode *inode = dentry->d_inode;
227 struct task_struct *p = get_proc_task(inode);
228 struct files_struct *files; 225 struct files_struct *files;
229 unsigned int fd, ino; 226 unsigned int fd;
230 int retval;
231 227
232 retval = -ENOENT;
233 if (!p) 228 if (!p)
234 goto out_no_task; 229 return -ENOENT;
235 retval = 0;
236
237 fd = filp->f_pos;
238 switch (fd) {
239 case 0:
240 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
241 goto out;
242 filp->f_pos++;
243 case 1:
244 ino = parent_ino(dentry);
245 if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
246 goto out;
247 filp->f_pos++;
248 default:
249 files = get_files_struct(p);
250 if (!files)
251 goto out;
252 rcu_read_lock();
253 for (fd = filp->f_pos - 2;
254 fd < files_fdtable(files)->max_fds;
255 fd++, filp->f_pos++) {
256 char name[PROC_NUMBUF];
257 int len;
258 int rv;
259
260 if (!fcheck_files(files, fd))
261 continue;
262 rcu_read_unlock();
263 230
264 len = snprintf(name, sizeof(name), "%d", fd); 231 if (!dir_emit_dots(file, ctx))
265 rv = proc_fill_cache(filp, dirent, filldir, 232 goto out;
266 name, len, instantiate, p, 233 if (!dir_emit_dots(file, ctx))
267 (void *)(unsigned long)fd); 234 goto out;
268 if (rv < 0) 235 files = get_files_struct(p);
269 goto out_fd_loop; 236 if (!files)
270 rcu_read_lock(); 237 goto out;
271 } 238
272 rcu_read_unlock(); 239 rcu_read_lock();
273out_fd_loop: 240 for (fd = ctx->pos - 2;
274 put_files_struct(files); 241 fd < files_fdtable(files)->max_fds;
242 fd++, ctx->pos++) {
243 char name[PROC_NUMBUF];
244 int len;
245
246 if (!fcheck_files(files, fd))
247 continue;
248 rcu_read_unlock();
249
250 len = snprintf(name, sizeof(name), "%d", fd);
251 if (!proc_fill_cache(file, ctx,
252 name, len, instantiate, p,
253 (void *)(unsigned long)fd))
254 goto out_fd_loop;
255 rcu_read_lock();
275 } 256 }
257 rcu_read_unlock();
258out_fd_loop:
259 put_files_struct(files);
276out: 260out:
277 put_task_struct(p); 261 put_task_struct(p);
278out_no_task: 262 return 0;
279 return retval;
280} 263}
281 264
282static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir) 265static int proc_readfd(struct file *file, struct dir_context *ctx)
283{ 266{
284 return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate); 267 return proc_readfd_common(file, ctx, proc_fd_instantiate);
285} 268}
286 269
287const struct file_operations proc_fd_operations = { 270const struct file_operations proc_fd_operations = {
288 .read = generic_read_dir, 271 .read = generic_read_dir,
289 .readdir = proc_readfd, 272 .iterate = proc_readfd,
290 .llseek = default_llseek, 273 .llseek = default_llseek,
291}; 274};
292 275
@@ -316,11 +299,10 @@ const struct inode_operations proc_fd_inode_operations = {
316 .setattr = proc_setattr, 299 .setattr = proc_setattr,
317}; 300};
318 301
319static struct dentry * 302static int
320proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry, 303proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry,
321 struct task_struct *task, const void *ptr) 304 struct task_struct *task, const void *ptr)
322{ 305{
323 struct dentry *error = ERR_PTR(-ENOENT);
324 unsigned fd = (unsigned long)ptr; 306 unsigned fd = (unsigned long)ptr;
325 struct proc_inode *ei; 307 struct proc_inode *ei;
326 struct inode *inode; 308 struct inode *inode;
@@ -340,9 +322,9 @@ proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry,
340 322
341 /* Close the race of the process dying before we return the dentry */ 323 /* Close the race of the process dying before we return the dentry */
342 if (tid_fd_revalidate(dentry, 0)) 324 if (tid_fd_revalidate(dentry, 0))
343 error = NULL; 325 return 0;
344 out: 326 out:
345 return error; 327 return -ENOENT;
346} 328}
347 329
348static struct dentry * 330static struct dentry *
@@ -351,9 +333,9 @@ proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
351 return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate); 333 return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
352} 334}
353 335
354static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir) 336static int proc_readfdinfo(struct file *file, struct dir_context *ctx)
355{ 337{
356 return proc_readfd_common(filp, dirent, filldir, 338 return proc_readfd_common(file, ctx,
357 proc_fdinfo_instantiate); 339 proc_fdinfo_instantiate);
358} 340}
359 341
@@ -364,6 +346,6 @@ const struct inode_operations proc_fdinfo_inode_operations = {
364 346
365const struct file_operations proc_fdinfo_operations = { 347const struct file_operations proc_fdinfo_operations = {
366 .read = generic_read_dir, 348 .read = generic_read_dir,
367 .readdir = proc_readfdinfo, 349 .iterate = proc_readfdinfo,
368 .llseek = default_llseek, 350 .llseek = default_llseek,
369}; 351};