patch-2.4.0-test3 linux/fs/proc/base.c

Next file: linux/fs/proc/proc_misc.c
Previous file: linux/fs/proc/array.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test2/linux/fs/proc/base.c linux/fs/proc/base.c
@@ -40,18 +40,9 @@
 int proc_pid_statm(struct task_struct*,char*);
 int proc_pid_cpu(struct task_struct*,char*);
 
-/* MOUNT_REWRITE: make all files have non-NULL ->f_vfsmnt (pipefs, sockfs) */
-/* Until then... */
-#define NULL_VFSMNT	/* remove as soon as pipefs and sockfs will be there */
-
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
 	if (inode->u.proc_i.file) {
-#ifdef NULL_VFSMNT
-		if (!inode->u.proc_i.file->f_vfsmnt)
-			mntget(*mnt);
-		else
-#endif
 		*mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
 		*dentry = dget(inode->u.proc_i.file->f_dentry);
 		return 0;
@@ -101,8 +92,10 @@
 		atomic_inc(&fs->count);
 	task_unlock(inode->u.proc_i.task);
 	if (fs) {
+		read_lock(&fs->lock);
 		*mnt = mntget(fs->pwdmnt);
 		*dentry = dget(fs->pwd);
+		read_unlock(&fs->lock);
 		result = 0;
 		put_fs_struct(fs);
 	}
@@ -119,8 +112,10 @@
 		atomic_inc(&fs->count);
 	task_unlock(inode->u.proc_i.task);
 	if (fs) {
+		read_lock(&fs->lock);
 		*mnt = mntget(fs->rootmnt);
 		*dentry = dget(fs->root);
+		read_unlock(&fs->lock);
 		result = 0;
 		put_fs_struct(fs);
 	}
@@ -216,15 +211,19 @@
 {
 	struct dentry *de, *base, *root;
 	struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
+	int res = 0;
 
 	if (standard_permission(inode, mask) != 0)
 		return -EACCES;
 
-	base = current->fs->root;
-	our_vfsmnt = current->fs->rootmnt;
 	if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
 		return -ENOENT;
+	read_lock(&current->fs->lock);
+	our_vfsmnt = mntget(current->fs->rootmnt);
+	base = dget(current->fs->root);
+	read_unlock(&current->fs->lock);
 
+	spin_lock(&dcache_lock);
 	de = root;
 	mnt = vfsmnt;
 
@@ -237,14 +236,18 @@
 
 	if (!is_subdir(de, base))
 		goto out;
+	spin_unlock(&dcache_lock);
 
+exit:
+	dput(base);
+	mntput(our_vfsmnt);
 	dput(root);
 	mntput(mnt);
-	return 0;
+	return res;
 out:
-	dput(root);
-	mntput(mnt);
-	return -EACCES;
+	spin_unlock(&dcache_lock);
+	res = -EACCES;
+	goto exit;
 }
 
 static ssize_t pid_maps_read(struct file * file, char * buf,
@@ -396,9 +399,6 @@
 {
 	struct inode *inode = dentry->d_inode;
 	int error;
-#ifdef NULL_VFSMNT
-	struct vfsmount *dummy = mntget(nd->mnt);
-#endif
 
 	/* We don't need a base pointer in the /proc filesystem */
 	path_release(nd);
@@ -408,10 +408,8 @@
 		goto out;
 
 	error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
+	nd->last_type = LAST_BIND;
 out:
-#ifdef NULL_VFSMNT
-	mntput(dummy);
-#endif
 	return error;
 }
 
@@ -419,29 +417,15 @@
 			    char * buffer, int buflen)
 {
 	struct inode * inode;
-	char * tmp = (char*)__get_free_page(GFP_KERNEL), *path, *pattern;
+	char * tmp = (char*)__get_free_page(GFP_KERNEL), *path;
 	int len;
 
 	if (!tmp)
 		return -ENOMEM;
 		
-	/* Check for special dentries.. */
-	pattern = NULL;
 	inode = dentry->d_inode;
-	if (inode && IS_ROOT(dentry)) {
-		if (S_ISSOCK(inode->i_mode))
-			pattern = "socket:[%lu]";
-		if (S_ISFIFO(inode->i_mode))
-			pattern = "pipe:[%lu]";
-	}
-	
-	if (pattern) {
-		len = sprintf(tmp, pattern, inode->i_ino);
-		path = tmp;
-	} else {
-		path = d_path(dentry, mnt, tmp, PAGE_SIZE);
-		len = tmp + PAGE_SIZE - 1 - path;
-	}
+	path = d_path(dentry, mnt, tmp, PAGE_SIZE);
+	len = tmp + PAGE_SIZE - 1 - path;
 
 	if (len < buflen)
 		buflen = len;
@@ -706,6 +690,7 @@
 };
 
 /* Lookups */
+#define MAX_MULBY10	((~0U-9)/10)
 
 static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
 {
@@ -726,10 +711,10 @@
 		name++;
 		if (c > 9)
 			goto out;
+		if (fd >= MAX_MULBY10)
+			goto out;
 		fd *= 10;
 		fd += c;
-		if (fd & 0xffff8000)
-			goto out;
 	}
 
 	inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
@@ -940,11 +925,11 @@
 		name++;
 		if (c > 9)
 			goto out;
+		if (pid >= MAX_MULBY10)
+			goto out;
 		pid *= 10;
 		pid += c;
 		if (!pid)
-			goto out;
-		if (pid & 0xffff0000)
 			goto out;
 	}
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)