struct super_block *proc_read_super(struct super_block *s,void *data, int silent) { struct inode * root_inode; struct task_struct *p; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = PROC_SUPER_MAGIC; s->s_op = &proc_sops; s->s_maxbytes = ~0UL; root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); if (!root_inode) goto out_no_root; /* * Fixup the root inode's nlink value */ read_lock(&tasklist_lock); for_each_task(p) if (p->pid) root_inode->i_nlink++; read_unlock(&tasklist_lock); s->s_root = d_alloc_root(root_inode); if (!s->s_root) goto out_no_root; parse_options(data, &root_inode->i_uid, &root_inode->i_gid); return s; out_no_root: printk("proc_read_super: get root inode failed\n"); iput(root_inode); return NULL; }
int proc_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = PROC_SUPER_MAGIC; s->s_op = &proc_sops; s->s_time_gran = 1; root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); if (!root_inode) goto out_no_root; root_inode->i_uid = 0; root_inode->i_gid = 0; s->s_root = d_alloc_root(root_inode); if (!s->s_root) goto out_no_root; return 0; out_no_root: printk("proc_read_super: get root inode failed\n"); iput(root_inode); return -ENOMEM; }
/* * NOTE! Normally we'd indicate that a file does not * exist by creating a negative dentry and returning * a successful return code. However, for this case * we do not want to create negative dentries, because * the state of the world can change behind our backs. * * Thus just return -ENOENT instead. */ static int proc_lookupfd(struct inode * dir, struct dentry * dentry) { unsigned int ino, pid, fd, c; struct task_struct * p; struct file * file; struct inode *inode; const char *name; int len, err; err = -ENOENT; if (!dir) goto out; ino = dir->i_ino; pid = ino >> 16; ino &= 0x0000ffff; if (!pid || ino != PROC_PID_FD || !S_ISDIR(dir->i_mode)) goto out; fd = 0; len = dentry->d_name.len; name = dentry->d_name.name; while (len-- > 0) { c = *name - '0'; name++; if (c > 9) goto out; fd *= 10; fd += c; if (fd & 0xffff8000) goto out; } read_lock(&tasklist_lock); file = NULL; p = find_task_by_pid(pid); if (p) file = fcheck_task(p, fd); read_unlock(&tasklist_lock); /* * File handle is invalid if it is out of range, if the process * has no files (Zombie) if the file is closed, or if its inode * is NULL */ if (!file || !file->f_dentry) goto out; ino = (pid << 16) + PROC_PID_FD_DIR + fd; inode = proc_get_inode(dir->i_sb, ino, NULL); if (inode) { dentry->d_op = &proc_dentry_operations; d_add(dentry, inode); err = 0; } out: return err; }
/* * /proc/self: */ static int proc_self_followlink(struct inode * dir, struct inode * inode, int flag, int mode, struct inode ** res_inode) { iput(dir); *res_inode = proc_get_inode(inode->i_sb, (current->pid << 16) + PROC_PID_INO, &proc_pid); iput(inode); if (!*res_inode) return -ENOENT; return 0; }
struct super_block *proc_read_super(struct super_block *s,void *data, int silent) { proc_root_init(); lock_super(s); s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = PROC_SUPER_MAGIC; s->s_op = &proc_sops; unlock_super(s); if (!(s->s_mounted = proc_get_inode(s, PROC_ROOT_INO, &proc_root))) { s->s_dev = 0; printk("get root inode failed\n"); return NULL; } parse_options(data, &s->s_mounted->i_uid, &s->s_mounted->i_gid); return s; }
static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry) { struct proc_dir_entry *de; struct inode *inode = NULL; if ((de = (struct proc_dir_entry *) dir->u.generic_ip) != NULL) { for (de = de->subdir ; de ; de = de->next) { if ((de && de->low_ino) && (de->namelen == dentry->d_name.len) && (memcmp(dentry->d_name.name, de->name, de->namelen) == 0)) { if ((inode = proc_get_inode(dir->i_sb, de->low_ino, de)) == NULL) { printk(KERN_ERR "COMX: lookup error\n"); return ERR_PTR(-EINVAL); } break; } } } dentry->d_op = &comx_dentry_operations; d_add(dentry, inode); return NULL; }
static int proc_lookupfd(struct inode * dir, const char * name, int len, struct inode ** result) { unsigned int ino, pid, fd, c; struct task_struct * p; struct super_block * sb; int i; *result = NULL; ino = dir->i_ino; pid = ino >> 16; ino &= 0x0000ffff; if (!dir) return -ENOENT; sb = dir->i_sb; if (!pid || ino != PROC_PID_FD || !S_ISDIR(dir->i_mode)) { iput(dir); return -ENOENT; } if (!len || (name[0] == '.' && (len == 1 || (name[1] == '.' && len == 2)))) { if (len < 2) { *result = dir; return 0; } if (!(*result = proc_get_inode(sb, (pid << 16)+PROC_PID_INO, &proc_pid))) { iput(dir); return -ENOENT; } iput(dir); return 0; } iput(dir); fd = 0; if (len > 1 && *name == '0') fd = 0xfffff; else while (len-- > 0) { c = *name - '0'; name++; if (c > 9) { fd = 0xfffff; break; } fd *= 10; fd += c; if (fd & 0xffff0000) { fd = 0xfffff; break; } } for (i = 0 ; i < NR_TASKS ; i++) if ((p = task[i]) && p->pid == pid) break; if (!pid || i >= NR_TASKS) return -ENOENT; if (fd >= NR_OPEN || !p->files || !p->files->fd[fd] || !p->files->fd[fd]->f_inode) return -ENOENT; ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd; if (!(*result = proc_get_inode(sb, ino, NULL))) return -ENOENT; return 0; }