]> git.hungrycats.org Git - linux/commitdiff
[PATCH] (4/5) sane procfs/dcache interaction
authorAlexander Viro <viro@math.psu.edu>
Mon, 22 Apr 2002 06:03:47 +0000 (23:03 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Mon, 22 Apr 2002 06:03:47 +0000 (23:03 -0700)
 - preparation for sane policy for /proc/<pid>/fd/* - don't store
   struct file * in these inodes anymore.

fs/proc/base.c
include/linux/proc_fs.h

index 7dfa4f269ab642fb79750d4de44d7b259c9c9ace..a28a670b12df2b9d2f41e69a9c03e81b7102c1a4 100644 (file)
 
 #define fake_ino(pid,ino) (((pid)<<16)|(ino))
 
+enum pid_directory_inos {
+       PROC_PID_INO = 2,
+       PROC_PID_STATUS,
+       PROC_PID_MEM,
+       PROC_PID_CWD,
+       PROC_PID_ROOT,
+       PROC_PID_EXE,
+       PROC_PID_FD,
+       PROC_PID_ENVIRON,
+       PROC_PID_CMDLINE,
+       PROC_PID_STAT,
+       PROC_PID_STATM,
+       PROC_PID_MAPS,
+       PROC_PID_CPU,
+       PROC_PID_MOUNTS,
+       PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
+};
+
+struct pid_entry {
+       int type;
+       int len;
+       char *name;
+       mode_t mode;
+};
+
+#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
+static struct pid_entry base_stuff[] = {
+  E(PROC_PID_FD,       "fd",           S_IFDIR|S_IRUSR|S_IXUSR),
+  E(PROC_PID_ENVIRON,  "environ",      S_IFREG|S_IRUSR),
+  E(PROC_PID_STATUS,   "status",       S_IFREG|S_IRUGO),
+  E(PROC_PID_CMDLINE,  "cmdline",      S_IFREG|S_IRUGO),
+  E(PROC_PID_STAT,     "stat",         S_IFREG|S_IRUGO),
+  E(PROC_PID_STATM,    "statm",        S_IFREG|S_IRUGO),
+#ifdef CONFIG_SMP
+  E(PROC_PID_CPU,      "cpu",          S_IFREG|S_IRUGO),
+#endif
+  E(PROC_PID_MAPS,     "maps",         S_IFREG|S_IRUGO),
+  E(PROC_PID_MEM,      "mem",          S_IFREG|S_IRUSR|S_IWUSR),
+  E(PROC_PID_CWD,      "cwd",          S_IFLNK|S_IRWXUGO),
+  E(PROC_PID_ROOT,     "root",         S_IFLNK|S_IRWXUGO),
+  E(PROC_PID_EXE,      "exe",          S_IFLNK|S_IRWXUGO),
+  E(PROC_PID_MOUNTS,   "mounts",       S_IFREG|S_IRUGO),
+  {0,0,NULL,0}
+};
+#undef E
+
 static inline struct task_struct *proc_task(struct inode *inode)
 {
        return PROC_I(inode)->task;
@@ -50,11 +96,28 @@ int proc_pid_cpu(struct task_struct*,char*);
 
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
-       struct file *file = PROC_I(inode)->file;
-       if (file) {
-               *mnt = mntget(file->f_vfsmnt);
-               *dentry = dget(file->f_dentry);
-               return 0;
+       struct task_struct *task = proc_task(inode);
+       struct files_struct *files;
+       struct file *file;
+       int fd = (inode->i_ino & 0xffff) - PROC_PID_FD_DIR;
+
+       task_lock(task);
+       files = task->files;
+       if (files)
+               atomic_inc(&files->count);
+       task_unlock(task);
+       if (files) {
+               read_lock(&files->file_lock);
+               file = fcheck_files(files, fd);
+               if (file) {
+                       *mnt = mntget(file->f_vfsmnt);
+                       *dentry = dget(file->f_dentry);
+                       read_unlock(&files->file_lock);
+                       put_files_struct(files);
+                       return 0;
+               }
+               read_unlock(&files->file_lock);
+               put_files_struct(files);
        }
        return -ENOENT;
 }
@@ -525,52 +588,6 @@ static struct inode_operations proc_pid_link_inode_operations = {
        follow_link:    proc_pid_follow_link
 };
 
-struct pid_entry {
-       int type;
-       int len;
-       char *name;
-       mode_t mode;
-};
-
-enum pid_directory_inos {
-       PROC_PID_INO = 2,
-       PROC_PID_STATUS,
-       PROC_PID_MEM,
-       PROC_PID_CWD,
-       PROC_PID_ROOT,
-       PROC_PID_EXE,
-       PROC_PID_FD,
-       PROC_PID_ENVIRON,
-       PROC_PID_CMDLINE,
-       PROC_PID_STAT,
-       PROC_PID_STATM,
-       PROC_PID_MAPS,
-       PROC_PID_CPU,
-       PROC_PID_MOUNTS,
-       PROC_PID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
-};
-
-#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
-static struct pid_entry base_stuff[] = {
-  E(PROC_PID_FD,       "fd",           S_IFDIR|S_IRUSR|S_IXUSR),
-  E(PROC_PID_ENVIRON,  "environ",      S_IFREG|S_IRUSR),
-  E(PROC_PID_STATUS,   "status",       S_IFREG|S_IRUGO),
-  E(PROC_PID_CMDLINE,  "cmdline",      S_IFREG|S_IRUGO),
-  E(PROC_PID_STAT,     "stat",         S_IFREG|S_IRUGO),
-  E(PROC_PID_STATM,    "statm",        S_IFREG|S_IRUGO),
-#ifdef CONFIG_SMP
-  E(PROC_PID_CPU,      "cpu",          S_IFREG|S_IRUGO),
-#endif
-  E(PROC_PID_MAPS,     "maps",         S_IFREG|S_IRUGO),
-  E(PROC_PID_MEM,      "mem",          S_IFREG|S_IRUSR|S_IWUSR),
-  E(PROC_PID_CWD,      "cwd",          S_IFLNK|S_IRWXUGO),
-  E(PROC_PID_ROOT,     "root",         S_IFLNK|S_IRWXUGO),
-  E(PROC_PID_EXE,      "exe",          S_IFLNK|S_IRWXUGO),
-  E(PROC_PID_MOUNTS,   "mounts",       S_IFREG|S_IRUGO),
-  {0,0,NULL,0}
-};
-#undef E
-
 #define NUMBUF 10
 
 static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
@@ -707,7 +724,6 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
        /* Common stuff */
        ei = PROC_I(inode);
        ei->task = NULL;
-       ei->file = NULL;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
        inode->i_ino = fake_ino(task->pid, ino);
 
@@ -842,21 +858,20 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
        task_unlock(task);
        if (!files)
                goto out_unlock;
+       inode->i_mode = S_IFLNK;
        read_lock(&files->file_lock);
-       file = ei->file = fcheck_files(files, fd);
+       file = fcheck_files(files, fd);
        if (!file)
                goto out_unlock2;
-       get_file(file);
+       if (file->f_mode & 1)
+               inode->i_mode |= S_IRUSR | S_IXUSR;
+       if (file->f_mode & 2)
+               inode->i_mode |= S_IWUSR | S_IXUSR;
        read_unlock(&files->file_lock);
        put_files_struct(files);
        inode->i_op = &proc_pid_link_inode_operations;
        inode->i_size = 64;
-       inode->i_mode = S_IFLNK;
        ei->op.proc_get_link = proc_fd_link;
-       if (file->f_mode & 1)
-               inode->i_mode |= S_IRUSR | S_IXUSR;
-       if (file->f_mode & 2)
-               inode->i_mode |= S_IWUSR | S_IXUSR;
        dentry->d_op = &pid_fd_dentry_operations;
        d_add(dentry, inode);
        if (!proc_task(dentry->d_inode)->pid)
@@ -1078,8 +1093,6 @@ out:
 
 void proc_pid_delete_inode(struct inode *inode)
 {
-       if (PROC_I(inode)->file)
-               fput(PROC_I(inode)->file);
        if (proc_task(inode))
                put_task_struct(proc_task(inode));
 }
index a0944b88f84d1deb0d72999d315fcbfb2e6f2183..33e093a1357be6e3be1948c0dade0e431d91c9a0 100644 (file)
@@ -212,7 +212,6 @@ struct proc_inode {
                int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
                int (*proc_read)(struct task_struct *task, char *page);
        } op;
-       struct file *file;
        struct proc_dir_entry *pde;
        struct inode vfs_inode;
 };