/*
       *  linux/fs/proc/base.c
       *
       *  Copyright (C) 1991, 1992 Linus Torvalds
       *
       *  proc base directory handling functions
       *
       *  1999, Al Viro. Rewritten. Now it covers the whole per-process part.
       *  Instead of using magical inumbers to determine the kind of object
       *  we allocate and fill in-core inodes upon lookup. They don't even
       *  go into icache. We cache the reference to task_struct upon lookup too.
       *  Eventually it should become a filesystem in its own. We don't use the
       *  rest of procfs anymore.
       */
      
      #include <asm/uaccess.h>
      
      #include <linux/config.h>
      #include <linux/errno.h>
      #include <linux/sched.h>
      #include <linux/proc_fs.h>
      #include <linux/stat.h>
      #include <linux/init.h>
      #include <linux/file.h>
      #include <linux/string.h>
      
      /*
       * For hysterical raisins we keep the same inumbers as in the old procfs.
       * Feel free to change the macro below - just keep the range distinct from
       * inumbers of the rest of procfs (currently those are in 0x0000--0xffff).
       * As soon as we'll get a separate superblock we will be able to forget
       * about magical ranges too.
       */
      
      #define fake_ino(pid,ino) (((pid)<<16)|(ino))
      
      ssize_t proc_pid_read_maps(struct task_struct*,struct file*,char*,size_t,loff_t*);
      int proc_pid_stat(struct task_struct*,char*);
      int proc_pid_status(struct task_struct*,char*);
      int proc_pid_statm(struct task_struct*,char*);
      int proc_pid_cpu(struct task_struct*,char*);
      
  43  static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
      {
  45  	if (inode->u.proc_i.file) {
      		*mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
      		*dentry = dget(inode->u.proc_i.file->f_dentry);
  48  		return 0;
      	}
  50  	return -ENOENT;
      }
      
  53  static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
      {
      	struct mm_struct * mm;
      	struct vm_area_struct * vma;
      	int result = -ENOENT;
      	struct task_struct *task = inode->u.proc_i.task;
      
      	task_lock(task);
      	mm = task->mm;
  62  	if (mm)
      		atomic_inc(&mm->mm_users);
      	task_unlock(task);
  65  	if (!mm)
  66  		goto out;
      	down(&mm->mmap_sem);
      	vma = mm->mmap;
  69  	while (vma) {
      		if ((vma->vm_flags & VM_EXECUTABLE) && 
  71  		    vma->vm_file) {
      			*mnt = mntget(vma->vm_file->f_vfsmnt);
      			*dentry = dget(vma->vm_file->f_dentry);
      			result = 0;
  75  			break;
      		}
      		vma = vma->vm_next;
      	}
      	up(&mm->mmap_sem);
      	mmput(mm);
      out:
  82  	return result;
      }
      
  85  static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
      {
      	struct fs_struct *fs;
      	int result = -ENOENT;
      	task_lock(inode->u.proc_i.task);
      	fs = inode->u.proc_i.task->fs;
  91  	if(fs)
      		atomic_inc(&fs->count);
      	task_unlock(inode->u.proc_i.task);
  94  	if (fs) {
      		read_lock(&fs->lock);
      		*mnt = mntget(fs->pwdmnt);
      		*dentry = dget(fs->pwd);
  98  		read_unlock(&fs->lock);
      		result = 0;
      		put_fs_struct(fs);
      	}
 102  	return result;
      }
      
 105  static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
      {
      	struct fs_struct *fs;
      	int result = -ENOENT;
      	task_lock(inode->u.proc_i.task);
      	fs = inode->u.proc_i.task->fs;
 111  	if(fs)
      		atomic_inc(&fs->count);
      	task_unlock(inode->u.proc_i.task);
 114  	if (fs) {
      		read_lock(&fs->lock);
      		*mnt = mntget(fs->rootmnt);
      		*dentry = dget(fs->root);
 118  		read_unlock(&fs->lock);
      		result = 0;
      		put_fs_struct(fs);
      	}
 122  	return result;
      }
      
 125  static int proc_pid_environ(struct task_struct *task, char * buffer)
      {
      	struct mm_struct *mm;
      	int res = 0;
      	task_lock(task);
      	mm = task->mm;
 131  	if (mm)
      		atomic_inc(&mm->mm_users);
      	task_unlock(task);
 134  	if (mm) {
      		int len = mm->env_end - mm->env_start;
 136  		if (len > PAGE_SIZE)
      			len = PAGE_SIZE;
      		res = access_process_vm(task, mm->env_start, buffer, len, 0);
      		mmput(mm);
      	}
 141  	return res;
      }
      
 144  static int proc_pid_cmdline(struct task_struct *task, char * buffer)
      {
      	struct mm_struct *mm;
      	int res = 0;
      	task_lock(task);
      	mm = task->mm;
 150  	if (mm)
      		atomic_inc(&mm->mm_users);
      	task_unlock(task);
 153  	if (mm) {
      		int len = mm->arg_end - mm->arg_start;
 155  		if (len > PAGE_SIZE)
      			len = PAGE_SIZE;
      		res = access_process_vm(task, mm->arg_start, buffer, len, 0);
      		// If the nul at the end of args has been overwritten, then
      		// assume application is using setproctitle(3).
 160  		if ( res > 0 && buffer[res-1] != '\0' )
      		{
      			len = strnlen( buffer, res );
 163  			if ( len < res )
      			{
      			    res = len;
      			}
 167  			else
      			{
      				len = mm->env_end - mm->env_start;
 170  				if (len > PAGE_SIZE - res)
      					len = PAGE_SIZE - res;
      				res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
      				res = strnlen( buffer, res );
      			}
      		}
      		mmput(mm);
      	}
 178  	return res;
      }
      
      /************************************************************************/
      /*                       Here the fs part begins                        */
      /************************************************************************/
      
      /* permission checks */
      
 187  static int standard_permission(struct inode *inode, int mask)
      {
      	int mode = inode->i_mode;
      
      	if ((mask & S_IWOTH) && IS_RDONLY(inode) &&
 192  	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 193  		return -EROFS; /* Nobody gets write access to a read-only fs */
 194  	else if ((mask & S_IWOTH) && IS_IMMUTABLE(inode))
 195  		return -EACCES; /* Nobody gets write access to an immutable file */
 196  	else if (current->fsuid == inode->i_uid)
      		mode >>= 6;
 198  	else if (in_group_p(inode->i_gid))
      		mode >>= 3;
 200  	if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
 201  		return 0;
      	/* read and search access */
      	if ((mask == S_IROTH) ||
 204  	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
 205  		if (capable(CAP_DAC_READ_SEARCH))
 206  			return 0;
 207  	return -EACCES;
      }
      
 210  static int proc_check_root(struct inode *inode)
      {
      	struct dentry *de, *base, *root;
      	struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
      	int res = 0;
      
 216  	if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
 217  		return -ENOENT;
      	read_lock(¤t->fs->lock);
      	our_vfsmnt = mntget(current->fs->rootmnt);
      	base = dget(current->fs->root);
 221  	read_unlock(¤t->fs->lock);
      
      	spin_lock(&dcache_lock);
      	de = root;
      	mnt = vfsmnt;
      
 227  	while (vfsmnt != our_vfsmnt) {
 228  		if (vfsmnt == vfsmnt->mnt_parent)
 229  			goto out;
      		de = vfsmnt->mnt_mountpoint;
      		vfsmnt = vfsmnt->mnt_parent;
      	}
      
 234  	if (!is_subdir(de, base))
 235  		goto out;
 236  	spin_unlock(&dcache_lock);
      
      exit:
      	dput(base);
      	mntput(our_vfsmnt);
      	dput(root);
      	mntput(mnt);
 243  	return res;
      out:
 245  	spin_unlock(&dcache_lock);
      	res = -EACCES;
 247  	goto exit;
      }
      
 250  static int proc_permission(struct inode *inode, int mask)
      {
 252  	if (standard_permission(inode, mask) != 0)
 253  		return -EACCES;
 254  	return proc_check_root(inode);
      }
      
 257  static ssize_t pid_maps_read(struct file * file, char * buf,
      			      size_t count, loff_t *ppos)
      {
      	struct inode * inode = file->f_dentry->d_inode;
      	struct task_struct *task = inode->u.proc_i.task;
      	ssize_t res;
      
      	res = proc_pid_read_maps(task, file, buf, count, ppos);
 265  	return res;
      }
      
      static struct file_operations proc_maps_operations = {
      	read:		pid_maps_read,
      };
      
      #define PROC_BLOCK_SIZE	(3*1024)		/* 4K page size but our output routines use some slack for overruns */
      
 274  static ssize_t proc_info_read(struct file * file, char * buf,
      			  size_t count, loff_t *ppos)
      {
      	struct inode * inode = file->f_dentry->d_inode;
      	unsigned long page;
      	ssize_t length;
      	ssize_t end;
      	struct task_struct *task = inode->u.proc_i.task;
      
 283  	if (count > PROC_BLOCK_SIZE)
      		count = PROC_BLOCK_SIZE;
 285  	if (!(page = __get_free_page(GFP_KERNEL)))
 286  		return -ENOMEM;
      
      	length = inode->u.proc_i.op.proc_read(task, (char*)page);
      
 290  	if (length < 0) {
      		free_page(page);
 292  		return length;
      	}
      	/* Static 4kB (or whatever) block capacity */
 295  	if (*ppos >= length) {
      		free_page(page);
 297  		return 0;
      	}
 299  	if (count + *ppos > length)
      		count = length - *ppos;
      	end = count + *ppos;
      	copy_to_user(buf, (char *) page + *ppos, count);
      	*ppos = end;
      	free_page(page);
 305  	return count;
      }
      
      static struct file_operations proc_info_file_operations = {
      	read:		proc_info_read,
      };
      
      #define MAY_PTRACE(p) \
      (p==current||(p->p_pptr==current&&(p->ptrace & PT_PTRACED)&&p->state==TASK_STOPPED))
      
 315  static ssize_t mem_read(struct file * file, char * buf,
      			size_t count, loff_t *ppos)
      {
      	struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
      	char *page;
      	unsigned long src = *ppos;
      	int copied = 0;
      
 323  	if (!MAY_PTRACE(task))
 324  		return -ESRCH;
      
      	page = (char *)__get_free_page(GFP_USER);
 327  	if (!page)
 328  		return -ENOMEM;
      
 330  	while (count > 0) {
      		int this_len, retval;
      
      		this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
      		retval = access_process_vm(task, src, page, this_len, 0);
 335  		if (!retval) {
 336  			if (!copied)
      				copied = -EIO;
 338  			break;
      		}
 340  		if (copy_to_user(buf, page, retval)) {
      			copied = -EFAULT;
 342  			break;
      		}
      		copied += retval;
      		src += retval;
      		buf += retval;
      		count -= retval;
      	}
      	*ppos = src;
      	free_page((unsigned long) page);
 351  	return copied;
      }
      
      #define mem_write NULL
      
      #ifndef mem_write
      /* This is a security hazard */
      static ssize_t mem_write(struct file * file, const char * buf,
      			 size_t count, loff_t *ppos)
      {
      	int copied = 0;
      	char *page;
      	struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
      	unsigned long dst = *ppos;
      
      	if (!MAY_PTRACE(task))
      		return -ESRCH;
      
      	page = (char *)__get_free_page(GFP_USER);
      	if (!page)
      		return -ENOMEM;
      
      	while (count > 0) {
      		int this_len, retval;
      
      		this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
      		if (copy_from_user(page, buf, this_len)) {
      			copied = -EFAULT;
      			break;
      		}
      		retval = access_process_vm(task, dst, page, this_len, 1);
      		if (!retval) {
      			if (!copied)
      				copied = -EIO;
      			break;
      		}
      		copied += retval;
      		buf += retval;
      		dst += retval;
      		count -= retval;			
      	}
      	*ppos = dst;
      	free_page((unsigned long) page);
      	return copied;
      }
      #endif
      
      static struct file_operations proc_mem_operations = {
      	read:		mem_read,
      	write:		mem_write,
      };
      
      static struct inode_operations proc_mem_inode_operations = {
      	permission:	proc_permission,
      };
      
 407  static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
      {
      	struct inode *inode = dentry->d_inode;
      	int error = -EACCES;
      
      	/* We don't need a base pointer in the /proc filesystem */
      	path_release(nd);
      
 415  	if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
 416  		goto out;
      	error = proc_check_root(inode);
 418  	if (error)
 419  		goto out;
      
      	error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
      	nd->last_type = LAST_BIND;
      out:
 424  	return error;
      }
      
 427  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;
      	int len;
      
 434  	if (!tmp)
 435  		return -ENOMEM;
      		
      	inode = dentry->d_inode;
      	path = d_path(dentry, mnt, tmp, PAGE_SIZE);
      	len = tmp + PAGE_SIZE - 1 - path;
      
 441  	if (len < buflen)
      		buflen = len;
      	copy_to_user(buffer, path, buflen);
      	free_page((unsigned long)tmp);
 445  	return buflen;
      }
      
 448  static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
      {
      	int error = -EACCES;
      	struct inode *inode = dentry->d_inode;
      	struct dentry *de;
      	struct vfsmount *mnt = NULL;
      
 455  	if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
 456  		goto out;
      	error = proc_check_root(inode);
 458  	if (error)
 459  		goto out;
      
      	error = inode->u.proc_i.op.proc_get_link(inode, &de, &mnt);
 462  	if (error)
 463  		goto out;
      
      	error = do_proc_readlink(de, mnt, buffer, buflen);
      	dput(de);
      	mntput(mnt);
      out:
 469  	return error;
      }
      
      static struct inode_operations proc_pid_link_inode_operations = {
      	readlink:	proc_pid_readlink,
      	follow_link:	proc_pid_follow_link
      };
      
      struct pid_entry {
      	int type;
      	int len;
      	char *name;
      	mode_t mode;
      };
      
      enum pid_directory_inos {
      	PROC_PID_INO = 2,
      	PROC_PID_STATUS,
      	PROC_PID_MEM,
      	PROC_PID_CWD,
      	PROC_PID_ROOT,
      	PROC_PID_EXE,
      	PROC_PID_FD,
      	PROC_PID_ENVIRON,
      	PROC_PID_CMDLINE,
      	PROC_PID_STAT,
      	PROC_PID_STATM,
      	PROC_PID_MAPS,
      	PROC_PID_CPU,
      	PROC_PID_FD_DIR = 0x8000,	/* 0x8000-0xffff */
      };
      
      #define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
      static struct pid_entry base_stuff[] = {
        E(PROC_PID_FD,	"fd",		S_IFDIR|S_IRUSR|S_IXUSR),
        E(PROC_PID_ENVIRON,	"environ",	S_IFREG|S_IRUSR),
        E(PROC_PID_STATUS,	"status",	S_IFREG|S_IRUGO),
        E(PROC_PID_CMDLINE,	"cmdline",	S_IFREG|S_IRUGO),
        E(PROC_PID_STAT,	"stat",		S_IFREG|S_IRUGO),
        E(PROC_PID_STATM,	"statm",	S_IFREG|S_IRUGO),
      #ifdef CONFIG_SMP
        E(PROC_PID_CPU,	"cpu",		S_IFREG|S_IRUGO),
      #endif
        E(PROC_PID_MAPS,	"maps",		S_IFREG|S_IRUGO),
        E(PROC_PID_MEM,	"mem",		S_IFREG|S_IRUSR|S_IWUSR),
        E(PROC_PID_CWD,	"cwd",		S_IFLNK|S_IRWXUGO),
        E(PROC_PID_ROOT,	"root",		S_IFLNK|S_IRWXUGO),
        E(PROC_PID_EXE,	"exe",		S_IFLNK|S_IRWXUGO),
        {0,0,NULL,0}
      };
      #undef E
      
      #define NUMBUF 10
      
 523  static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
      {
      	struct inode *inode = filp->f_dentry->d_inode;
      	struct task_struct *p = inode->u.proc_i.task;
      	unsigned int fd, pid, ino;
      	int retval;
      	char buf[NUMBUF];
      	struct files_struct * files;
      
      	retval = 0;
      	pid = p->pid;
      
      	fd = filp->f_pos;
 536  	switch (fd) {
 537  		case 0:
 538  			if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
 539  				goto out;
      			filp->f_pos++;
 541  		case 1:
      			ino = fake_ino(pid, PROC_PID_INO);
 543  			if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
 544  				goto out;
      			filp->f_pos++;
 546  		default:
      			task_lock(p);
      			files = p->files;
 549  			if (files)
      				atomic_inc(&files->count);
      			task_unlock(p);
 552  			if (!files)
 553  				goto out;
      			for (fd = filp->f_pos-2;
 555  			     fd < files->max_fds;
      			     fd++, filp->f_pos++) {
      				unsigned int i,j;
      
 559  				if (!fcheck_files(files, fd))
 560  					continue;
      
      				j = NUMBUF;
      				i = fd;
 564  				do {
      					j--;
      					buf[j] = '0' + (i % 10);
      					i /= 10;
 568  				} while (i);
      
      				ino = fake_ino(pid, PROC_PID_FD_DIR + fd);
 571  				if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0)
 572  					break;
      			}
      			put_files_struct(files);
      	}
      out:
 577  	return retval;
      }
      
 580  static int proc_base_readdir(struct file * filp,
      	void * dirent, filldir_t filldir)
      {
      	int i;
      	int pid;
      	struct inode *inode = filp->f_dentry->d_inode;
      	struct pid_entry *p;
      
      	pid = inode->u.proc_i.task->pid;
 589  	if (!inode->u.proc_i.task->p_pptr)
 590  		return -ENOENT;
      	i = filp->f_pos;
 592  	switch (i) {
 593  		case 0:
 594  			if (filldir(dirent, ".", 1, i, inode->i_ino, DT_DIR) < 0)
 595  				return 0;
      			i++;
      			filp->f_pos++;
      			/* fall through */
 599  		case 1:
 600  			if (filldir(dirent, "..", 2, i, PROC_ROOT_INO, DT_DIR) < 0)
 601  				return 0;
      			i++;
      			filp->f_pos++;
      			/* fall through */
 605  		default:
      			i -= 2;
 607  			if (i>=sizeof(base_stuff)/sizeof(base_stuff[0]))
 608  				return 1;
      			p = base_stuff + i;
 610  			while (p->name) {
      				if (filldir(dirent, p->name, p->len, filp->f_pos,
 612  					    fake_ino(pid, p->type), p->mode >> 12) < 0)
 613  					return 0;
      				filp->f_pos++;
      				p++;
      			}
      	}
 618  	return 1;
      }
      
      /* building an inode */
      
 623  static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
      {
      	struct inode * inode;
      
      	/* We need a new inode */
      	
      	inode = new_inode(sb);
 630  	if (!inode)
 631  		goto out;
      
      	/* Common stuff */
      
      	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
      	inode->i_ino = fake_ino(task->pid, ino);
      
      	inode->u.proc_i.file = NULL;
      	/*
      	 * grab the reference to task.
      	 */
      	inode->u.proc_i.task = task;
      	get_task_struct(task);
 644  	if (!task->p_pptr)
 645  		goto out_unlock;
      
      	inode->i_uid = 0;
      	inode->i_gid = 0;
 649  	if (ino == PROC_PID_INO || task->dumpable) {
      		inode->i_uid = task->euid;
      		inode->i_gid = task->egid;
      	}
      
      out:
 655  	return inode;
      
      out_unlock:
      	iput(inode);
 659  	return NULL;
      }
      
      /* dentry stuff */
      
 664  static int pid_fd_revalidate(struct dentry * dentry, int flags)
      {
 666  	return 0;
      }
      
      /*
       *	Exceptional case: normally we are not allowed to unhash a busy
       * directory. In this case, however, we can do it - no aliasing problems
       * due to the way we treat inodes.
       */
 674  static int pid_base_revalidate(struct dentry * dentry, int flags)
      {
 676  	if (dentry->d_inode->u.proc_i.task->p_pptr)
 677  		return 1;
      	d_drop(dentry);
 679  	return 0;
      }
      
 682  static int pid_delete_dentry(struct dentry * dentry)
      {
 684  	return 1;
      }
      
      static struct dentry_operations pid_fd_dentry_operations =
      {
      	d_revalidate:	pid_fd_revalidate,
      	d_delete:	pid_delete_dentry,
      };
      
      static struct dentry_operations pid_dentry_operations =
      {
      	d_delete:	pid_delete_dentry,
      };
      
      static struct dentry_operations pid_base_dentry_operations =
      {
      	d_revalidate:	pid_base_revalidate,
      	d_delete:	pid_delete_dentry,
      };
      
      /* Lookups */
      #define MAX_MULBY10	((~0U-9)/10)
      
 707  static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
      {
      	unsigned int fd, c;
      	struct task_struct *task = dir->u.proc_i.task;
      	struct file * file;
      	struct files_struct * files;
      	struct inode *inode;
      	const char *name;
      	int len;
      
      	fd = 0;
      	len = dentry->d_name.len;
      	name = dentry->d_name.name;
 720  	if (len > 1 && *name == '0') goto out;
 721  	while (len-- > 0) {
      		c = *name - '0';
      		name++;
 724  		if (c > 9)
 725  			goto out;
 726  		if (fd >= MAX_MULBY10)
 727  			goto out;
      		fd *= 10;
      		fd += c;
      	}
      
      	inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
 733  	if (!inode)
 734  		goto out;
      	task_lock(task);
      	files = task->files;
 737  	if (files)
      		atomic_inc(&files->count);
      	task_unlock(task);
 740  	if (!files)
 741  		goto out_unlock;
      	read_lock(&files->file_lock);
      	file = inode->u.proc_i.file = fcheck_files(files, fd);
 744  	if (!file)
 745  		goto out_unlock2;
      	get_file(file);
 747  	read_unlock(&files->file_lock);
      	put_files_struct(files);
      	inode->i_op = &proc_pid_link_inode_operations;
      	inode->i_size = 64;
      	inode->i_mode = S_IFLNK;
      	inode->u.proc_i.op.proc_get_link = proc_fd_link;
 753  	if (file->f_mode & 1)
      		inode->i_mode |= S_IRUSR | S_IXUSR;
 755  	if (file->f_mode & 2)
      		inode->i_mode |= S_IWUSR | S_IXUSR;
      	dentry->d_op = &pid_fd_dentry_operations;
      	d_add(dentry, inode);
 759  	return NULL;
      
      out_unlock2:
      	put_files_struct(files);
 763  	read_unlock(&files->file_lock);
      out_unlock:
      	iput(inode);
      out:
 767  	return ERR_PTR(-ENOENT);
      }
      
      static struct file_operations proc_fd_operations = {
      	read:		generic_read_dir,
      	readdir:	proc_readfd,
      };
      
      /*
       * proc directories can do almost nothing..
       */
      static struct inode_operations proc_fd_inode_operations = {
      	lookup:		proc_lookupfd,
      	permission:	proc_permission,
      };
      
 783  static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
      {
      	struct inode *inode;
      	int error;
      	struct task_struct *task = dir->u.proc_i.task;
      	struct pid_entry *p;
      
      	error = -ENOENT;
      	inode = NULL;
      
 793  	for (p = base_stuff; p->name; p++) {
 794  		if (p->len != dentry->d_name.len)
 795  			continue;
 796  		if (!memcmp(dentry->d_name.name, p->name, p->len))
 797  			break;
      	}
 799  	if (!p->name)
 800  		goto out;
      
      	error = -EINVAL;
      	inode = proc_pid_make_inode(dir->i_sb, task, p->type);
 804  	if (!inode)
 805  		goto out;
      
      	inode->i_mode = p->mode;
      	/*
      	 * Yes, it does not scale. And it should not. Don't add
      	 * new entries into /proc/<pid>/ without very good reasons.
      	 */
 812  	switch(p->type) {
 813  		case PROC_PID_FD:
      			inode->i_nlink = 2;
      			inode->i_op = &proc_fd_inode_operations;
      			inode->i_fop = &proc_fd_operations;
 817  			break;
 818  		case PROC_PID_EXE:
      			inode->i_op = &proc_pid_link_inode_operations;
      			inode->u.proc_i.op.proc_get_link = proc_exe_link;
 821  			break;
 822  		case PROC_PID_CWD:
      			inode->i_op = &proc_pid_link_inode_operations;
      			inode->u.proc_i.op.proc_get_link = proc_cwd_link;
 825  			break;
 826  		case PROC_PID_ROOT:
      			inode->i_op = &proc_pid_link_inode_operations;
      			inode->u.proc_i.op.proc_get_link = proc_root_link;
 829  			break;
 830  		case PROC_PID_ENVIRON:
      			inode->i_fop = &proc_info_file_operations;
      			inode->u.proc_i.op.proc_read = proc_pid_environ;
 833  			break;
 834  		case PROC_PID_STATUS:
      			inode->i_fop = &proc_info_file_operations;
      			inode->u.proc_i.op.proc_read = proc_pid_status;
 837  			break;
 838  		case PROC_PID_STAT:
      			inode->i_fop = &proc_info_file_operations;
      			inode->u.proc_i.op.proc_read = proc_pid_stat;
 841  			break;
 842  		case PROC_PID_CMDLINE:
      			inode->i_fop = &proc_info_file_operations;
      			inode->u.proc_i.op.proc_read = proc_pid_cmdline;
 845  			break;
 846  		case PROC_PID_STATM:
      			inode->i_fop = &proc_info_file_operations;
      			inode->u.proc_i.op.proc_read = proc_pid_statm;
 849  			break;
 850  		case PROC_PID_MAPS:
      			inode->i_fop = &proc_maps_operations;
 852  			break;
      #ifdef CONFIG_SMP
      		case PROC_PID_CPU:
      			inode->i_fop = &proc_info_file_operations;
      			inode->u.proc_i.op.proc_read = proc_pid_cpu;
      			break;
      #endif
 859  		case PROC_PID_MEM:
      			inode->i_op = &proc_mem_inode_operations;
      			inode->i_fop = &proc_mem_operations;
 862  			break;
 863  		default:
      			printk("procfs: impossible type (%d)",p->type);
      			iput(inode);
 866  			return ERR_PTR(-EINVAL);
      	}
      	dentry->d_op = &pid_dentry_operations;
      	d_add(dentry, inode);
 870  	return NULL;
      
      out:
 873  	return ERR_PTR(error);
      }
      
      static struct file_operations proc_base_operations = {
      	read:		generic_read_dir,
      	readdir:	proc_base_readdir,
      };
      
      static struct inode_operations proc_base_inode_operations = {
      	lookup:		proc_base_lookup,
      };
      
      /*
       * /proc/self:
       */
 888  static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
      {
      	char tmp[30];
      	sprintf(tmp, "%d", current->pid);
 892  	return vfs_readlink(dentry,buffer,buflen,tmp);
      }
      
 895  static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
      {
      	char tmp[30];
      	sprintf(tmp, "%d", current->pid);
 899  	return vfs_follow_link(nd,tmp);
      }	
      
      static struct inode_operations proc_self_inode_operations = {
      	readlink:	proc_self_readlink,
      	follow_link:	proc_self_follow_link,
      };
      
 907  struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
      {
      	unsigned int pid, c;
      	struct task_struct *task;
      	const char *name;
      	struct inode *inode;
      	int len;
      
      	pid = 0;
      	name = dentry->d_name.name;
      	len = dentry->d_name.len;
 918  	if (len == 4 && !memcmp(name, "self", 4)) {
      		inode = new_inode(dir->i_sb);
 920  		if (!inode)
 921  			return ERR_PTR(-ENOMEM);
      		inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
      		inode->i_ino = fake_ino(0, PROC_PID_INO);
      		inode->u.proc_i.file = NULL;
      		inode->u.proc_i.task = NULL;
      		inode->i_mode = S_IFLNK|S_IRWXUGO;
      		inode->i_uid = inode->i_gid = 0;
      		inode->i_size = 64;
      		inode->i_op = &proc_self_inode_operations;
      		d_add(dentry, inode);
 931  		return NULL;
      	}
 933  	while (len-- > 0) {
      		c = *name - '0';
      		name++;
 936  		if (c > 9)
 937  			goto out;
 938  		if (pid >= MAX_MULBY10)
 939  			goto out;
      		pid *= 10;
      		pid += c;
 942  		if (!pid)
 943  			goto out;
      	}
      
      	read_lock(&tasklist_lock);
      	task = find_task_by_pid(pid);
 948  	if (task)
      		get_task_struct(task);
 950  	read_unlock(&tasklist_lock);
 951  	if (!task)
 952  		goto out;
      
      	inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
      
      	free_task_struct(task);
      
 958  	if (!inode)
 959  		goto out;
      	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
      	inode->i_op = &proc_base_inode_operations;
      	inode->i_fop = &proc_base_operations;
      	inode->i_nlink = 3;
      	inode->i_flags|=S_IMMUTABLE;
      
      	dentry->d_op = &pid_base_dentry_operations;
      	d_add(dentry, inode);
 968  	return NULL;
      out:
 970  	return ERR_PTR(-ENOENT);
      }
      
 973  void proc_pid_delete_inode(struct inode *inode)
      {
 975  	if (inode->u.proc_i.file)
      		fput(inode->u.proc_i.file);
 977  	if (inode->u.proc_i.task)
      		free_task_struct(inode->u.proc_i.task);
      }
      
      #define PROC_NUMBUF 10
      #define PROC_MAXPIDS 20
      
      /*
       * Get a few pid's to return for filldir - we need to hold the
       * tasklist lock while doing this, and we must release it before
       * we actually do the filldir itself, so we use a temp buffer..
       */
 989  static int get_pid_list(int index, unsigned int *pids)
      {
      	struct task_struct *p;
      	int nr_pids = 0;
      
      	index--;
      	read_lock(&tasklist_lock);
 996  	for_each_task(p) {
      		int pid = p->pid;
 998  		if (!pid)
 999  			continue;
1000  		if (--index >= 0)
1001  			continue;
      		pids[nr_pids] = pid;
      		nr_pids++;
1004  		if (nr_pids >= PROC_MAXPIDS)
1005  			break;
      	}
1007  	read_unlock(&tasklist_lock);
1008  	return nr_pids;
      }
      
1011  int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
      {
      	unsigned int pid_array[PROC_MAXPIDS];
      	char buf[PROC_NUMBUF];
      	unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
      	unsigned int nr_pids, i;
      
1018  	if (!nr) {
      		ino_t ino = fake_ino(0,PROC_PID_INO);
1020  		if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0)
1021  			return 0;
      		filp->f_pos++;
      		nr++;
      	}
      
      	nr_pids = get_pid_list(nr, pid_array);
      
1028  	for (i = 0; i < nr_pids; i++) {
      		int pid = pid_array[i];
      		ino_t ino = fake_ino(pid,PROC_PID_INO);
      		unsigned long j = PROC_NUMBUF;
      
1033  		do buf[--j] = '0' + (pid % 10); while (pid/=10);
      
1035  		if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino, DT_DIR) < 0)
1036  			break;
      		filp->f_pos++;
      	}
1039  	return 0;
      }