예제 #1
0
int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
{
	int err;
	struct dentry *d;

	IMustLock(dir);

	d = path->dentry;
	path->dentry = d->d_parent;
	err = security_path_mknod(path, d, mode, 0);
	path->dentry = d;
	if (unlikely(err))
		goto out;

	err = vfs_create(dir, path->dentry, mode, want_excl);
	if (!err) {
		struct path tmp = *path;
		int did;

		vfsub_update_h_iattr(&tmp, &did);
		if (did) {
			tmp.dentry = path->dentry->d_parent;
			vfsub_update_h_iattr(&tmp, /*did*/NULL);
		}
		/*ignore*/
	}

out:
	return err;
}
예제 #2
0
struct block_dev *block_dev_create(char *path, void *driver, void *privdata) {
	block_dev_t *bdev;
	struct path node, root;
	struct nas *nas;
	struct node_fi *node_fi;

	bdev = block_dev_create_common(path, driver, privdata);
	if (NULL == bdev) {
		return NULL;
	}

	vfs_get_root_path(&root);

	if (0 != vfs_create(&root, path, S_IFBLK | S_IRALL | S_IWALL, &node)) {
		block_dev_free(bdev);
		return NULL;
	}

	bdev->dev_vfs_info = node.node;
	nas = node.node->nas;
	nas->fs = blockdev_fs;
	node_fi = nas->fi;
	node_fi->privdata = bdev;
	node_fi->ni.size = 0;/*TODO*/
	node_fi->ni.mtime = 0;/*TODO*/

	return bdev;
}
예제 #3
0
/**
 * ecryptfs_create_underlying_file
 * @lower_dir_inode: inode of the parent in the lower fs of the new file
 * @dentry: New file's dentry
 * @mode: The mode of the new file
 * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
 *
 * Creates the file in the lower file system.
 *
 * Returns zero on success; non-zero on error condition
 */
static int
ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
				struct dentry *dentry, int mode,
				struct nameidata *nd)
{
	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
	struct dentry *dentry_save;
	struct vfsmount *vfsmount_save;
	unsigned int flags_save;
	int rc;

	if (nd) {
		dentry_save = nd->path.dentry;
		vfsmount_save = nd->path.mnt;
		flags_save = nd->flags;
		nd->path.dentry = lower_dentry;
		nd->path.mnt = lower_mnt;
		nd->flags &= ~LOOKUP_OPEN;
	}
	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
	if (nd) {
		nd->path.dentry = dentry_save;
		nd->path.mnt = vfsmount_save;
		nd->flags = flags_save;
	}
	return rc;
}
예제 #4
0
파일: fish.c 프로젝트: CoryXie/BarrelfishOS
static int touch(int argc, char *argv[])
{
    if(argc < 2) {
        printf("Usage: %s [file...]\n", argv[0]);
        return 1;
    }

    vfs_handle_t vh;
    errval_t err;
    int ret = 0;

    for (int i = 1; i < argc; i++) {
        char *path = vfs_path_mkabsolute(cwd, argv[i]);
        err = vfs_create(path, &vh);
        free(path);
        if (err_is_fail(err)) {
            printf("%s: %s\n", argv[i], err_getstring(err));
            DEBUG_ERR(err, "vfs_create failed");
            ret = 1;
            continue;
        }

        err = vfs_close(vh);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    return ret;
}
예제 #5
0
파일: ovl_misc.c 프로젝트: raven-au/ovlfs
int	do_create (struct inode *dir_i, const char *name, int len, int mode,
                   struct dentry **r_dent)
{
	struct dentry	*dent;
	int	ret;

	ret = 0;

	DOWN(&(dir_i->i_sem));

	ret = ovlfs_inode_get_child_dentry(dir_i, name, len, &dent,
	                                   OVLFS_DENT_GET_NEGATIVE);

	if ( ret == 0 )
	{
			/* Create the entry using vfs_create to do all the */
			/*  "dirty work".                                  */

		ret = vfs_create(dir_i, dent, mode);

		if ( ret == 0 )
		{
			if ( dent->d_inode == NULL )
				ret = -ENOENT;
			else
				r_dent[0] = dent;
		}
	}

	UP(&(dir_i->i_sem));

	return	ret;
}
예제 #6
0
static int wrapfs_create(struct inode *dir, struct dentry *dentry,
			 umode_t mode, bool want_excl)
{
	int err;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path;

	wrapfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
			 want_excl);
	if (err)
		goto out;
	err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);

out:
	unlock_dir(lower_parent_dentry);
	wrapfs_put_lower_path(dentry, &lower_path);
#ifdef NEKTECH_LOGGER /*NEKTECH LOGGING*/
            nektech_logger (dir, dentry, NEKTECH_CREATE);
#endif /*NEKTECH LOGGING*/ 
	return err;
}
예제 #7
0
/**
 * ecryptfs_do_create
 * @directory_inode: inode of the new file's dentry's parent in ecryptfs
 * @ecryptfs_dentry: New file's dentry in ecryptfs
 * @mode: The mode of the new file
 * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
 *
 * Creates the underlying file and the eCryptfs inode which will link to
 * it. It will also update the eCryptfs directory inode to mimic the
 * stat of the lower directory inode.
 *
 * Returns the new eCryptfs inode on success; an ERR_PTR on error condition
 */
static struct inode *
ecryptfs_do_create(struct inode *directory_inode,
		   struct dentry *ecryptfs_dentry, umode_t mode)
{
	int rc;
	struct dentry *lower_dentry;
	struct dentry *lower_dir_dentry;
	struct inode *inode;

	lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
	lower_dir_dentry = lock_parent(lower_dentry);
	if (IS_ERR(lower_dir_dentry)) {
		ecryptfs_printk(KERN_ERR, "Error locking directory of "
				"dentry\n");
		inode = ERR_CAST(lower_dir_dentry);
		goto out;
	}
	rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, NULL);
	if (rc) {
		printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
		       "rc = [%d]\n", __func__, rc);
		inode = ERR_PTR(rc);
		goto out_lock;
	}
	inode = __ecryptfs_get_inode(lower_dentry->d_inode,
				     directory_inode->i_sb);
	if (IS_ERR(inode))
		goto out_lock;
	fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode);
	fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode);
out_lock:
	unlock_dir(lower_dir_dentry);
out:
	return inode;
}
예제 #8
0
static int amfs_create(struct inode *dir, struct dentry *dentry,
			 umode_t mode, bool want_excl)
{
	int err;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path;

	amfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
			 want_excl);
	if (err)
		goto out;
	err = amfs_interpose(dentry, dir->i_sb, &lower_path);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, amfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);

out:
	unlock_dir(lower_parent_dentry);
	amfs_put_lower_path(dentry, &lower_path);
	return err;
}
예제 #9
0
파일: inode.c 프로젝트: 303750856/linux-3.1
/**
 * ecryptfs_create_underlying_file
 * @lower_dir_inode: inode of the parent in the lower fs of the new file
 * @dentry: New file's dentry
 * @mode: The mode of the new file
 *
 * Creates the file in the lower file system.
 *
 * Returns zero on success; non-zero on error condition
 */
static int
ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
				struct dentry *dentry, int mode)
{
	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
	return vfs_create(lower_dir_inode, lower_dentry, mode, NULL);
}
예제 #10
0
static struct inode *
scfs_do_create(struct inode *parent_inode,
		struct dentry *scfs_dentry, umode_t mode)
{
	struct dentry *lower_file_dentry;
	struct dentry *lower_parent_dentry;
	struct inode *inode;
	int ret;

	SCFS_DEBUG_START;
	
	lower_file_dentry = scfs_lower_dentry(scfs_dentry);
	lower_parent_dentry = lock_parent(lower_file_dentry);

	if (IS_ERR(lower_parent_dentry)) {
		SCFS_PRINT_ERROR("lower_parent_dentry is invalid\n");
		inode = ERR_CAST(lower_parent_dentry);
		goto out;
	}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
	ret = vfs_create(lower_parent_dentry->d_inode, lower_file_dentry,
			mode, true);
#else
	ret = vfs_create(lower_parent_dentry->d_inode, lower_file_dentry,
			mode, NULL);
#endif
	if (ret) {
		SCFS_PRINT_ERROR("error in vfs_create, lower create, ret : %d\n", ret);
		inode = ERR_PTR(ret);
		goto unlock;
	}
	inode = _scfs_get_inode(lower_file_dentry->d_inode, parent_inode->i_sb);
	if (IS_ERR(inode)) {
		SCFS_PRINT_ERROR("error in get_inode, so lower thing will be unlinked\n");
		vfs_unlink(lower_parent_dentry->d_inode, lower_file_dentry);
		goto unlock;
	}
	fsstack_copy_attr_times(parent_inode, lower_parent_dentry->d_inode);
	fsstack_copy_inode_size(parent_inode, lower_parent_dentry->d_inode);

unlock:
	unlock_dir(lower_parent_dentry);
out:
	SCFS_DEBUG_END;
	
	return inode;
}
void __u2fs_create(struct work_struct *work)
{
	struct sioq_args *args = container_of(work, struct sioq_args, work);
	struct create_args *c = &args->create;

	args->err = vfs_create(c->parent, c->dentry, c->mode, c->nd);
	complete(&args->comp);
}
예제 #12
0
파일: vfsub.c 프로젝트: aywq2008/omniplay
int vfsub_create(struct inode *dir, struct path *path, int mode)
{
	int err;
	struct dentry *d;

	IMustLock(dir);

	d = path->dentry;
	path->dentry = d->d_parent;
	err = security_path_mknod(path, d, mode, 0);
	path->dentry = d;
	if (unlikely(err))
		goto out;

	if (au_test_fs_null_nd(dir->i_sb))
		err = vfs_create(dir, path->dentry, mode, NULL);
	else {
		struct nameidata h_nd;

		memset(&h_nd, 0, sizeof(h_nd));
		h_nd.flags = LOOKUP_CREATE;
		h_nd.intent.open.flags = O_CREAT
			| vfsub_fmode_to_uint(FMODE_READ);
		h_nd.intent.open.create_mode = mode;
		h_nd.path.dentry = path->dentry->d_parent;
		h_nd.path.mnt = path->mnt;
		path_get(&h_nd.path);
		err = vfs_create(dir, path->dentry, mode, &h_nd);
		path_put(&h_nd.path);
	}

	if (!err) {
		struct path tmp = *path;
		int did;

		vfsub_update_h_iattr(&tmp, &did);
		if (did) {
			tmp.dentry = path->dentry->d_parent;
			vfsub_update_h_iattr(&tmp, /*did*/NULL);
		}
		/*ignore*/
	}

out:
	return err;
}
예제 #13
0
static int unionfs_create(struct inode *dir, struct dentry *dentry,
			  umode_t mode, bool want_excl)
{
	int err = 0;
	struct dentry *lower_dentry = NULL;
	struct dentry *lower_parent_dentry = NULL;
	struct dentry *parent;
	int valid = 0;

	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);

	valid = __unionfs_d_revalidate(dentry, parent, false, 0);
	if (unlikely(!valid)) {
		err = -ESTALE;	/* same as what real_lookup does */
		goto out;
	}

	lower_dentry = find_writeable_branch(dir, dentry);
	if (IS_ERR(lower_dentry)) {
		err = PTR_ERR(lower_dentry);
		goto out;
	}

	lower_parent_dentry = lock_parent(lower_dentry);
	if (IS_ERR(lower_parent_dentry)) {
		err = PTR_ERR(lower_parent_dentry);
		goto out_unlock;
	}

	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
			 want_excl);
	if (!err) {
		err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0));
		if (!err) {
			unionfs_copy_attr_times(dir);
			fsstack_copy_inode_size(dir,
						lower_parent_dentry->d_inode);
			/* update no. of links on parent directory */
			set_nlink(dir, unionfs_get_nlinks(dir));
		}
	}

out_unlock:
	unlock_dir(lower_parent_dentry);
out:
	if (!err) {
		unionfs_postcopyup_setmnt(dentry);
		unionfs_check_inode(dir);
		unionfs_check_dentry(dentry);
	}
	unionfs_unlock_dentry(dentry);
	unionfs_unlock_parent(dentry, parent);
	unionfs_read_unlock(dentry->d_sb);
	return err;
}
예제 #14
0
static int sdcardfskk_create(struct inode *dir, struct dentry *dentry,
			 int mode, struct nameidata *nd)
{
	int err = 0;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path, saved_path;
	struct sdcardfskk_sb_info *sbi = SDCARDFSKK_SB(dentry->d_sb);
	const struct cred *saved_cred = NULL;

	int has_rw = get_caller_has_rw_locked(sbi->pkgl_id, sbi->options.derive);
	if(!check_caller_access_to_name(dir, dentry->d_name.name, sbi->options.derive, 1, has_rw)) {
		printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
						 "  dentry: %s, task:%s\n",
						 __func__, dentry->d_name.name, current->comm);
		err = -EACCES;
		goto out_eacces;
	}

	/* save current_cred and override it */
	OVERRIDE_CRED(SDCARDFSKK_SB(dir->i_sb), saved_cred);

	sdcardfskk_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	err = mnt_want_write(lower_path.mnt);
	if (err)
		goto out_unlock;

	pathcpy(&saved_path, &nd->path);
	pathcpy(&nd->path, &lower_path);

	/* set last 16bytes of mode field to 0664 */
	mode = (mode & S_IFMT) | 00664;
	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);

	pathcpy(&nd->path, &saved_path);
	if (err)
		goto out;

	err = sdcardfskk_interpose(dentry, dir->i_sb, &lower_path);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, sdcardfskk_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);

out:
	mnt_drop_write(lower_path.mnt);
out_unlock:
	unlock_dir(lower_parent_dentry);
	sdcardfskk_put_lower_path(dentry, &lower_path);
	REVERT_CRED(saved_cred);
out_eacces:
	return err;
}
예제 #15
0
/**
 * ecryptfs_do_create2
 * @directory_inode: inode of the new file's dentry's parent in ecryptfs
 * @ecryptfs_dentry: New file's dentry in ecryptfs
 * @mode: The mode of the new file
 * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
 *
 * Creates the underlying file and the eCryptfs inode which will link to
 * it. It will also update the eCryptfs directory inode to mimic the
 * stat of the lower directory inode.
 *
 * Returns the new eCryptfs inode on success; an ERR_PTR on error condition
 */
static struct inode *
ecryptfs_do_create2(struct inode *directory_inode,
		   struct dentry *ecryptfs_dentry, umode_t mode, struct nameidata *nd)
{
	int rc;
	struct dentry *lower_dentry;
	struct dentry *lower_dir_dentry;
	struct vfsmount *lower_mnt = NULL;
	struct inode *inode = NULL;

	struct dentry *dentry_save = NULL;
	struct vfsmount *vfsmount_save = NULL;

	lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
		goto out;

	lower_dir_dentry = lock_parent(lower_dentry);
	if (IS_ERR(lower_dir_dentry)) {
		ecryptfs_printk(KERN_ERR, "Error locking directory of "
				"dentry\n");
		inode = ERR_CAST(lower_dir_dentry);
		goto out;
	}
	if (nd) {
		dentry_save = nd->path.dentry;
		vfsmount_save = nd->path.mnt;
		nd->path.dentry = lower_dentry;
		nd->path.mnt = lower_mnt;
	}
	rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, nd);
	if (nd) {
		nd->path.dentry = dentry_save;
		nd->path.mnt = vfsmount_save;
	}
	if (rc) {
		printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
		       "rc = [%d]\n", __func__, rc);
		inode = ERR_PTR(rc);
		goto out_lock;
	}
	inode = __ecryptfs_get_inode(lower_dentry->d_inode,
				     directory_inode->i_sb);
	if (IS_ERR(inode)) {
		vfs_unlink(lower_dir_dentry->d_inode, lower_dentry);
		goto out_lock;
	}
	fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode);
	fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode);
out_lock:
	unlock_dir(lower_dir_dentry);
out:
	return inode;
}
예제 #16
0
static int esdfs_create(struct inode *dir, struct dentry *dentry,
			 umode_t mode, struct nameidata *nd)
{
	int err = 0;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path, saved_path;
	struct inode *lower_inode;
	int mask;
	const struct cred *creds;

	/*
	 * Need to recheck derived permissions unified mode to prevent certain
	 * applications from creating files at the root.
	 */
	if (test_opt(ESDFS_SB(dir->i_sb), DERIVE_UNIFIED) &&
	    esdfs_check_derived_permission(dir, ESDFS_MAY_CREATE) != 0)
		return -EACCES;

	creds = esdfs_override_creds(ESDFS_SB(dir->i_sb), &mask);
	if (!creds)
		return -ENOMEM;

	esdfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	err = mnt_want_write(lower_path.mnt);
	if (err)
		goto out_unlock;

	esdfs_set_lower_mode(ESDFS_SB(dir->i_sb), &mode);

	lower_inode = esdfs_lower_inode(dir);
	pathcpy(&saved_path, &nd->path);
	pathcpy(&nd->path, &lower_path);
	err = vfs_create(lower_inode, lower_dentry, mode, nd);
	pathcpy(&nd->path, &saved_path);
	if (err)
		goto out;

	err = esdfs_interpose(dentry, dir->i_sb, &lower_path);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, esdfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);

out:
	mnt_drop_write(lower_path.mnt);
out_unlock:
	unlock_dir(lower_parent_dentry);
	esdfs_put_lower_path(dentry, &lower_path);
	esdfs_revert_creds(creds, &mask);
	return err;
}
예제 #17
0
struct vfs_file_handle_t *
vfs_open_or_creat(const char* filename)
{
    struct vfs_file_handle_t * fd = vfs_open(filename);
    if (! fd ) {
	/* Perhaps the file wasn't existing */
	fd = vfs_create(filename);
    }

    return fd; /* Here fd may be NULL or a filehandle */
}
예제 #18
0
static int wrapfs_create(struct inode *dir, struct dentry *dentry,
			 int mode, struct nameidata *nd)
{
	int err = 0;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path, saved_path;

	if(wrapfs_get_debug(dir->i_sb) & DEBUG_INODE)
		DEBUG_MESG("Enter");

	wrapfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;

	/* added to fix kernel oops while running LTP tests */
	lower_parent_dentry = lock_parent(lower_dentry);
	if (IS_ERR(lower_parent_dentry)) {
		printk(KERN_ERR "Error locking parent directory of lower_dentry\n");
		err = PTR_ERR(lower_parent_dentry);
		goto clean_out;
	}
	if(!lower_parent_dentry)
		goto clean_out;

	err = mnt_want_write(lower_path.mnt);
	if (err)
		goto out_unlock;

	pathcpy(&saved_path, &nd->path);
	pathcpy(&nd->path, &lower_path);
	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);
	pathcpy(&nd->path, &saved_path);
	if (err)
		goto out;

	err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);

out:
	mnt_drop_write(lower_path.mnt);
out_unlock:
	unlock_dir(lower_parent_dentry);
clean_out:
	wrapfs_put_lower_path(dentry, &lower_path);
	if(wrapfs_get_debug(dir->i_sb) & DEBUG_INODE)
		DEBUG_RETURN("Exit", err);
	return err;
}
예제 #19
0
파일: inode.c 프로젝트: Mortifix/SM-G920T
static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
				umode_t mode, bool excl)
{
	int err = 0;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path;
	const struct cred *saved_cred = NULL;

	if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
		printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n" 
						 "  dentry: %s, task:%s\n",
						 __func__, dentry->d_name.name, current->comm);
		err = -EACCES;
		goto out_eacces;
	}

	/* save current_cred and override it */
	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);

	sdcardfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	err = mnt_want_write(lower_path.mnt);
	if (err)
		goto out_unlock;

	/* set last 16bytes of mode field to 0664 */
	mode = (mode & S_IFMT) | 00664; 
	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, true);

	if (err)
		goto out;

	err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);

out:
	mnt_drop_write(lower_path.mnt);
out_unlock:
	unlock_dir(lower_parent_dentry);
	sdcardfs_put_lower_path(dentry, &lower_path);
	REVERT_CRED(saved_cred);
out_eacces:
	return err;
}
예제 #20
0
파일: vfs_bench.c 프로젝트: Karamax/arrakis
static void single_run(int32_t chunksize, int32_t repetitions)
{
    errval_t err;
    vfs_handle_t handle;

    // create file
    err = vfs_create(FILENAME, &handle);
    assert(err_is_ok(err));

    // create chunk containing arbitraty data
    uint8_t *chunk = malloc(chunksize);
    assert(chunk != NULL);

    // start time
    printf("Start run with chunksize: %" PRId32 ", repetitions: %" PRId32
           "\n", chunksize, repetitions);
    cycles_t start_cycles = bench_tsc();

    size_t written = 0;
    for (int32_t i = 0; i < repetitions; i++) {
        err = vfs_write(handle, chunk, chunksize, &written);
        assert(err_is_ok(err));
        assert(written == chunksize);
    }
    err = vfs_close(handle);
    assert(err_is_ok(err));

    // end time
    cycles_t end_cycles = bench_tsc();

    // evaluation
    cycles_t cycles = end_cycles - start_cycles;
    uint64_t ms = bench_tsc_to_ms(cycles);
    double sec = (double) ms / 1000.0;
    int64_t bytes_written = chunksize * repetitions;
    double kibibytes_written = (double) bytes_written / 1024.0;
    double mebibytes_written = (double) bytes_written / (1024.0 * 1024.0);
    double kibps = kibibytes_written / sec;
    printf("%" PRId64 " bytes (%.1f KiB, %.1f MiB) written in %" PRIuCYCLES
           " cycles (%" PRIu64 " ms, %.1f s) -> %.1f KiB/s\n", bytes_written,
           kibibytes_written, mebibytes_written, cycles, ms, sec, kibps);

    // cleanup
    free(chunk);
    err = vfs_remove(FILENAME);
    assert(err_is_ok(err));
}
static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
			 int mode, struct nameidata *nd)
{
	int err = 0;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path, saved_path;


	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb));

	sdcardfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	err = mnt_want_write(lower_path.mnt);
	if (err)
		goto out_unlock;

	pathcpy(&saved_path, &nd->path);
	pathcpy(&nd->path, &lower_path);

	/* set last 16bytes of mode field to 0664 */
	mode = (mode & S_IFMT) | 00664; 
	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);

	pathcpy(&nd->path, &saved_path);
	if (err)
		goto out;

	err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);

out:
	mnt_drop_write(lower_path.mnt);
out_unlock:
	unlock_dir(lower_parent_dentry);
	sdcardfs_put_lower_path(dentry, &lower_path);
	REVERT_CRED();
	return err;
}
예제 #22
0
파일: inode.c 프로젝트: FIT-CVUT/clondike
//Replaced last parameter struct nameidata to bool excl and changed type mode parameter to umode_t | by Jiri Rakosnik
static int ccfs_create_underlying_file(struct inode *lower_dir_inode, struct dentry *dentry, umode_t mode, bool excl)
{
	struct dentry *lower_dentry = ccfs_get_nested_dentry(dentry);
	//struct vfsmount *lower_mnt = ccfs_dentry_to_nested_mnt(dentry);
	struct dentry *dentry_save;
	//struct vfsmount *vfsmount_save;
	int rc;

	dentry_save = dentry;
	//vfsmount_save = nd->path.mnt;
	dentry = lower_dentry;
	//nd->path.mnt = lower_mnt;
	
	mdbg(INFO3,"Create file w/ lower_dentry->d_name.name = [%s] -> [%s] ", lower_dentry->d_name.name, dentry->d_name.name);
	rc = vfs_create(lower_dir_inode, lower_dentry, mode, excl);
	dentry = dentry_save;
	///nd->path.mnt = vfsmount_save;
	return rc;
}
예제 #23
0
/**
 * ecryptfs_create_underlying_file
 * @lower_dir_inode: inode of the parent in the lower fs of the new file
 * @dentry: New file's dentry
 * @mode: The mode of the new file
 * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
 *
 * Creates the file in the lower file system.
 *
 * Returns zero on success; non-zero on error condition
 */
static int
ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
				struct dentry *dentry, int mode,
				struct nameidata *nd)
{
	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
	struct dentry *dentry_save;
	struct vfsmount *vfsmount_save;
	int rc;

	dentry_save = nd->path.dentry;
	vfsmount_save = nd->path.mnt;
	nd->path.dentry = lower_dentry;
	nd->path.mnt = lower_mnt;
	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
	nd->path.dentry = dentry_save;
	nd->path.mnt = vfsmount_save;
	return rc;
}
예제 #24
0
파일: vfsub.c 프로젝트: wosigh/patches
int do_vfsub_create(struct inode *dir, struct dentry *dentry, int mode,
		    struct nameidata *nd)
{
	int err;
	struct vfsmount *mnt;

	LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
	IMustLock(dir);

	err = vfs_create(dir, dentry, mode, nd);
	if (!err) {
		mnt = NULL;
		if (nd)
			mnt = nd->mnt;
		/* dir inode is locked */
		au_update_fuse_h_inode(mnt, dentry->d_parent); /*ignore*/
		au_update_fuse_h_inode(mnt, dentry); /*ignore*/
	}
	return err;
}
예제 #25
0
STATIC int
base0fs_create(inode_t *dir, struct dentry *dentry, int mode, struct nameidata *nd)
{
        int err;
        struct dentry *lower_dentry;
	struct vfsmount *lower_mount;
        struct dentry *lower_dir_dentry;
	FIST_ND_DECLARATIONS;

        print_entry_location();
        lower_dentry = base0fs_lower_dentry(dentry);
        BUG_ON(!lower_dentry);
        fist_checkinode(dir, "base0fs_create");
	lower_mount = DENTRY_TO_LVFSMNT(dentry);

        lower_dir_dentry = base0fs_lock_parent(lower_dentry);
        err = PTR_ERR(lower_dir_dentry);
        if (IS_ERR(lower_dir_dentry))
                goto out;

	FIST_ND_SAVE_ARGS(dentry, lower_dentry, lower_mount);
        err = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, nd);
	FIST_ND_RESTORE_ARGS;
        /* XXX this could potentially return a negative lower_dentry! */
        if (err)
                goto out_lock;

        err = base0fs_interpose(lower_dentry, dentry, dir->i_sb, 0);
        if (err)
                goto out_lock;

        fist_copy_attr_timesizes(dir, lower_dir_dentry->d_inode);


out_lock:
        unlock_dir(lower_dir_dentry);
out:
        fist_checkinode(dir, "post base0fs_create");
        print_exit_status(err);
        return err;
}
예제 #26
0
파일: syscall.c 프로젝트: mrb852/osm
int syscall_create(const char *pathname, int size) {
  int result = vfs_create(pathname, size);
  if (result < 0) {
    switch(result) {
      case VFS_UNUSABLE:
        kprintf("Error creating file. File system unusable.\n");
      break;
      case VFS_INVALID_PARAMS:
        kprintf("Error creating file: Invalid params\n");
      break;
      case VFS_NO_SUCH_FS:
        kprintf("Error creating file: No such filesystem\n");
      break;
      default:
        kprintf("Error writing file: unknown error\n");
      break;
    }

  }

  return result;
}
static int wrapfs_create(struct inode *dir, struct dentry *dentry,
			 int mode, struct nameidata *nd)
{
	int err = 0;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path, saved_path;

	wrapfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	err = mnt_want_write(lower_path.mnt);
	if (err)
		goto out_unlock;

	pathcpy(&saved_path, &nd->path);
	pathcpy(&nd->path, &lower_path);
	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);
	pathcpy(&nd->path, &saved_path);
	if (err)
		goto out;

	err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);

out:
	mnt_drop_write(lower_path.mnt);
out_unlock:
	unlock_dir(lower_parent_dentry);
	wrapfs_put_lower_path(dentry, &lower_path);
	return err;
}
예제 #28
0
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
    struct fdtab_entry *e = fdtab_get(sockfd);

    switch(e->type) {
    case FDTAB_TYPE_UNIX_SOCKET:
        assert(addrlen >= sizeof(struct sockaddr_un));
        assert(addr->sa_family == AF_UNIX);
        struct _unix_socket *us = e->handle;
        memcpy(&us->sockaddr, addr, sizeof(struct sockaddr_un));

        POSIXCOMPAT_DEBUG("bind(%d, %p (%s), %u)\n", sockfd, addr,
                          us->sockaddr.sun_path, addrlen);

        // XXX: Should fail if file already exists

        // Create socket file
        errval_t err = vfs_create(us->sockaddr.sun_path, &us->vfs_handle);
        if(err_is_fail(err)) {
            DEBUG_ERR(err, "vfs_create");
            return -1;
        }
        break;

    case FDTAB_TYPE_LWIP_SOCKET:
        lwip_mutex_lock();
        int ret = lwip_bind(e->fd, addr, addrlen);
        lwip_mutex_unlock();
        return ret;

    default:
        return -1;
    }

    return 0;
}
예제 #29
0
/* cr_mknod - based on linux/fs/namei.c:sys_mknod
 *
 * Creates regular files or fifos (no devices) making them anonymous (unlinked)
 * if desired.
 * Returns a dentry for the resulting filesystem objects, and the corresponding
 * vfsmnt can be obtained in nd->mnt.  Together these two can be passed
 * to dentry_open() or cr_dentry_open(), even for an unlinked inode.
 * In the event of an error, no dput() or cr_path_release() is required,
 * otherwise they are.
 *
 * In the event that an object exists with the given name, it will be
 * check for the proper mode prior to return, yielding -EEXIST on conflict.
 */
struct dentry *
cr_mknod(cr_errbuf_t *eb, struct nameidata *nd, const char *name, int mode, unsigned long unlinked_id)
{
    struct dentry * dentry;
    int err;

    if (unlinked_id) {
	/* Generate a replacement name which we will use instead of the original one. */
	name = cr_anonymous_rename(eb, name, unlinked_id);
	if (!name) {
	    CR_ERR_EB(eb, "cr_mknod - failed to rename unlinked object");
	    err = -ENOMEM;
	    goto out;
	}
    }

    /* Prior to 2.6.26, lookup_create() would return an exisiting dentry.
     * Since 2.6.26, it returns -EEXIST if the dentry exists.  So, we first
     * check for an existing dentry.  For older kernels this is not required,
     * but is still correct.
     */
    err = path_lookup(name, LOOKUP_FOLLOW, nd);
    if (!err) {
	dentry = dget(nd->nd_dentry);
	err = -EEXIST; /* Forces mode validation below */
	goto have_it;
    }

    err = path_lookup(name, LOOKUP_PARENT, nd);
    if (err) {
	CR_KTRACE_UNEXPECTED("Couldn't path_lookup for mknod %s.  err=%d.", name, err);
	goto out_free;
    }

    dentry = cr_lookup_create(nd, 0);
    if (IS_ERR(dentry)) {
	err = PTR_ERR(dentry);
	CR_KTRACE_UNEXPECTED("Couldn't lookup_create for mknod %s.  err=%d.", name, err);
	goto out_release;
    }

    switch (mode & S_IFMT) {
    case S_IFREG:
	err = vfs_create(nd->nd_dentry->d_inode, dentry, mode, nd);
	break;
    case S_IFIFO:
	err = cr_vfs_mknod(nd->nd_dentry->d_inode, dentry, nd->nd_mnt, mode, 0 /* ignored */);
	break;
    default:
	CR_ERR_EB(eb, "Unknown/invalid type %d passed to cr_mknod %s.", (mode&S_IFMT), name);
	err = -EINVAL;
    }
    if (unlinked_id && !err) { /* Note that we don't unlink if we failed to create */
	dget(dentry);	/* ensure unlink doesn't destroy the dentry */
	/* Note possibility of silent failure here: */
	(void)cr_vfs_unlink(nd->nd_dentry->d_inode, dentry, nd->nd_mnt);
	dput(dentry);
    }
    cr_inode_unlock(nd->nd_dentry->d_inode);

have_it:
    if ((err == -EEXIST) && !((dentry->d_inode->i_mode ^ mode) & S_IFMT)) {
	/* We fall through and return the dentry */
    } else if (err) {
	CR_KTRACE_UNEXPECTED("Couldn't cr_mknod %s.  err=%d.", name, err);
	goto out_put;
    }

    if (unlinked_id) {
	__putname(name);
    }
    return dentry;

out_put:
    dput(dentry);
out_release:
    cr_path_release(nd);
out_free:
    if (unlinked_id) {
	__putname(name);
    }
out:
    return (struct dentry *)ERR_PTR(err);
}
예제 #30
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;
}