示例#1
0
/**
 *  cdev_open: - open a character special device node
 *  @inode: the character device inode
 *  @file: the user file pointer
 *
 *  cdev_open() is only used to open a stream from a character device node in an external
 *  filesystem.  This is never called for direct opens of a specfs device node (for direct opens see
 *  spec_dev_open() in strspecfs.c).  It is also not used for direct opens of fifos, pipes or
 *  sockets.  Those devices provide their own file operations to the main operating system.  The
 *  character device number from the inode is used to determine the shadow special file system
 *  (internal) inode and chain the open call.
 *
 *  This is the separation point where we convert the external device number to an internal device
 *  number.  The external device number is contained in inode->i_rdev.
 *
 *  @inode is the inode in the external filesystem.
 *
 *  @file->f_op is the external file operations (character device, fifo) and must be replaced with
 *	our file operations.
 *
 *  @file->f_dentry is the external filesystem dentry for the device node.
 *  @file->f_vfsmnt is the external filesystem vfsmnt for the device node.
 *  @file exists on the file->f_dentry->d_inode->i_sb->s_files list.
 *
 *  What we should be doing here is get a fresh new dentry.  Find our inode from the device number,
 *  add it to the dentry.  Set the dentry->d_sb to the specfs super block, set dentry->d_parent =
 *  dget(file->f_dentry->d_parent), but do not add the dentry to the child list on the parent
 *  directory, nor do we hash the dentry.  Next we do a dentry open on the on the dentry and a file
 *  pointer swap on return.
 *
 *  Instead of farting around with dentries and such, just lookup the inode in the specfs replace
 *  the file->f_ops and chain the open with the specfs inode passed to the new open procedure.  For
 *  FIFOs we pass the external filesystem inode instead.
 */
STATIC int
cdev_open(struct inode *inode, struct file *file)
{
	int err;
	struct cdevsw *cdev;
	struct devnode *cmin;
	major_t major;
	minor_t minor;
	modID_t modid;
	dev_t dev;
	int sflag;

#if defined HAVE_KFUNC_TO_KDEV_T
	minor = MINOR(kdev_t_to_nr(inode->i_rdev));
	major = MAJOR(kdev_t_to_nr(inode->i_rdev));
#else
	minor = MINOR(inode->i_rdev);
	major = MAJOR(inode->i_rdev);
#endif
	if (!(cdev = sdev_get(major))) {
		return (-ENXIO);
	}
	minor = cdev_minor(cdev, major, minor);
	major = cdev->d_major;
	modid = cdev->d_modid;
	dev = makedevice(modid, minor);
	sflag = DRVOPEN;
	if (cdev->d_flag & D_CLONE)
		sflag = CLONEOPEN;
	else if ((cmin = cmin_get(cdev, minor)) && cmin->n_flag & D_CLONE)
		sflag = CLONEOPEN;
	err = spec_open(file, cdev, dev, sflag);
	sdev_put(cdev);
	return (err);
}
示例#2
0
/*
 *  clone_open: - open a clone device node
 *  @inode: the external filesystem inode
 *  @file: the external filesystem file pointer
 *
 *  clone_open() is only used to open a clone device from a character device node in an external
 *  filesystem.  This is never called for direct opens of a specfs device node (for direct opens see
 *  spec_dev_open() in strspecfs.c).  The character device number from the inode is used to
 *  determine the shadow special filesystem (internal) inode and chain the open call.
 *
 *  This is the separation point where we convert the external device number to an internal device
 *  number.  The external device number is contained in inode->i_rdev.
 */
STATIC int
clone_open(struct inode *inode, struct file *file)
{
	int err;
	struct cdevsw *cdev;
	major_t major;
	minor_t minor;
	modID_t modid, instance;

#if defined HAVE_KFUNC_TO_KDEV_T
	minor = MINOR(kdev_t_to_nr(inode->i_rdev));
	major = MAJOR(kdev_t_to_nr(inode->i_rdev));
#else
	minor = MINOR(inode->i_rdev);
	major = MAJOR(inode->i_rdev);
#endif
	minor = cdev_minor(&clone_cdev, major, minor);
	major = clone_cdev.d_major;
	modid = clone_cdev.d_modid;
	err = -ENXIO;
	if (!(cdev = sdev_get(minor))) {
		goto exit;
	}
	instance = cdev->d_modid;
	err = spec_open(file, cdev, makedevice(modid, instance), CLONEOPEN);
	sdev_put(cdev);
      exit:
	return (err);
}
示例#3
0
/*
 * For backward compatibility?  Maybe this should be moved
 * into arch/i386 instead?
 */
static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
{
	static int warncount = 5;
	struct __old_kernel_stat tmp;
	int retval;

	if ((retval = security_inode_stat(inode)))
		return retval;

	if (warncount > 0) {
		warncount--;
		printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
			current->comm);
	} else if (warncount < 0) {
		/* it's laughable, but... */
		warncount = 0;
	}

	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
	tmp.st_ino = inode->i_ino;
	tmp.st_mode = inode->i_mode;
	tmp.st_nlink = inode->i_nlink;
	SET_OLDSTAT_UID(tmp, inode->i_uid);
	SET_OLDSTAT_GID(tmp, inode->i_gid);
	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
#if BITS_PER_LONG == 32
	if (inode->i_size > MAX_NON_LFS)
		return -EOVERFLOW;
#endif	
	tmp.st_size = inode->i_size;
	tmp.st_atime = inode->i_atime;
	tmp.st_mtime = inode->i_mtime;
	tmp.st_ctime = inode->i_ctime;
	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
示例#4
0
static inline u32 *
encode_fattr(struct svc_rqst *rqstp, u32 *p, struct inode *inode)
{
	int type = (inode->i_mode & S_IFMT);

	*p++ = htonl(nfs_ftypes[type >> 12]);
	*p++ = htonl((u32) inode->i_mode);
	*p++ = htonl((u32) inode->i_nlink);
	*p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid));
	*p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid));

	if (S_ISLNK(type) && inode->i_size > NFS_MAXPATHLEN) {
		*p++ = htonl(NFS_MAXPATHLEN);
	} else {
		*p++ = htonl((u32) inode->i_size);
	}
	*p++ = htonl((u32) inode->i_blksize);
	if (S_ISCHR(type) || S_ISBLK(type))
		*p++ = htonl((u32) kdev_t_to_nr(inode->i_rdev));
	else
		*p++ = htonl(0xffffffff);
	*p++ = htonl((u32) inode->i_blocks);
	*p++ = htonl((u32) kdev_t_to_nr(inode->i_dev));
	*p++ = htonl((u32) inode->i_ino);
	*p++ = htonl((u32) inode->i_atime);
	*p++ = 0;
	*p++ = htonl((u32) lease_get_mtime(inode));
	*p++ = 0;
	*p++ = htonl((u32) inode->i_ctime);
	*p++ = 0;

	return p;
}
示例#5
0
文件: stat.c 项目: dmgerman/original
static int cp_new_stat(struct inode * inode, struct stat * statbuf)
{
	struct stat tmp;
	unsigned int blocks, indirect;

	memset(&tmp, 0, sizeof(tmp));
	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
	tmp.st_ino = inode->i_ino;
	tmp.st_mode = inode->i_mode;
	tmp.st_nlink = inode->i_nlink;
	SET_STAT_UID(tmp, inode->i_uid);
	SET_STAT_GID(tmp, inode->i_gid);
	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
#if BITS_PER_LONG == 32
	if (inode->i_size > 0x7fffffff)
		return -EOVERFLOW;
#endif	
	tmp.st_size = inode->i_size;
	tmp.st_atime = inode->i_atime;
	tmp.st_mtime = inode->i_mtime;
	tmp.st_ctime = inode->i_ctime;
/*
 * st_blocks and st_blksize are approximated with a simple algorithm if
 * they aren't supported directly by the filesystem. The minix and msdos
 * filesystems don't keep track of blocks, so they would either have to
 * be counted explicitly (by delving into the file itself), or by using
 * this simple algorithm to get a reasonable (although not 100% accurate)
 * value.
 */

/*
 * Use minix fs values for the number of direct and indirect blocks.  The
 * count is now exact for the minix fs except that it counts zero blocks.
 * Everything is in units of BLOCK_SIZE until the assignment to
 * tmp.st_blksize.
 */
#define D_B   7
#define I_B   (BLOCK_SIZE / sizeof(unsigned short))

	if (!inode->i_blksize) {
		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
		if (blocks > D_B) {
			indirect = (blocks - D_B + I_B - 1) / I_B;
			blocks += indirect;
			if (indirect > 1) {
				indirect = (indirect - 1 + I_B - 1) / I_B;
				blocks += indirect;
				if (indirect > 1)
					blocks++;
			}
		}
		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
		tmp.st_blksize = BLOCK_SIZE;
	} else {
		tmp.st_blocks = inode->i_blocks;
		tmp.st_blksize = inode->i_blksize;
	}
	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
示例#6
0
static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
{
	struct new_stat tmp;
	unsigned int blocks, indirect;

	memset(&tmp, 0, sizeof(tmp));
	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
	tmp.st_ino = inode->i_ino;
	tmp.st_mode = inode->i_mode;
	tmp.st_nlink = inode->i_nlink;
	tmp.st_uid = inode->i_uid;
	tmp.st_gid = inode->i_gid;
	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
	tmp.st_size = inode->i_size;
	if (inode->i_pipe)
		tmp.st_size = PIPE_SIZE(*inode);
	tmp.st_atime = inode->i_atime;
	tmp.st_mtime = inode->i_mtime;
	tmp.st_ctime = inode->i_ctime;
/*
 * st_blocks and st_blksize are approximated with a simple algorithm if
 * they aren't supported directly by the filesystem. The minix and msdos
 * filesystems don't keep track of blocks, so they would either have to
 * be counted explicitly (by delving into the file itself), or by using
 * this simple algorithm to get a reasonable (although not 100% accurate)
 * value.
 */

/*
 * Use minix fs values for the number of direct and indirect blocks.  The
 * count is now exact for the minix fs except that it counts zero blocks.
 * Everything is in BLOCK_SIZE'd units until the assignment to
 * tmp.st_blksize.
 */
#define D_B   7
#define I_B   (BLOCK_SIZE / sizeof(unsigned short))

	if (!inode->i_blksize) {
		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
		if (blocks > D_B) {
			indirect = (blocks - D_B + I_B - 1) / I_B;
			blocks += indirect;
			if (indirect > 1) {
				indirect = (indirect - 1 + I_B - 1) / I_B;
				blocks += indirect;
				if (indirect > 1)
					blocks++;
			}
		}
		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
		tmp.st_blksize = BLOCK_SIZE;
	} else {
		tmp.st_blocks = inode->i_blocks;
		tmp.st_blksize = inode->i_blksize;
	}
	memcpy_tofs(statbuf,&tmp,sizeof(tmp));
}
示例#7
0
static long cp_new_stat64(struct inode * inode, struct stat64 * statbuf)
{
	struct stat64 tmp;
	unsigned int blocks, indirect;
	int retval;

	if ((retval = security_inode_stat(inode)))
		return retval;

	memset(&tmp, 0, sizeof(tmp));
	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
	tmp.st_ino = inode->i_ino;
#ifdef STAT64_HAS_BROKEN_ST_INO
	tmp.__st_ino = inode->i_ino;
#endif
	tmp.st_mode = inode->i_mode;
	tmp.st_nlink = inode->i_nlink;
	tmp.st_uid = inode->i_uid;
	tmp.st_gid = inode->i_gid;
	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
	tmp.st_atime = inode->i_atime;
	tmp.st_mtime = inode->i_mtime;
	tmp.st_ctime = inode->i_ctime;
	tmp.st_size = inode->i_size;
/*
 * st_blocks and st_blksize are approximated with a simple algorithm if
 * they aren't supported directly by the filesystem. The minix and msdos
 * filesystems don't keep track of blocks, so they would either have to
 * be counted explicitly (by delving into the file itself), or by using
 * this simple algorithm to get a reasonable (although not 100% accurate)
 * value.
 */

/*
 * Use minix fs values for the number of direct and indirect blocks.  The
 * count is now exact for the minix fs except that it counts zero blocks.
 * Everything is in units of BLOCK_SIZE until the assignment to
 * tmp.st_blksize.
 */
#define D_B   7
#define I_B   (BLOCK_SIZE / sizeof(unsigned short))

	if (!inode->i_blksize) {
		blocks = (tmp.st_size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
		if (blocks > D_B) {
			indirect = (blocks - D_B + I_B - 1) / I_B;
			blocks += indirect;
			if (indirect > 1) {
				indirect = (indirect - 1 + I_B - 1) / I_B;
				blocks += indirect;
				if (indirect > 1)
					blocks++;
			}
		}
		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
		tmp.st_blksize = BLOCK_SIZE;
	} else {
示例#8
0
文件: inode.c 项目: dmgerman/original
void devpts_pty_new(int number, kdev_t device)
{
	struct super_block *sb = devpts_mnt->mnt_sb;
	struct devpts_sb_info *sbi = SBI(sb);
	struct inode *inode;
		
	if ( sbi->inodes[number] )
		return; /* Already registered, this does happen */
		
	inode = new_inode(sb);
	if (!inode)
		return;
	inode->i_ino = number+2;
	inode->i_blocks = 0;
	inode->i_blksize = 1024;
	inode->i_uid = sbi->setuid ? sbi->uid : current->fsuid;
	inode->i_gid = sbi->setgid ? sbi->gid : current->fsgid;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
	init_special_inode(inode, S_IFCHR|sbi->mode, kdev_t_to_nr(device));

	if ( sbi->inodes[number] ) {
		iput(inode);
		return;
	}
	sbi->inodes[number] = inode;
}
示例#9
0
文件: rd.c 项目: nhanh0/hah
static int rd_open(struct inode * inode, struct file * filp)
{
	int unit = DEVICE_NR(inode->i_rdev);

#ifdef CONFIG_BLK_DEV_INITRD
	if (unit == INITRD_MINOR) {
		if (!initrd_start) return -ENODEV;
		initrd_users++;
		filp->f_op = &initrd_fops;
		return 0;
	}
#endif

	if (unit >= NUM_RAMDISKS)
		return -ENXIO;

	/*
	 * Immunize device against invalidate_buffers() and prune_icache().
	 */
	if (rd_bdev[unit] == NULL) {
		rd_bdev[unit] = bdget(kdev_t_to_nr(inode->i_rdev));
		rd_bdev[unit]->bd_openers++;
		rd_bdev[unit]->bd_inode->i_mapping->a_ops = &ramdisk_aops;
	}

	return 0;
}
示例#10
0
文件: link.c 项目: rohsaini/mkunity
static int proc_readlink(struct inode * inode, char * buffer, int buflen)
{
	int i;
	unsigned int dev,ino;
	char buf[64];

	if (!S_ISLNK(inode->i_mode)) {
		iput(inode);
		return -EINVAL;
	}
	i = proc_follow_link(NULL, inode, 0, 0, &inode);
	if (i)
		return i;
	if (!inode)
		return -EIO;
	dev = kdev_t_to_nr(inode->i_dev);
	ino = inode->i_ino;
	iput(inode);
	i = sprintf(buf,"[%04x]:%u", dev, ino);
	if (buflen > i)
		buflen = i;
	i = 0;
	while (i < buflen)
		put_user(buf[i++],buffer++);
	return i;
}
示例#11
0
static int bfs_statfs(struct super_block *s, struct statfs *buf)
{
	buf->f_type = BFS_MAGIC;
	buf->f_bsize = s->s_blocksize;
	buf->f_blocks = s->su_blocks;
	buf->f_bfree = buf->f_bavail = s->su_freeb;
	buf->f_files = s->su_lasti + 1 - BFS_ROOT_INO;
	buf->f_ffree = s->su_freei;
	buf->f_fsid.val[0] = kdev_t_to_nr(s->s_dev);
	buf->f_namelen = BFS_NAMELEN;
	return 0;
}
示例#12
0
/*
 * For backward compatibility?  Maybe this should be moved
 * into arch/i386 instead?
 */
static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
{
	struct old_stat tmp;

	printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
		current->comm);
	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
	tmp.st_ino = inode->i_ino;
	tmp.st_mode = inode->i_mode;
	tmp.st_nlink = inode->i_nlink;
	tmp.st_uid = inode->i_uid;
	tmp.st_gid = inode->i_gid;
	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
	tmp.st_size = inode->i_size;
	if (inode->i_pipe)
		tmp.st_size = PIPE_SIZE(*inode);
	tmp.st_atime = inode->i_atime;
	tmp.st_mtime = inode->i_mtime;
	tmp.st_ctime = inode->i_ctime;
	memcpy_tofs(statbuf,&tmp,sizeof(tmp));
}
示例#13
0
STATIC int
nsdev_open(struct inode *inode, struct file *file)
{
	int err;
	struct cdevsw *cdev;
	struct dentry *dentry;
	major_t major;
	minor_t minor;
	modID_t modid, instance;
	dev_t dev;

#if defined HAVE_KFUNC_TO_KDEV_T
	minor = MINOR(kdev_t_to_nr(inode->i_rdev));
	major = MAJOR(kdev_t_to_nr(inode->i_rdev));
#else
	minor = MINOR(inode->i_rdev);
	major = MAJOR(inode->i_rdev);
#endif
	minor = cdev_minor(&nsdev_cdev, major, minor);
	major = nsdev_cdev.d_major;
	modid = nsdev_cdev.d_modid;
#ifdef HAVE_KMEMB_STRUCT_FILE_F_VFSMNT
	dentry = file->f_dentry;
#else
	dentry = file->f_path.dentry;
#endif
	err = -ENXIO;
	if (!(cdev = cdev_match((char *) dentry->d_name.name)))
		goto exit;
	err = -ENXIO;
	if (cdev == &nsdev_cdev)
		goto cdev_put_exit;	/* would loop */
	instance = cdev->d_modid;
	dev = makedevice(modid, instance);
	err = spec_open(file, cdev, dev, CLONEOPEN);
      cdev_put_exit:
	sdev_put(cdev);
      exit:
	return (err);
}
示例#14
0
文件: dmfs-lv.c 项目: andyvand/cygdm
static struct dentry *dmfs_lv_lookup(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = NULL;
	struct dmfs_inode_info *ii;

	ii = dmfs_find_by_name(dentry->d_name.name, dentry->d_name.len);
	if (ii) {
		int dev = kdev_t_to_nr(DMFS_I(dir)->md->dev);
		inode = ii->create(dir, 0600, ii->seq_ops, dev);
	}

	d_add(dentry, inode);
	return NULL;
}
示例#15
0
文件: inode.c 项目: dmgerman/original
struct inode * proc_get_inode(struct super_block * sb, int ino,
				struct proc_dir_entry * de)
{
	struct inode * inode;

	/*
	 * Increment the use count so the dir entry can't disappear.
	 */
	de_get(de);
#if 1
/* shouldn't ever happen */
if (de && de->deleted)
printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&de->count));
#endif

	inode = iget(sb, ino);
	if (!inode)
		goto out_fail;
	
	inode->u.generic_ip = (void *) de;
	if (de) {
		if (de->mode) {
			inode->i_mode = de->mode;
			inode->i_uid = de->uid;
			inode->i_gid = de->gid;
		}
		if (de->size)
			inode->i_size = de->size;
		if (de->nlink)
			inode->i_nlink = de->nlink;
		if (de->owner)
			__MOD_INC_USE_COUNT(de->owner);
		if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode))
			init_special_inode(inode,de->mode,kdev_t_to_nr(de->rdev));
		else {
			if (de->proc_iops)
				inode->i_op = de->proc_iops;
			if (de->proc_fops)
				inode->i_fop = de->proc_fops;
		}
	}

out:
	return inode;

out_fail:
	de_put(de);
	goto out;
}			
static int __init create_dev(char *name, kdev_t dev, char *devfs_name)
{
	void *handle;
	char path[64];
	int n;

	sys_unlink(name);
	if (!do_devfs)
		return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev));

	handle = devfs_find_handle(NULL, dev ? NULL : devfs_name,
				MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1);
	if (!handle)
		return -1;
	n = devfs_generate_path(handle, path + 5, sizeof (path) - 5);
	if (n < 0)
		return -1;
	return sys_symlink(path + n + 5, name);
}
示例#17
0
void jfs_read_inode(struct inode *inode)
{
	int rc;

	rc = alloc_jfs_inode(inode);
	if (rc) {
		jfs_warn("In jfs_read_inode, alloc_jfs_inode failed");
		goto bad_inode;
	}
	jfs_info("In jfs_read_inode, inode = 0x%p", inode);

	if (diRead(inode))
		goto bad_inode_free;

	if (S_ISREG(inode->i_mode)) {
		inode->i_op = &jfs_file_inode_operations;
		inode->i_fop = &jfs_file_operations;
		inode->i_mapping->a_ops = &jfs_aops;
	} else if (S_ISDIR(inode->i_mode)) {
		inode->i_op = &jfs_dir_inode_operations;
		inode->i_fop = &jfs_dir_operations;
		inode->i_mapping->a_ops = &jfs_aops;
		inode->i_mapping->gfp_mask = GFP_NOFS;
	} else if (S_ISLNK(inode->i_mode)) {
		if (inode->i_size >= IDATASIZE) {
			inode->i_op = &page_symlink_inode_operations;
			inode->i_mapping->a_ops = &jfs_aops;
		} else
			inode->i_op = &jfs_symlink_inode_operations;
	} else {
		inode->i_op = &jfs_file_inode_operations;
		init_special_inode(inode, inode->i_mode,
				   kdev_t_to_nr(inode->i_rdev));
	}

	return;

      bad_inode_free:
	free_jfs_inode(inode);
      bad_inode:
	make_bad_inode(inode);
}
示例#18
0
int acct_process(long exitcode)
{
    struct acct ac;
    unsigned short fs;

    if (acct_active) {
        strncpy(ac.ac_comm, current->comm, ACCT_COMM);
        ac.ac_comm[ACCT_COMM-1] = '\0';
        ac.ac_utime = current->utime;
        ac.ac_stime = current->stime;
        ac.ac_btime = CT_TO_SECS(current->start_time) + (xtime.tv_sec - (jiffies / HZ));
        ac.ac_etime = CURRENT_TIME - ac.ac_btime;
        ac.ac_uid   = current->uid;
        ac.ac_gid   = current->gid;
        ac.ac_tty   = (current)->tty == NULL ? -1 :
                      kdev_t_to_nr(current->tty->device);
        ac.ac_flag  = 0;
        if (current->flags & PF_FORKNOEXEC)
            ac.ac_flag |= AFORK;
        if (current->flags & PF_SUPERPRIV)
            ac.ac_flag |= ASU;
        if (current->flags & PF_DUMPCORE)
            ac.ac_flag |= ACORE;
        if (current->flags & PF_SIGNALED)
            ac.ac_flag |= AXSIG;
        ac.ac_minflt = current->min_flt;
        ac.ac_majflt = current->maj_flt;
        ac.ac_exitcode = exitcode;

        /* Kernel segment override */
        fs = get_fs();
        set_fs(KERNEL_DS);

        acct_file.f_op->write(acct_file.f_inode, &acct_file,
                              (char *)&ac, sizeof(struct acct));

        set_fs(fs);
    }
    return 0;
}
示例#19
0
int bd_acquire(struct inode *inode)
{
	struct block_device *bdev;
	spin_lock(&bdev_lock);
	if (inode->i_bdev) {
		atomic_inc(&inode->i_bdev->bd_count);
		spin_unlock(&bdev_lock);
		return 0;
	}
	spin_unlock(&bdev_lock);
	bdev = bdget(kdev_t_to_nr(inode->i_rdev));
	if (!bdev)
		return -ENOMEM;
	spin_lock(&bdev_lock);
	if (!inode->i_bdev) {
		inode->i_bdev = bdev;
		inode->i_mapping = bdev->bd_inode->i_mapping;
		list_add(&inode->i_devices, &bdev->bd_inodes);
	} else if (inode->i_bdev != bdev)
		BUG();
	spin_unlock(&bdev_lock);
	return 0;
}
示例#20
0
static struct buffer_head * sysv_update_inode(struct inode * inode)
{
	struct super_block * sb = inode->i_sb;
	struct buffer_head * bh;
	struct sysv_inode * raw_inode;
	unsigned int ino, block;

	ino = inode->i_ino;
	if (!ino || ino > sb->sv_ninodes) {
		printk("Bad inode number on dev %s: %d is out of range\n",
		       inode->i_sb->s_id, ino);
		return 0;
	}
	raw_inode = sysv_raw_inode(sb, ino, &bh);
	if (!raw_inode) {
		printk("unable to read i-node block\n");
		return 0;
	}

	raw_inode->i_mode = cpu_to_fs16(sb, inode->i_mode);
	raw_inode->i_uid = cpu_to_fs16(sb, fs_high2lowuid(inode->i_uid));
	raw_inode->i_gid = cpu_to_fs16(sb, fs_high2lowgid(inode->i_gid));
	raw_inode->i_nlink = cpu_to_fs16(sb, inode->i_nlink);
	raw_inode->i_size = cpu_to_fs32(sb, inode->i_size);
	raw_inode->i_atime = cpu_to_fs32(sb, inode->i_atime);
	raw_inode->i_mtime = cpu_to_fs32(sb, inode->i_mtime);
	raw_inode->i_ctime = cpu_to_fs32(sb, inode->i_ctime);
	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
		inode->u.sysv_i.i_data[0] = 
			cpu_to_fs32(sb, kdev_t_to_nr(inode->i_rdev));
	for (block = 0; block < 10+1+1+1; block++)
		write3byte(sb, (unsigned char*)&inode->u.sysv_i.i_data[block],
			&raw_inode->i_a.i_addb[3*block]);
	mark_buffer_dirty(bh);
	return bh;
}
示例#21
0
int copyup_named_dentry(struct inode *dir, struct dentry *dentry,
			int bstart, int new_bindex, char *name,
			int namelen, struct file **copyup_file, int len)
{
	struct dentry *new_hidden_dentry;
	struct dentry *old_hidden_dentry = NULL;
	struct super_block *sb;
	struct file *input_file = NULL;
	struct file *output_file = NULL;
	ssize_t read_bytes, write_bytes;
	mm_segment_t old_fs;
	int err = 0;
	char *buf;
	int old_bindex;
	int got_branch_input = -1;
	int got_branch_output = -1;
	int old_bstart;
	int old_bend;
	int size = len;
	struct dentry *new_hidden_parent_dentry;
	mm_segment_t oldfs;
	char *symbuf = NULL;
	uid_t saved_uid = current->fsuid;
	gid_t saved_gid = current->fsgid;

	print_entry_location();
	verify_locked(dentry);
	fist_print_dentry("IN: copyup_named_dentry", dentry);

	old_bindex = bstart;
	old_bstart = dbstart(dentry);
	old_bend = dbend(dentry);

	ASSERT(new_bindex >= 0);
	ASSERT(new_bindex < old_bindex);
	PASSERT(dir);
	PASSERT(dentry);

	sb = dir->i_sb;

	if ((err = is_robranch_super(sb, new_bindex)))
		goto out;

	/* Create the directory structure above this dentry. */
	new_hidden_dentry = create_parents_named(dir, dentry, name, new_bindex);
	PASSERT(new_hidden_dentry);
	if (IS_ERR(new_hidden_dentry)) {
		err = PTR_ERR(new_hidden_dentry);
		goto out;
	}

	fist_print_generic_dentry("Copyup Object", new_hidden_dentry);

	/* Now we actually create the object. */
	old_hidden_dentry = dtohd_index(dentry, old_bindex);
	PASSERT(old_hidden_dentry);
	PASSERT(old_hidden_dentry->d_inode);
	DGET(old_hidden_dentry);

	/* For symlinks, we must read the link before we lock the directory. */
	if (S_ISLNK(old_hidden_dentry->d_inode->i_mode)) {
		PASSERT(old_hidden_dentry->d_inode->i_op);
		PASSERT(old_hidden_dentry->d_inode->i_op->readlink);

		symbuf = KMALLOC(PATH_MAX, GFP_UNIONFS);
		if (!symbuf) {
			err = -ENOMEM;
			goto copyup_readlink_err;
		}

		oldfs = get_fs();
		set_fs(KERNEL_DS);
		err =
		    old_hidden_dentry->d_inode->i_op->
		    readlink(old_hidden_dentry, symbuf, PATH_MAX);
		set_fs(oldfs);
		if (err < 0)
			goto copyup_readlink_err;
		symbuf[err] = '\0';
	}

	/* Now we lock the parent, and create the object in the new branch. */
	new_hidden_parent_dentry = lock_parent(new_hidden_dentry);
	current->fsuid = new_hidden_parent_dentry->d_inode->i_uid;
	current->fsgid = new_hidden_parent_dentry->d_inode->i_gid;
	if (S_ISDIR(old_hidden_dentry->d_inode->i_mode)) {
		err = vfs_mkdir(new_hidden_parent_dentry->d_inode,
				new_hidden_dentry, S_IRWXU);
	} else if (S_ISLNK(old_hidden_dentry->d_inode->i_mode)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
		err = vfs_symlink(new_hidden_parent_dentry->d_inode,
				  new_hidden_dentry, symbuf);
#else
		err = vfs_symlink(new_hidden_parent_dentry->d_inode,
				  new_hidden_dentry, symbuf, S_IRWXU);
#endif
	} else if (S_ISBLK(old_hidden_dentry->d_inode->i_mode)
		   || S_ISCHR(old_hidden_dentry->d_inode->i_mode)
		   || S_ISFIFO(old_hidden_dentry->d_inode->i_mode)
		   || S_ISSOCK(old_hidden_dentry->d_inode->i_mode)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
		err = vfs_mknod(new_hidden_parent_dentry->d_inode,
				new_hidden_dentry,
				old_hidden_dentry->d_inode->i_mode,
				kdev_t_to_nr(old_hidden_dentry->d_inode->
					     i_rdev));
#else
		err = vfs_mknod(new_hidden_parent_dentry->d_inode,
				new_hidden_dentry,
				old_hidden_dentry->d_inode->i_mode,
				old_hidden_dentry->d_inode->i_rdev);
#endif
	} else if (S_ISREG(old_hidden_dentry->d_inode->i_mode)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
		err = vfs_create(new_hidden_parent_dentry->d_inode,
				 new_hidden_dentry, S_IRWXU);
#else
		err = vfs_create(new_hidden_parent_dentry->d_inode,
				 new_hidden_dentry, S_IRWXU, NULL);
#endif
	} else {
		char diemsg[100];
		snprintf(diemsg, sizeof(diemsg), "Unknown inode type %d\n",
			 old_hidden_dentry->d_inode->i_mode);
		FISTBUG(diemsg);
	}
	current->fsuid = saved_uid;
	current->fsgid = saved_gid;
	unlock_dir(new_hidden_parent_dentry);
      copyup_readlink_err:
	KFREE(symbuf);
	if (err) {
		/* get rid of the hidden dentry and all its traces */
		DPUT(new_hidden_dentry);
		set_dtohd_index(dentry, new_bindex, NULL);
		set_dbstart(dentry, old_bstart);
		set_dbend(dentry, old_bend);
		goto out;
	}

	/* We actually copyup the file here. */
	if (S_ISREG(old_hidden_dentry->d_inode->i_mode)) {
		mntget(stohiddenmnt_index(sb, old_bindex));
		branchget(sb, old_bindex);
		got_branch_input = old_bindex;
		input_file =
		    DENTRY_OPEN(old_hidden_dentry,
				stohiddenmnt_index(sb, old_bindex), O_RDONLY);
		if (IS_ERR(input_file)) {
			err = PTR_ERR(input_file);
			goto out;
		}
		if (!input_file->f_op || !input_file->f_op->read) {
			err = -EINVAL;
			goto out;
		}

		/* copy the new file */
		DGET(new_hidden_dentry);
		mntget(stohiddenmnt_index(sb, new_bindex));
		branchget(sb, new_bindex);
		got_branch_output = new_bindex;
		output_file =
		    DENTRY_OPEN(new_hidden_dentry,
				stohiddenmnt_index(sb, new_bindex), O_WRONLY);
		if (IS_ERR(output_file)) {
			err = PTR_ERR(output_file);
			goto out;
		}
		if (!output_file->f_op || !output_file->f_op->write) {
			err = -EINVAL;
			goto out;
		}

		/* allocating a buffer */
		buf = (char *)KMALLOC(PAGE_SIZE, GFP_UNIONFS);
		if (!buf) {
			err = -ENOMEM;
			goto out;
		}

		/* now read PAGE_SIZE bytes from offset 0 in a loop */
		old_fs = get_fs();

		input_file->f_pos = 0;
		output_file->f_pos = 0;

		set_fs(KERNEL_DS);
		do {
			if (len >= PAGE_SIZE)
				size = PAGE_SIZE;
			else if ((len < PAGE_SIZE) && (len > 0))
				size = len;

			len -= PAGE_SIZE;

			read_bytes =
			    input_file->f_op->read(input_file, buf, size,
						   &input_file->f_pos);
			if (read_bytes <= 0) {
				err = read_bytes;
				break;
			}

			write_bytes =
			    output_file->f_op->write(output_file, buf,
						     read_bytes,
						     &output_file->f_pos);
			if (write_bytes < 0 || (write_bytes < read_bytes)) {
				err = -EIO;
				break;
			}
		} while ((read_bytes > 0) && (len > 0));
		set_fs(old_fs);
		KFREE(buf);
	}

	/* Set permissions. */
	if ((err =
	     copyup_permissions(sb, old_hidden_dentry, new_hidden_dentry)))
		goto out;
	/* Selinux uses extended attributes for permissions. */
#if defined(UNIONFS_XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20))
	if ((err = copyup_xattrs(old_hidden_dentry, new_hidden_dentry)))
		goto out;
#endif

	/* do not allow files getting deleted to be reinterposed */
	if (!d_deleted(dentry))
		unionfs_reinterpose(dentry);

      out:
	if (input_file && !IS_ERR(input_file)) {
		fput(input_file);
	} else {
		/* since input file was not opened, we need to explicitly
		 * dput the old_hidden_dentry
		 */
		DPUT(old_hidden_dentry);
	}

	/* in any case, we have to branchput */
	if (got_branch_input >= 0)
		branchput(sb, got_branch_input);

	if (output_file) {
		if (copyup_file && !err) {
			*copyup_file = output_file;
		} else {
			fput(output_file);
			branchput(sb, got_branch_output);
		}
	}

	fist_print_dentry("OUT: copyup_dentry", dentry);
	fist_print_inode("OUT: copyup_dentry", dentry->d_inode);

	print_exit_status(err);
	return err;
}
示例#22
0
文件: blkmtd.c 项目: nhanh0/hah
/* Startup */
static int __init init_blkmtd(void)
{
  struct file *file = NULL;
  struct inode *inode;
  mtd_raw_dev_data_t *rawdevice = NULL;
  int maj, min;
  int i, blocksize, blocksize_bits;
  loff_t size = 0;
  int readonly = 0;
  int erase_size = CONFIG_MTD_BLKDEV_ERASESIZE;
  kdev_t rdev;
  int err;
  int mode;
  int totalsize = 0, total_sectors = 0;
  int regions;

  mtd_info = NULL;

  // Check args
  if(device == 0) {
    printk("blkmtd: error, missing `device' name\n");
    return 1;
  }

  if(ro)
    readonly = 1;

  if(erasesz)
    erase_size = erasesz;

  DEBUG(1, "blkmtd: got device = `%s' erase size = %dK readonly = %s\n", device, erase_size, readonly ? "yes" : "no");
  // Get a handle on the device
  mode = (readonly) ? O_RDONLY : O_RDWR;
  file = filp_open(device, mode, 0);
  if(IS_ERR(file)) {
    DEBUG(2, "blkmtd: open_namei returned %ld\n", PTR_ERR(file));
    return 1;
  }
  
  /* determine is this is a block device and if so get its major and minor
     numbers */
  inode = file->f_dentry->d_inode;
  if(!S_ISBLK(inode->i_mode)) {
    printk("blkmtd: %s not a block device\n", device);
    filp_close(file, NULL);
    return 1;
  }
  rdev = inode->i_rdev;
  //filp_close(file, NULL);
  DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n",
	 MAJOR(rdev), MINOR(rdev));
  maj = MAJOR(rdev);
  min = MINOR(rdev);

  if(maj == MTD_BLOCK_MAJOR) {
    printk("blkmtd: attempting to use an MTD device as a block device\n");
    return 1;
  }

  DEBUG(1, "blkmtd: devname = %s\n", bdevname(rdev));
  blocksize = BLOCK_SIZE;

  if(bs) {
    blocksize = bs;
  } else {
    if (blksize_size[maj] && blksize_size[maj][min]) {
      DEBUG(2, "blkmtd: blksize_size = %d\n", blksize_size[maj][min]);
      blocksize = blksize_size[maj][min];
    }
  }
  i = blocksize;
  blocksize_bits = 0;
  while(i != 1) {
    blocksize_bits++;
    i >>= 1;
  }

  if(count) {
    size = count;
  } else {
    if (blk_size[maj]) {
      size = ((loff_t) blk_size[maj][min] << BLOCK_SIZE_BITS) >> blocksize_bits;
    }
  }
  total_sectors = size;
  size *= blocksize;
  totalsize = size;
  DEBUG(1, "blkmtd: size = %ld\n", (long int)size);

  if(size == 0) {
    printk("blkmtd: cant determine size\n");
    return 1;
  }
  rawdevice = (mtd_raw_dev_data_t *)kmalloc(sizeof(mtd_raw_dev_data_t), GFP_KERNEL);
  if(rawdevice == NULL) {
    err = -ENOMEM;
    goto init_err;
  }
  memset(rawdevice, 0, sizeof(mtd_raw_dev_data_t));
  // get the block device
  rawdevice->binding = bdget(kdev_t_to_nr(MKDEV(maj, min)));
  err = blkdev_get(rawdevice->binding, mode, 0, BDEV_RAW);
  if (err) {
    goto init_err;
  }
  rawdevice->totalsize = totalsize;
  rawdevice->total_sectors = total_sectors;
  rawdevice->sector_size = blocksize;
  rawdevice->sector_bits = blocksize_bits;
  rawdevice->readonly = readonly;

  DEBUG(2, "sector_size = %d, sector_bits = %d\n", rawdevice->sector_size, rawdevice->sector_bits);

  mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
  if (mtd_info == NULL) {
    err = -ENOMEM;
    goto init_err;
  }
  memset(mtd_info, 0, sizeof(*mtd_info));

  // Setup the MTD structure
  mtd_info->name = "blkmtd block device";
  if(readonly) {
    mtd_info->type = MTD_ROM;
    mtd_info->flags = MTD_CAP_ROM;
    mtd_info->erasesize = erase_size << 10;
  } else {
    mtd_info->type = MTD_RAM;
    mtd_info->flags = MTD_CAP_RAM;
    mtd_info->erasesize = erase_size << 10;
  }
  mtd_info->size = size;
  mtd_info->erase = blkmtd_erase;
  mtd_info->read = blkmtd_read;
  mtd_info->write = blkmtd_write;
  mtd_info->sync = blkmtd_sync;
  mtd_info->point = 0;
  mtd_info->unpoint = 0;

  mtd_info->priv = rawdevice;
  regions = calc_erase_regions(NULL, erase_size << 10, size);
  DEBUG(1, "blkmtd: init: found %d erase regions\n", regions);
  mtd_info->eraseregions = kmalloc(regions * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
  if(mtd_info->eraseregions == NULL) {
  }
  mtd_info->numeraseregions = regions;
  calc_erase_regions(mtd_info->eraseregions, erase_size << 10, size);

  /* setup the page cache info */
  INIT_LIST_HEAD(&rawdevice->as.clean_pages);
  INIT_LIST_HEAD(&rawdevice->as.dirty_pages);
  INIT_LIST_HEAD(&rawdevice->as.locked_pages);
  rawdevice->as.nrpages = 0;
  rawdevice->as.a_ops = &blkmtd_aops;
  rawdevice->as.host = inode;
  rawdevice->as.i_mmap = NULL;
  rawdevice->as.i_mmap_shared = NULL;
  spin_lock_init(&rawdevice->as.i_shared_lock);
  rawdevice->as.gfp_mask = GFP_KERNEL;
  rawdevice->file = file;

  file->private_data = rawdevice;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
   mtd_info->module = THIS_MODULE;			
#endif
   if (add_mtd_device(mtd_info)) {
     err = -EIO;
     goto init_err;
   }
   init_waitqueue_head(&thr_wq);
   init_waitqueue_head(&mtbd_sync_wq);
   DEBUG(3, "blkmtd: init: kernel task @ %p\n", write_queue_task);
   DEBUG(2, "blkmtd: init: starting kernel task\n");
   kernel_thread(write_queue_task, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
   DEBUG(2, "blkmtd: init: started\n");
   printk("blkmtd loaded: version = %s using %s erase_size = %dK %s\n", VERSION, device, erase_size, (readonly) ? "(read-only)" : "");
   return 0;

 init_err:
   if(!rawdevice) {
     if(rawdevice->binding) 
       blkdev_put(rawdevice->binding, BDEV_RAW);

     kfree(rawdevice);
     rawdevice = NULL;
   }
   if(mtd_info) {
     if(mtd_info->eraseregions)
       kfree(mtd_info->eraseregions);
     kfree(mtd_info);
     mtd_info = NULL;
   }
   return err;
}
示例#23
0
文件: file.c 项目: mischief/los
/*
 * This is almost identical to Linux's fs/stat.c:cp_new_stat.
 * It just reads the values out of the inode struct.
 */
static OSKIT_COMDECL
file_stat(oskit_file_t *f,
          struct oskit_stat *out_stats)
{
    gfile_t *file;
    struct inode *inode;
    struct dentry *dentry;
    unsigned int blocks, indirect;

    file = (gfile_t *)f;
    if (!verify_file(file)) return OSKIT_E_INVALIDARG;
    dentry = file->dentry;
    inode = dentry->d_inode;

    if (out_stats == NULL)
        return OSKIT_E_INVALIDARG;

    memset(out_stats, 0, sizeof(*out_stats));
    out_stats->dev		 = kdev_t_to_nr(inode->i_dev);
    out_stats->ino		 = inode->i_ino;
    out_stats->mode		 = inode->i_mode;
    out_stats->nlink	 = inode->i_nlink;
    out_stats->uid		 = inode->i_uid;
    out_stats->gid		 = inode->i_gid;
    out_stats->rdev		 = kdev_t_to_nr(inode->i_rdev);
    out_stats->size		 = inode->i_size;
    out_stats->atime.tv_sec	 = inode->i_atime;
    out_stats->mtime.tv_sec	 = inode->i_mtime;
    out_stats->ctime.tv_sec	 = inode->i_ctime;

    /*
     * st_blocks and st_blksize are approximated with a simple algorithm if
     * they aren't supported directly by the filesystem. The minix and msdos
     * filesystems don't keep track of blocks, so they would either have to
     * be counted explicitly (by delving into the file itself), or by using
     * this simple algorithm to get a reasonable (although not 100% accurate)
     * value.
     */

    /*
     * Use minix fs values for the number of direct and indirect blocks.  The
     * count is now exact for the minix fs except that it counts zero blocks.
     * Everything is in BLOCK_SIZE'd units until the assignment to
     * out_stats->blksize.
     */
#define D_B   7
#define I_B   (BLOCK_SIZE / sizeof(unsigned short))

    if (!inode->i_blksize) {
        blocks = (out_stats->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
        if (blocks > D_B) {
            indirect = (blocks - D_B + I_B - 1) / I_B;
            blocks += indirect;
            if (indirect > 1) {
                indirect = (indirect - 1 + I_B - 1) / I_B;
                blocks += indirect;
                if (indirect > 1)
                    blocks++;
            }
        }
        out_stats->blocks = (BLOCK_SIZE / 512) * blocks;
        out_stats->blksize = BLOCK_SIZE;
    } else {
示例#24
0
/*
 * Object creation/destruction.
 */
LinuxFilesystemInfo* newLinuxFilesystemInfo(EFilesystemOperation operation, const char* dev_name, const char* dir_name, const char* type)
{
    LinuxFilesystemInfo* object;
#ifdef TALPA_HAVE_PATH_LOOKUP
    struct nameidata nd;
#else
    struct path p;
#endif
    struct vfsmount *mnt;
    struct dentry *dentry;
    int rc;

    object = talpa_alloc(sizeof(template_LinuxFilesystemInfo));
    if ( likely(object != NULL) )
    {
        memcpy(object, &template_LinuxFilesystemInfo, sizeof(template_LinuxFilesystemInfo));
        object->i_IFilesystemInfo.object = object;

        object->mOperation = operation;

        /* Two cases, mount and umount. On mount we are receiving all the strings and have very little
           extra work to do. On umount we are receiving just the mount point and will get the other data */

        if ( operation == EFS_Mount )
        {
            object->mType = copyString(type);

            mnt = 0;
            dentry = 0;
#ifdef TALPA_HAVE_PATH_LOOKUP
            rc = talpa_path_lookup(dev_name, TALPA_LOOKUP, &nd);
#else
            rc = kern_path(dev_name, TALPA_LOOKUP, &p);
#endif

            if ( rc == 0 )
            {
                struct inode *inode;
#ifdef TALPA_HAVE_PATH_LOOKUP
                mnt = talpa_nd_mnt(&nd);
                dentry = talpa_nd_dentry(&nd);
#else
                mnt = p.mnt;
                dentry = p.dentry;
#endif

                inode = dentry->d_inode;

                object->mDeviceName = absolutePath(dentry,mnt);

                if (S_ISBLK(inode->i_mode))
                {
                    object->mDevice = kdev_t_to_nr(inode->i_rdev);
                    object->mDeviceMajor = MAJOR(inode->i_rdev);
                    object->mDeviceMinor = MINOR(inode->i_rdev);
                }

#ifdef TALPA_HAVE_PATH_LOOKUP
                talpa_path_release(&nd);
#else
                path_put(&p);
#endif
            }

            if ( !object->mDeviceName )
            {
                dbg("DEBUG: EFS_Mount absolutePath deviceName failed: %s",dev_name);
                object->mDeviceName = copyString(dev_name);
                if ( !object->mDeviceName )
                {
                    goto error;
                }
            }

            if ( dir_name )
            {

                mnt = 0;
                dentry = 0;
#ifdef TALPA_HAVE_PATH_LOOKUP
                rc = talpa_path_lookup(dir_name, TALPA_LOOKUP, &nd);
#else
                rc = kern_path(dir_name, TALPA_LOOKUP, &p);
#endif

                if ( rc == 0 )
                {
#ifdef TALPA_HAVE_PATH_LOOKUP
                    mnt = talpa_nd_mnt(&nd);
                    dentry = talpa_nd_dentry(&nd);
#else
                    mnt = p.mnt;
                    dentry = p.dentry;
#endif

                    object->mMountPoint = absolutePath(dentry,mnt);

#ifdef TALPA_HAVE_PATH_LOOKUP
                    talpa_path_release(&nd);
#else
                    path_put(&p);
#endif
                }

                if ( object->mMountPoint == 0 )
                {
                    dbg("DEBUG: EFS_Mount absolutePath dir_name failed: %s",dir_name);
                    object->mMountPoint = copyString(dir_name);
                }
            }
        }
        else if ( (operation == EFS_Umount) && dir_name )
        {
            const char* mnt_devname;

#ifdef TALPA_HAVE_PATH_LOOKUP
            rc = talpa_path_lookup(dir_name, TALPA_LOOKUP, &nd);
#else
            rc = kern_path(dir_name, TALPA_LOOKUP, &p);
#endif
            if ( unlikely(rc != 0) )
            {
                dbg("DEBUG: EFS_Umount talpa_path_lookup/kern_path failed (%d)", rc);
                goto error;
            }
#ifdef TALPA_HAVE_PATH_LOOKUP
            mnt = talpa_nd_mnt(&nd);
            dentry = talpa_nd_dentry(&nd);
#else
            mnt = p.mnt;
            dentry = p.dentry;
#endif

            if ( dentry != mnt->mnt_root )
            {
                dbg("DEBUG: EFS_Umount dentry != mnt->mnt_root");
                goto error2;
            }

            object->mMountPoint = absolutePath(dentry,mnt);

            if ( object->mMountPoint == 0 )
            {
                dbg("DEBUG: EFS_Umount absolutePath dir_name failed");
                object->mMountPoint = copyString(dir_name);
                if ( !object->mMountPoint )
                {
                    goto error2;
                }
            }

            mnt_devname = getDeviceName(mnt);
            if ( mnt_devname )
            {
                if ( mnt->mnt_sb->s_bdev )
                {
#ifdef TALPA_HAVE_PATH_LOOKUP
                    struct nameidata dnd;
#else
                    struct path dp;
#endif
                    struct vfsmount *dmnt;
                    struct dentry *ddentry;

#ifdef TALPA_HAVE_PATH_LOOKUP
                    rc = talpa_path_lookup(mnt_devname, TALPA_LOOKUP, &dnd);
#else
                    rc = kern_path(mnt_devname, TALPA_LOOKUP, &dp);
#endif
                    if ( rc == 0 )
                    {
                        struct inode *inode;


#ifdef TALPA_HAVE_PATH_LOOKUP
                        dmnt = talpa_nd_mnt(&dnd);
                        ddentry = talpa_nd_dentry(&dnd);
#else
                        dmnt = dp.mnt;
                        ddentry = dp.dentry;
#endif
                        inode = ddentry->d_inode;
                        object->mDeviceName = absolutePath(ddentry,dmnt);

                        if (S_ISBLK(inode->i_mode))
                        {
                            object->mDevice = kdev_t_to_nr(inode->i_rdev);
                            object->mDeviceMajor = MAJOR(kdev_t_to_nr(inode->i_rdev));
                            object->mDeviceMinor = MINOR(kdev_t_to_nr(inode->i_rdev));
                        }

#ifdef TALPA_HAVE_PATH_LOOKUP
                        talpa_path_release(&dnd);
#else
                        path_put(&dp);
#endif
                    }
                }

                if ( !object->mDeviceName )
                {
                    dbg("DEBUG: EFS_Umount absolutePath mnt_devname failed");
                    object->mDeviceName = copyString(mnt_devname);
                    if ( !object->mDeviceName )
                    {
                        goto error2;
                    }
                }
            }

            if ( mnt->mnt_sb->s_type->name )
            {
                object->mType = copyString(mnt->mnt_sb->s_type->name);
            }

            if ( !object->mType )
            {
                object->mType = copyString(type);
            }

            dbg("Device %s resolved from mount point %s - %s", object->mDeviceName, object->mMountPoint, object->mType);

            object->mPropagationCount = countPropagationPoints(mnt);

#ifdef TALPA_HAVE_PATH_LOOKUP
            talpa_path_release(&nd);
#else
            path_put(&p);
#endif
        }
        else
        {
            dbg("DEBUG: unknown operation");
            goto error;
        }


        dbg("NAME:%s MAJOR:%u MINOR:%u",object->mDeviceName, object->mDeviceMajor, object->mDeviceMinor);
    }
    else
    {
        err("talpa_alloc() failed");
    }

    return object;

    error2:
#ifdef TALPA_HAVE_PATH_LOOKUP
    talpa_path_release(&nd);
#else
    path_put(&p);
#endif
    error:
    talpa_free(object->mDeviceName);
    talpa_free(object->mMountPoint);
    talpa_free(object->mType);
    talpa_free(object);

    return NULL;
}
示例#25
0
static int get_stat(int pid, char * buffer)
{
    struct task_struct ** p = get_task(pid), *tsk;
    unsigned long sigignore=0, sigcatch=0, wchan;
    unsigned long vsize, eip, esp;
    long priority, nice;
    int i,tty_pgrp;
    char state;

    if (!p || (tsk = *p) == NULL)
        return 0;
    if (tsk->state < 0 || tsk->state > 5)
        state = '.';
    else
        state = "RSDZTW"[tsk->state];
    vsize = eip = esp = 0;
    if (tsk->mm && tsk->mm != &init_mm) {
        struct vm_area_struct *vma = tsk->mm->mmap;
        while (vma) {
            vsize += vma->vm_end - vma->vm_start;
            vma = vma->vm_next;
        }
        if (tsk->kernel_stack_page) {
            eip = KSTK_EIP(tsk);
            esp = KSTK_ESP(tsk);
        }
    }
    wchan = get_wchan(tsk);
    if (tsk->sig) {
        unsigned long bit = 1;
        for(i=0; i<32; ++i) {
            switch((unsigned long) tsk->sig->action[i].sa_handler) {
            case 0:
                break;
            case 1:
                sigignore |= bit;
                break;
            default:
                sigcatch |= bit;
            }
            bit <<= 1;
        }
    }
    if (tsk->tty)
        tty_pgrp = tsk->tty->pgrp;
    else
        tty_pgrp = -1;

    /* scale priority and nice values from timeslices to -20..20 */
    /* to make it look like a "normal" unix priority/nice value  */
    priority = tsk->counter;
    priority = 20 - (priority * 10 + DEF_PRIORITY / 2) / DEF_PRIORITY;
    nice = tsk->priority;
    nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY;

    return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu\n",
                   pid,
                   tsk->comm,
                   state,
                   tsk->p_pptr->pid,
                   tsk->pgrp,
                   tsk->session,
                   tsk->tty ? kdev_t_to_nr(tsk->tty->device) : 0,
                   tty_pgrp,
                   tsk->flags,
                   tsk->min_flt,
                   tsk->cmin_flt,
                   tsk->maj_flt,
                   tsk->cmaj_flt,
                   tsk->utime,
                   tsk->stime,
                   tsk->cutime,
                   tsk->cstime,
                   priority,
                   nice,
                   tsk->timeout,
                   tsk->it_real_value,
                   tsk->start_time,
                   vsize,
                   tsk->mm ? tsk->mm->rss : 0, /* you might want to shift this left 3 */
                   tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0,
                   tsk->mm ? tsk->mm->start_code : 0,
                   tsk->mm ? tsk->mm->end_code : 0,
                   tsk->mm ? tsk->mm->start_stack : 0,
                   esp,
                   eip,
                   tsk->signal,
                   tsk->blocked,
                   sigignore,
                   sigcatch,
                   wchan,
                   tsk->nswap,
                   tsk->cnswap);
}
示例#26
0
static inline int examineFile(const void* self, EFilesystemOperation op, struct file* file, bool clonefile)
{
    int decision = 0;
    IFileInfo *pFInfo;


    /* We can't use a file object without a dentry or inode */
    if ( ( file->f_dentry == NULL ) || ( file->f_dentry->d_inode == NULL ) )
    {
        return 0;
    }

    /* First check with the examineInode method */
    decision = this->mTargetProcessor->examineInode(this->mTargetProcessor, op, flags_to_writable(file->f_flags), file->f_flags, kdev_t_to_nr(inode_dev(file->f_dentry->d_inode)), file->f_dentry->d_inode->i_ino);

    if ( likely(decision != -EAGAIN) )
    {
        return decision;
    }

    /* Make sure our open and close attempts while examining will be excluded */
    current->flags |= PF_TALPA_INTERNAL;

    pFInfo = this->mLinuxFilesystemFactory->i_IFilesystemFactory.newFileInfoFromFile(this->mLinuxFilesystemFactory, op, file);

    if ( likely(pFInfo != NULL) )
    {
        IFile *pFile = NULL;
#ifdef TALPA_SAME_FILE
        if ( clonefile )
        {
            pFile = GL_object.mLinuxFilesystemFactory->i_IFilesystemFactory.cloneFile(GL_object.mLinuxFilesystemFactory, file);
        }
#endif
        decision = this->mTargetProcessor->examineFileInfo(this->mTargetProcessor, pFInfo, pFile);
#ifdef TALPA_SAME_FILE
        if ( likely(pFile != NULL) )
        {
            pFile->delete(pFile);
        }