diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-04-19 04:00:00 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-04-19 04:00:00 +0000 |
commit | 46e045034336a2cc90c1798cd7cc07af744ddfd6 (patch) | |
tree | 3b9b51fc482e729f663d25333e77fbed9aaa939a /fs/proc | |
parent | 31dc59d503a02e84c4de98826452acaeb56dc15a (diff) |
Merge with Linux 2.3.99-pre4.
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/array.c | 4 | ||||
-rw-r--r-- | fs/proc/base.c | 89 | ||||
-rw-r--r-- | fs/proc/generic.c | 4 | ||||
-rw-r--r-- | fs/proc/root.c | 6 |
4 files changed, 57 insertions, 46 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index 54e594634..63a1d5828 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -574,7 +574,9 @@ ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char * if (map->vm_file != NULL) { dev = map->vm_file->f_dentry->d_inode->i_dev; ino = map->vm_file->f_dentry->d_inode->i_ino; - line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE); + line = d_path(map->vm_file->f_dentry, + map->vm_file->f_vfsmnt, + buffer, PAGE_SIZE); buffer[PAGE_SIZE-1] = '\n'; line -= maxlen; if(line < buffer) diff --git a/fs/proc/base.c b/fs/proc/base.c index 4a191bfef..63bd4459b 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -38,22 +38,28 @@ int proc_pid_status(struct task_struct*,char*); int proc_pid_statm(struct task_struct*,char*); int proc_pid_cpu(struct task_struct*,char*); -static struct dentry *proc_fd_link(struct inode *inode) +/* MOUNT_REWRITE: make all files have non-NULL ->f_vfsmnt (pipefs, sockfs) */ +static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { - if (inode->u.proc_i.file) - return dget(inode->u.proc_i.file->f_dentry); - return NULL; + if (inode->u.proc_i.file) { + if (inode->u.proc_i.file->f_vfsmnt) { + *mnt = mntget(inode->u.proc_i.file->f_vfsmnt); + } + *dentry = dget(inode->u.proc_i.file->f_dentry); + return 0; + } + return -ENOENT; } -static struct dentry *proc_exe_link(struct inode *inode) +static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { struct mm_struct * mm; struct vm_area_struct * vma; - struct dentry *result = NULL; + int result = -ENOENT; struct task_struct *task = inode->u.proc_i.task; if (!task_lock(task)) - return NULL; + return result; mm = task->mm; if (!mm) goto out; @@ -62,7 +68,9 @@ static struct dentry *proc_exe_link(struct inode *inode) while (vma) { if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { - result = dget(vma->vm_file->f_dentry); + *mnt = mntget(vma->vm_file->f_vfsmnt); + *dentry = dget(vma->vm_file->f_dentry); + result = 0; break; } vma = vma->vm_next; @@ -73,25 +81,31 @@ out: return result; } -static struct dentry *proc_cwd_link(struct inode *inode) +static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { - struct dentry *result = NULL; + int result = -ENOENT; if (task_lock(inode->u.proc_i.task)) { struct fs_struct *fs = inode->u.proc_i.task->fs; - if (fs) - result = dget(fs->pwd); + if (fs) { + *mnt = mntget(fs->pwdmnt); + *dentry = dget(fs->pwd); + result = 0; + } task_unlock(inode->u.proc_i.task); } return result; } -static struct dentry *proc_root_link(struct inode *inode) +static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { - struct dentry *result = NULL; + int result = -ENOENT; if (task_lock(inode->u.proc_i.task)) { struct fs_struct *fs = inode->u.proc_i.task->fs; - if (fs) - result = dget(fs->root); + if (fs) { + *mnt = mntget(fs->rootmnt); + *dentry = dget(fs->root); + result = 0; + } task_unlock(inode->u.proc_i.task); } return result; @@ -160,16 +174,18 @@ static int proc_permission(struct inode *inode, int mask) { struct dentry *de, *base, *root; struct super_block *our_sb, *sb, *below; + struct vfsmount *our_vfsmnt, *vfsmnt, *mnt; if (standard_permission(inode, mask) != 0) return -EACCES; base = current->fs->root; - de = root = proc_root_link(inode); /* Ewww... */ - - if (!de) + our_vfsmnt = current->fs->rootmnt; + if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */ return -ENOENT; + de = root; + mnt = vfsmnt; our_sb = base->d_inode->i_sb; sb = de->d_inode->i_sb; while (sb != our_sb) { @@ -184,9 +200,11 @@ static int proc_permission(struct inode *inode, int mask) goto out; dput(root); + mntput(mnt); return 0; out: dput(root); + mntput(mnt); return -EACCES; } @@ -345,30 +363,26 @@ static struct inode_operations proc_mem_inode_operations = { permission: proc_permission, }; -static struct dentry * proc_pid_follow_link(struct dentry *dentry, - struct dentry *base, - unsigned int follow) +static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) { struct inode *inode = dentry->d_inode; - struct dentry * result; int error; /* We don't need a base pointer in the /proc filesystem */ - dput(base); + dput(nd->dentry); + mntput(nd->mnt); error = proc_permission(inode, MAY_EXEC); - result = ERR_PTR(error); if (error) goto out; - result = inode->u.proc_i.op.proc_get_link(inode); + error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt); out: - if (!result) - result = ERR_PTR(-ENOENT); - return result; + return error; } -static int do_proc_readlink(struct dentry *dentry, char * buffer, int buflen) +static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, + char * buffer, int buflen) { struct inode * inode; char * tmp = (char*)__get_free_page(GFP_KERNEL), *path, *pattern; @@ -391,7 +405,7 @@ static int do_proc_readlink(struct dentry *dentry, char * buffer, int buflen) len = sprintf(tmp, pattern, inode->i_ino); path = tmp; } else { - path = d_path(dentry, tmp, PAGE_SIZE); + path = d_path(dentry, mnt, tmp, PAGE_SIZE); len = tmp + PAGE_SIZE - 1 - path; } @@ -406,22 +420,19 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen) { int error; struct inode *inode = dentry->d_inode; + struct vfsmount *mnt; error = proc_permission(inode, MAY_EXEC); if (error) goto out; - dentry = inode->u.proc_i.op.proc_get_link(inode); - error = -ENOENT; - if (!dentry) - goto out; - - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) + error = inode->u.proc_i.op.proc_get_link(inode, &dentry, &mnt); + if (error) goto out; - error = do_proc_readlink(dentry, buffer, buflen); + error = do_proc_readlink(dentry, mnt, buffer, buflen); dput(dentry); + mntput(mnt); out: return error; } diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 28e0c08e5..4d6662780 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -201,10 +201,10 @@ static int proc_readlink(struct dentry *dentry, char *buffer, int buflen) return vfs_readlink(dentry, buffer, buflen, s); } -static struct dentry *proc_follow_link(struct dentry *dentry, struct dentry *base, unsigned flags) +static int proc_follow_link(struct dentry *dentry, struct nameidata *nd) { char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data; - return vfs_follow_link(dentry, base, flags, s); + return vfs_follow_link(nd, s); } static struct inode_operations proc_link_inode_operations = { diff --git a/fs/proc/root.c b/fs/proc/root.c index cce48d845..af01f0281 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -32,13 +32,11 @@ static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen) return vfs_readlink(dentry,buffer,buflen,tmp); } -static struct dentry * proc_self_follow_link(struct dentry *dentry, - struct dentry *base, - unsigned int follow) +static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) { char tmp[30]; sprintf(tmp, "%d", current->pid); - return vfs_follow_link(dentry,base,follow,tmp); + return vfs_follow_link(nd,tmp); } static struct inode_operations proc_self_inode_operations = { |