summaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-04-19 04:00:00 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-04-19 04:00:00 +0000
commit46e045034336a2cc90c1798cd7cc07af744ddfd6 (patch)
tree3b9b51fc482e729f663d25333e77fbed9aaa939a /fs/proc
parent31dc59d503a02e84c4de98826452acaeb56dc15a (diff)
Merge with Linux 2.3.99-pre4.
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c4
-rw-r--r--fs/proc/base.c89
-rw-r--r--fs/proc/generic.c4
-rw-r--r--fs/proc/root.c6
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 = {