patch-2.3.99-pre4 linux/fs/proc/base.c
Next file: linux/fs/proc/generic.c
Previous file: linux/fs/proc/array.c
Back to the patch index
Back to the overall index
- Lines: 196
- Date:
Fri Apr 7 13:38:00 2000
- Orig file:
v2.3.99-pre3/linux/fs/proc/base.c
- Orig date:
Tue Mar 7 14:32:26 2000
diff -u --recursive --new-file v2.3.99-pre3/linux/fs/proc/base.c linux/fs/proc/base.c
@@ -38,22 +38,28 @@
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 @@
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 @@
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 @@
{
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 @@
goto out;
dput(root);
+ mntput(mnt);
return 0;
out:
dput(root);
+ mntput(mnt);
return -EACCES;
}
@@ -345,30 +363,26 @@
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 @@
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 @@
{
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;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)