d_hash_and_lookup(): export, switch open-coded instances
[sfrench/cifs-2.6.git] / fs / proc / base.c
index aa63d25157b8d396a9a7d0f1728fe673fa577e31..9d962555972791c41d6e8d154ff53c425b300a9d 100644 (file)
@@ -383,7 +383,7 @@ static int lstats_open(struct inode *inode, struct file *file)
 static ssize_t lstats_write(struct file *file, const char __user *buf,
                            size_t count, loff_t *offs)
 {
-       struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
+       struct task_struct *task = get_proc_task(file_inode(file));
 
        if (!task)
                return -ESRCH;
@@ -542,13 +542,6 @@ int proc_setattr(struct dentry *dentry, struct iattr *attr)
        if (error)
                return error;
 
-       if ((attr->ia_valid & ATTR_SIZE) &&
-           attr->ia_size != i_size_read(inode)) {
-               error = vmtruncate(inode, attr->ia_size);
-               if (error)
-                       return error;
-       }
-
        setattr_copy(inode, attr);
        mark_inode_dirty(inode);
        return 0;
@@ -609,7 +602,7 @@ static const struct inode_operations proc_def_inode_operations = {
 static ssize_t proc_info_read(struct file * file, char __user * buf,
                          size_t count, loff_t *ppos)
 {
-       struct inode * inode = file->f_path.dentry->d_inode;
+       struct inode * inode = file_inode(file);
        unsigned long page;
        ssize_t length;
        struct task_struct *task = get_proc_task(inode);
@@ -675,7 +668,7 @@ static const struct file_operations proc_single_file_operations = {
 
 static int __mem_open(struct inode *inode, struct file *file, unsigned int mode)
 {
-       struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+       struct task_struct *task = get_proc_task(file_inode(file));
        struct mm_struct *mm;
 
        if (!task)
@@ -876,7 +869,7 @@ static const struct file_operations proc_environ_operations = {
 static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
                            loff_t *ppos)
 {
-       struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+       struct task_struct *task = get_proc_task(file_inode(file));
        char buffer[PROC_NUMBUF];
        int oom_adj = OOM_ADJUST_MIN;
        size_t len;
@@ -923,7 +916,7 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
                goto out;
        }
 
-       task = get_proc_task(file->f_path.dentry->d_inode);
+       task = get_proc_task(file_inode(file));
        if (!task) {
                err = -ESRCH;
                goto out;
@@ -983,7 +976,7 @@ static const struct file_operations proc_oom_adj_operations = {
 static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
                                        size_t count, loff_t *ppos)
 {
-       struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+       struct task_struct *task = get_proc_task(file_inode(file));
        char buffer[PROC_NUMBUF];
        short oom_score_adj = OOM_SCORE_ADJ_MIN;
        unsigned long flags;
@@ -1026,7 +1019,7 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
                goto out;
        }
 
-       task = get_proc_task(file->f_path.dentry->d_inode);
+       task = get_proc_task(file_inode(file));
        if (!task) {
                err = -ESRCH;
                goto out;
@@ -1074,7 +1067,7 @@ static const struct file_operations proc_oom_score_adj_operations = {
 static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
                                  size_t count, loff_t *ppos)
 {
-       struct inode * inode = file->f_path.dentry->d_inode;
+       struct inode * inode = file_inode(file);
        struct task_struct *task = get_proc_task(inode);
        ssize_t length;
        char tmpbuf[TMPBUFLEN];
@@ -1091,7 +1084,7 @@ static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
 static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
                                   size_t count, loff_t *ppos)
 {
-       struct inode * inode = file->f_path.dentry->d_inode;
+       struct inode * inode = file_inode(file);
        char *page, *tmp;
        ssize_t length;
        uid_t loginuid;
@@ -1149,7 +1142,7 @@ static const struct file_operations proc_loginuid_operations = {
 static ssize_t proc_sessionid_read(struct file * file, char __user * buf,
                                  size_t count, loff_t *ppos)
 {
-       struct inode * inode = file->f_path.dentry->d_inode;
+       struct inode * inode = file_inode(file);
        struct task_struct *task = get_proc_task(inode);
        ssize_t length;
        char tmpbuf[TMPBUFLEN];
@@ -1172,7 +1165,7 @@ static const struct file_operations proc_sessionid_operations = {
 static ssize_t proc_fault_inject_read(struct file * file, char __user * buf,
                                      size_t count, loff_t *ppos)
 {
-       struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
+       struct task_struct *task = get_proc_task(file_inode(file));
        char buffer[PROC_NUMBUF];
        size_t len;
        int make_it_fail;
@@ -1204,7 +1197,7 @@ static ssize_t proc_fault_inject_write(struct file * file,
        make_it_fail = simple_strtol(strstrip(buffer), &end, 0);
        if (*end)
                return -EINVAL;
-       task = get_proc_task(file->f_dentry->d_inode);
+       task = get_proc_task(file_inode(file));
        if (!task)
                return -ESRCH;
        task->make_it_fail = make_it_fail;
@@ -1244,7 +1237,7 @@ static ssize_t
 sched_write(struct file *file, const char __user *buf,
            size_t count, loff_t *offset)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
+       struct inode *inode = file_inode(file);
        struct task_struct *p;
 
        p = get_proc_task(inode);
@@ -1295,7 +1288,7 @@ static ssize_t
 sched_autogroup_write(struct file *file, const char __user *buf,
            size_t count, loff_t *offset)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
+       struct inode *inode = file_inode(file);
        struct task_struct *p;
        char buffer[PROC_NUMBUF];
        int nice;
@@ -1350,7 +1343,7 @@ static const struct file_operations proc_pid_sched_autogroup_operations = {
 static ssize_t comm_write(struct file *file, const char __user *buf,
                                size_t count, loff_t *offset)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
+       struct inode *inode = file_inode(file);
        struct task_struct *p;
        char buffer[TASK_COMM_LEN];
 
@@ -2153,7 +2146,7 @@ out_no_task:
 static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
                                  size_t count, loff_t *ppos)
 {
-       struct inode * inode = file->f_path.dentry->d_inode;
+       struct inode * inode = file_inode(file);
        char *p = NULL;
        ssize_t length;
        struct task_struct *task = get_proc_task(inode);
@@ -2174,7 +2167,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
 static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
                                   size_t count, loff_t *ppos)
 {
-       struct inode * inode = file->f_path.dentry->d_inode;
+       struct inode * inode = file_inode(file);
        char *page;
        ssize_t length;
        struct task_struct *task = get_proc_task(inode);
@@ -2263,7 +2256,7 @@ static const struct inode_operations proc_attr_dir_inode_operations = {
 static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf,
                                         size_t count, loff_t *ppos)
 {
-       struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
+       struct task_struct *task = get_proc_task(file_inode(file));
        struct mm_struct *mm;
        char buffer[PROC_NUMBUF];
        size_t len;
@@ -2315,7 +2308,7 @@ static ssize_t proc_coredump_filter_write(struct file *file,
                goto out_no_task;
 
        ret = -ESRCH;
-       task = get_proc_task(file->f_dentry->d_inode);
+       task = get_proc_task(file_inode(file));
        if (!task)
                goto out_no_task;
 
@@ -2345,146 +2338,6 @@ static const struct file_operations proc_coredump_filter_operations = {
 };
 #endif
 
-/*
- * /proc/self:
- */
-static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
-                             int buflen)
-{
-       struct pid_namespace *ns = dentry->d_sb->s_fs_info;
-       pid_t tgid = task_tgid_nr_ns(current, ns);
-       char tmp[PROC_NUMBUF];
-       if (!tgid)
-               return -ENOENT;
-       sprintf(tmp, "%d", tgid);
-       return vfs_readlink(dentry,buffer,buflen,tmp);
-}
-
-static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
-       struct pid_namespace *ns = dentry->d_sb->s_fs_info;
-       pid_t tgid = task_tgid_nr_ns(current, ns);
-       char *name = ERR_PTR(-ENOENT);
-       if (tgid) {
-               /* 11 for max length of signed int in decimal + NULL term */
-               name = kmalloc(12, GFP_KERNEL);
-               if (!name)
-                       name = ERR_PTR(-ENOMEM);
-               else
-                       sprintf(name, "%d", tgid);
-       }
-       nd_set_link(nd, name);
-       return NULL;
-}
-
-static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
-                               void *cookie)
-{
-       char *s = nd_get_link(nd);
-       if (!IS_ERR(s))
-               kfree(s);
-}
-
-static const struct inode_operations proc_self_inode_operations = {
-       .readlink       = proc_self_readlink,
-       .follow_link    = proc_self_follow_link,
-       .put_link       = proc_self_put_link,
-};
-
-/*
- * proc base
- *
- * These are the directory entries in the root directory of /proc
- * that properly belong to the /proc filesystem, as they describe
- * describe something that is process related.
- */
-static const struct pid_entry proc_base_stuff[] = {
-       NOD("self", S_IFLNK|S_IRWXUGO,
-               &proc_self_inode_operations, NULL, {}),
-};
-
-static struct dentry *proc_base_instantiate(struct inode *dir,
-       struct dentry *dentry, struct task_struct *task, const void *ptr)
-{
-       const struct pid_entry *p = ptr;
-       struct inode *inode;
-       struct proc_inode *ei;
-       struct dentry *error;
-
-       /* Allocate the inode */
-       error = ERR_PTR(-ENOMEM);
-       inode = new_inode(dir->i_sb);
-       if (!inode)
-               goto out;
-
-       /* Initialize the inode */
-       ei = PROC_I(inode);
-       inode->i_ino = get_next_ino();
-       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-
-       /*
-        * grab the reference to the task.
-        */
-       ei->pid = get_task_pid(task, PIDTYPE_PID);
-       if (!ei->pid)
-               goto out_iput;
-
-       inode->i_mode = p->mode;
-       if (S_ISDIR(inode->i_mode))
-               set_nlink(inode, 2);
-       if (S_ISLNK(inode->i_mode))
-               inode->i_size = 64;
-       if (p->iop)
-               inode->i_op = p->iop;
-       if (p->fop)
-               inode->i_fop = p->fop;
-       ei->op = p->op;
-       d_add(dentry, inode);
-       error = NULL;
-out:
-       return error;
-out_iput:
-       iput(inode);
-       goto out;
-}
-
-static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
-{
-       struct dentry *error;
-       struct task_struct *task = get_proc_task(dir);
-       const struct pid_entry *p, *last;
-
-       error = ERR_PTR(-ENOENT);
-
-       if (!task)
-               goto out_no_task;
-
-       /* Lookup the directory entry */
-       last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1];
-       for (p = proc_base_stuff; p <= last; p++) {
-               if (p->len != dentry->d_name.len)
-                       continue;
-               if (!memcmp(dentry->d_name.name, p->name, p->len))
-                       break;
-       }
-       if (p > last)
-               goto out;
-
-       error = proc_base_instantiate(dir, dentry, task, p);
-
-out:
-       put_task_struct(task);
-out_no_task:
-       return error;
-}
-
-static int proc_base_fill_cache(struct file *filp, void *dirent,
-       filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
-{
-       return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
-                               proc_base_instantiate, task, p);
-}
-
 #ifdef CONFIG_TASK_IO_ACCOUNTING
 static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
 {
@@ -2765,6 +2618,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
 
        name.name = buf;
        name.len = snprintf(buf, sizeof(buf), "%d", pid);
+       /* no ->d_hash() rejects on procfs */
        dentry = d_hash_and_lookup(mnt->mnt_root, &name);
        if (dentry) {
                shrink_dcache_parent(dentry);
@@ -2839,10 +2693,6 @@ void proc_flush_task(struct task_struct *task)
                proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr,
                                        tgid->numbers[i].nr);
        }
-
-       upid = &pid->numbers[pid->level];
-       if (upid->nr == 1)
-               pid_ns_release_proc(upid->ns);
 }
 
 static struct dentry *proc_pid_instantiate(struct inode *dir,
@@ -2876,15 +2726,11 @@ out:
 
 struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
 {
-       struct dentry *result;
+       struct dentry *result = NULL;
        struct task_struct *task;
        unsigned tgid;
        struct pid_namespace *ns;
 
-       result = proc_base_lookup(dir, dentry);
-       if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
-               goto out;
-
        tgid = name_to_int(dentry);
        if (tgid == ~0U)
                goto out;
@@ -2947,7 +2793,7 @@ retry:
        return iter;
 }
 
-#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))
+#define TGID_OFFSET (FIRST_PROCESS_ENTRY)
 
 static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
        struct tgid_iter iter)
@@ -2967,25 +2813,12 @@ static int fake_filldir(void *buf, const char *name, int namelen,
 /* for the /proc/ directory itself, after non-process stuff has been done */
 int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-       unsigned int nr;
-       struct task_struct *reaper;
        struct tgid_iter iter;
        struct pid_namespace *ns;
        filldir_t __filldir;
 
        if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET)
-               goto out_no_task;
-       nr = filp->f_pos - FIRST_PROCESS_ENTRY;
-
-       reaper = get_proc_task(filp->f_path.dentry->d_inode);
-       if (!reaper)
-               goto out_no_task;
-
-       for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) {
-               const struct pid_entry *p = &proc_base_stuff[nr];
-               if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
-                       goto out;
-       }
+               goto out;
 
        ns = filp->f_dentry->d_sb->s_fs_info;
        iter.task = NULL;
@@ -3006,8 +2839,6 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
        }
        filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET;
 out:
-       put_task_struct(reaper);
-out_no_task:
        return 0;
 }