patch-2.1.44 linux/fs/proc/root.c
Next file: linux/fs/proc/scsi.c
Previous file: linux/fs/proc/procfs_syms.c
Back to the patch index
Back to the overall index
- Lines: 244
- Date:
Mon Jul 7 13:11:02 1997
- Orig file:
v2.1.43/linux/fs/proc/root.c
- Orig date:
Mon Jun 16 16:35:59 1997
diff -u --recursive --new-file v2.1.43/linux/fs/proc/root.c linux/fs/proc/root.c
@@ -24,7 +24,7 @@
#define FIRST_PROCESS_ENTRY 256
static int proc_root_readdir(struct inode *, struct file *, void *, filldir_t);
-static int proc_root_lookup(struct inode *,const char *,int,struct inode **);
+static int proc_root_lookup(struct inode *,struct qstr *,struct inode **);
static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
@@ -64,6 +64,7 @@
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
+ NULL, /* follow_link */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* bmap */
@@ -104,6 +105,7 @@
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
+ NULL, /* follow_link */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* bmap */
@@ -149,14 +151,14 @@
#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
static int (*proc_openprom_defreaddir_ptr)(struct inode *, struct file *, void *, filldir_t);
-static int (*proc_openprom_deflookup_ptr)(struct inode *, const char *, int, struct inode **);
+static int (*proc_openprom_deflookup_ptr)(struct inode *, struct qstr *, struct inode **);
void (*proc_openprom_use)(struct inode *, int) = 0;
static struct openpromfs_dev *proc_openprom_devices = NULL;
static ino_t proc_openpromdev_ino = PROC_OPENPROMD_FIRST;
struct inode_operations *
proc_openprom_register(int (*readdir)(struct inode *, struct file *, void *, filldir_t),
- int (*lookup)(struct inode *, const char *, int, struct inode **),
+ int (*lookup)(struct inode *, struct qstr *, struct inode **),
void (*use)(struct inode *, int),
struct openpromfs_dev ***devices)
{
@@ -218,14 +220,13 @@
}
static int
-proc_openprom_deflookup(struct inode * dir,const char * name, int len,
- struct inode ** result)
+proc_openprom_deflookup(struct inode * dir, struct qstr *str, struct inode ** result)
{
request_module("openpromfs");
if (proc_openprom_inode_operations.lookup !=
proc_openprom_deflookup)
return proc_openprom_inode_operations.lookup
- (dir, name, len, result);
+ (dir, str, result);
iput(dir);
return -ENOENT;
}
@@ -264,6 +265,7 @@
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
+ NULL, /* follow_link */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* bmap */
@@ -350,7 +352,6 @@
int len;
char tmp[30];
- iput(inode);
len = sprintf(tmp, "%d", current->pid);
if (buflen < len)
len = buflen;
@@ -358,6 +359,15 @@
return len;
}
+static struct dentry * proc_self_follow_link(struct inode *inode, struct dentry *base)
+{
+ int len;
+ char tmp[30];
+
+ len = sprintf(tmp, "%d", current->pid);
+ return lookup_dentry(tmp, base, 1);
+}
+
static struct inode_operations proc_self_inode_operations = {
NULL, /* no file-ops */
NULL, /* create */
@@ -370,6 +380,7 @@
NULL, /* mknod */
NULL, /* rename */
proc_self_readlink, /* readlink */
+ proc_self_follow_link, /* follow_link */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* bmap */
@@ -612,90 +623,41 @@
}
-int proc_match(int len,const char * name,struct proc_dir_entry * de)
-{
- if (!de || !de->low_ino)
- return 0;
- /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
- if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
- return 1;
- if (de->namelen != len)
- return 0;
- return !memcmp(name, de->name, len);
-}
-
-int proc_lookup(struct inode * dir,const char * name, int len,
- struct inode ** result)
+int proc_lookup(struct inode * dir, struct qstr * str, struct inode ** result)
{
struct proc_dir_entry * de;
- int ino;
*result = NULL;
- if (!dir || !S_ISDIR(dir->i_mode)) {
- iput(dir);
+ if (!dir || !S_ISDIR(dir->i_mode))
return -ENOTDIR;
- }
de = (struct proc_dir_entry *) dir->u.generic_ip;
- if (!de) {
- iput(dir);
+ if (!de)
return -EINVAL;
- }
-
- /* Either remove this as soon as possible due to security problems,
- * or uncomment the root-only usage.
- */
-
- /* Allow generic inode lookups everywhere.
- * No other name in /proc must begin with a '['.
- */
- if(/*!current->uid &&*/ name[0] == '[')
- return proc_arbitrary_lookup(dir,name,len,result);
- /* Special case "." and "..": they aren't on the directory list */
- *result = dir;
- if (!len)
- return 0;
- if (name[0] == '.') {
- if (len == 1)
- return 0;
- if (name[1] == '.' && len == 2) {
- struct inode * inode;
- inode = proc_get_inode(dir->i_sb, de->parent->low_ino, de->parent);
- iput(dir);
- if (!inode)
+ *result = NULL;
+ for (de = de->subdir; de ; de = de->next) {
+ if (!de || !de->low_ino)
+ continue;
+ if (de->namelen != str->len)
+ continue;
+ if (!memcmp(str->name, de->name, str->len)) {
+ int ino = de->low_ino | (dir->i_ino & ~(0xffff));
+ if (!(*result = proc_get_inode(dir->i_sb, ino, de)))
return -EINVAL;
- *result = inode;
return 0;
}
}
-
- *result = NULL;
- for (de = de->subdir; de ; de = de->next) {
- if (proc_match(len, name, de))
- break;
- }
- if (!de) {
- iput(dir);
- return -ENOENT;
- }
-
- ino = de->low_ino | (dir->i_ino & ~(0xffff));
-
- if (!(*result = proc_get_inode(dir->i_sb, ino, de))) {
- iput(dir);
- return -EINVAL;
- }
- iput(dir);
- return 0;
+ return -ENOENT;
}
-static int proc_root_lookup(struct inode * dir,const char * name, int len,
- struct inode ** result)
+static int proc_root_lookup(struct inode * dir,struct qstr *str, struct inode ** result)
{
unsigned int pid, c;
int ino, retval;
struct task_struct *p;
+ const char *name;
+ int len;
atomic_inc(&dir->i_count);
@@ -710,13 +672,13 @@
read_unlock(&tasklist_lock);
}
- retval = proc_lookup(dir, name, len, result);
- if (retval != -ENOENT) {
- iput(dir);
+ retval = proc_lookup(dir, str, result);
+ if (retval != -ENOENT)
return retval;
- }
pid = 0;
+ name = str->name;
+ len = str->len;
while (len-- > 0) {
c = *name - '0';
name++;
@@ -732,16 +694,12 @@
}
}
p = find_task_by_pid(pid);
- if (!pid || !p) {
- iput(dir);
+ if (!pid || !p)
return -ENOENT;
- }
+
ino = (pid << 16) + PROC_PID_INO;
- if (!(*result = proc_get_inode(dir->i_sb, ino, &proc_pid))) {
- iput(dir);
+ if (!(*result = proc_get_inode(dir->i_sb, ino, &proc_pid)))
return -EINVAL;
- }
- iput(dir);
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov