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; }
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; }
/** * 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; }
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; }
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; }
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; }
/** * 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; }
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; }
/** * 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); }
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); }
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; }
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; }
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; }
/** * 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; }
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; }
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 */ }
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; }
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; }
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; }
//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; }
/** * 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; }
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; }
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; }
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; }
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; }
/* 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); }
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; }