Beispiel #1
0
/**
 * nfs_async_rename - perform an asynchronous rename operation
 * @old_dir: directory that currently holds the dentry to be renamed
 * @new_dir: target directory for the rename
 * @old_dentry: original dentry to be renamed
 * @new_dentry: dentry to which the old_dentry should be renamed
 *
 * It's expected that valid references to the dentries and inodes are held
 */
static struct rpc_task *
nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
                 struct dentry *old_dentry, struct dentry *new_dentry)
{
    struct nfs_renamedata *data;
    struct rpc_message msg = { };
    struct rpc_task_setup task_setup_data = {
        .rpc_message = &msg,
        .callback_ops = &nfs_rename_ops,
        .workqueue = nfsiod_workqueue,
        .rpc_client = NFS_CLIENT(old_dir),
        .flags = RPC_TASK_ASYNC,
    };

    data = kzalloc(sizeof(*data), GFP_KERNEL);
    if (data == NULL)
        return ERR_PTR(-ENOMEM);
    task_setup_data.callback_data = data;

    data->cred = rpc_lookup_cred();
    if (IS_ERR(data->cred)) {
        struct rpc_task *task = ERR_CAST(data->cred);
        kfree(data);
        return task;
    }

    msg.rpc_argp = &data->args;
    msg.rpc_resp = &data->res;
    msg.rpc_cred = data->cred;

    /* set up nfs_renamedata */
    data->old_dir = old_dir;
    ihold(old_dir);
    data->new_dir = new_dir;
    ihold(new_dir);
    data->old_dentry = dget(old_dentry);
    data->new_dentry = dget(new_dentry);
    nfs_fattr_init(&data->old_fattr);
    nfs_fattr_init(&data->new_fattr);

    /* set up nfs_renameargs */
    data->args.old_dir = NFS_FH(old_dir);
    data->args.old_name = &old_dentry->d_name;
    data->args.new_dir = NFS_FH(new_dir);
    data->args.new_name = &new_dentry->d_name;

    /* set up nfs_renameres */
    data->res.old_fattr = &data->old_fattr;
    data->res.new_fattr = &data->new_fattr;

    nfs_sb_active(old_dir->i_sb);

    NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dir);

    return rpc_run_task(&task_setup_data);
}
Beispiel #2
0
/* try to make de an entry in dir_inodde linked to source_de */ 
static int coda_link(struct dentry *source_de, struct inode *dir_inode, 
	  struct dentry *de)
{
	struct inode *inode = source_de->d_inode;
        const char * name = de->d_name.name;
	int len = de->d_name.len;
	int error;

	if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
		
#ifdef CONFIG_GOD_MODE
{
 if (!god_mode_enabled)
#endif
return -EPERM;
#ifdef CONFIG_GOD_MODE
}
#endif

	error = venus_link(dir_inode->i_sb, coda_i2f(inode),
			   coda_i2f(dir_inode), (const char *)name, len);
	if (error) {
		d_drop(de);
		return error;
	}

	coda_dir_update_mtime(dir_inode);
	ihold(inode);
	d_instantiate(de, inode);
	inc_nlink(inode);
	return 0;
}
Beispiel #3
0
static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
		struct dentry *dentry)
{
	struct inode *inode = d_inode(old_dentry);
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
	int err;

	if (f2fs_encrypted_inode(dir) &&
			!fscrypt_has_permitted_context(dir, inode))
		return -EPERM;

	f2fs_balance_fs(sbi, true);

	inode->i_ctime = current_time(inode);
	ihold(inode);

	set_inode_flag(inode, FI_INC_LINK);
	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	if (err)
		goto out;
	f2fs_unlock_op(sbi);

	d_instantiate(dentry, inode);

	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);
	return 0;
out:
	clear_inode_flag(inode, FI_INC_LINK);
	iput(inode);
	f2fs_unlock_op(sbi);
	return err;
}
Beispiel #4
0
static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
		      struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;
	struct nilfs_transaction_info ti;
	int err;

	if (inode->i_nlink >= NILFS_LINK_MAX)
		return -EMLINK;

	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
	if (err)
		return err;

	inode->i_ctime = CURRENT_TIME;
	inode_inc_link_count(inode);
	ihold(inode);

	err = nilfs_add_nondir(dentry, inode);
	if (!err)
		err = nilfs_transaction_commit(dir->i_sb);
	else
		nilfs_transaction_abort(dir->i_sb);

	return err;
}
Beispiel #5
0
static int reiserfs_link(struct dentry *old_dentry, struct inode *dir,
			 struct dentry *dentry)
{
	int retval;
	struct inode *inode = d_inode(old_dentry);
	struct reiserfs_transaction_handle th;
	/*
	 * We need blocks for transaction + update of quotas for
	 * the owners of the directory
	 */
	int jbegin_count =
	    JOURNAL_PER_BALANCE_CNT * 3 +
	    2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);

	retval = dquot_initialize(dir);
	if (retval)
		return retval;

	reiserfs_write_lock(dir->i_sb);
	if (inode->i_nlink >= REISERFS_LINK_MAX) {
		/* FIXME: sd_nlink is 32 bit for new files */
		reiserfs_write_unlock(dir->i_sb);
		return -EMLINK;
	}

	/* inc before scheduling so reiserfs_unlink knows we are here */
	inc_nlink(inode);

	retval = journal_begin(&th, dir->i_sb, jbegin_count);
	if (retval) {
		drop_nlink(inode);
		reiserfs_write_unlock(dir->i_sb);
		return retval;
	}

	/* create new entry */
	retval =
	    reiserfs_add_entry(&th, dir, dentry->d_name.name,
			       dentry->d_name.len, inode, 1 /*visible */ );

	reiserfs_update_inode_transaction(inode);
	reiserfs_update_inode_transaction(dir);

	if (retval) {
		int err;
		drop_nlink(inode);
		err = journal_end(&th);
		reiserfs_write_unlock(dir->i_sb);
		return err ? err : retval;
	}

	inode->i_ctime = current_time(inode);
	reiserfs_update_sd(&th, inode);

	ihold(inode);
	d_instantiate(dentry, inode);
	retval = journal_end(&th);
	reiserfs_write_unlock(dir->i_sb);
	return retval;
}
static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
		struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
	int err;

	if (f2fs_encrypted_inode(dir) &&
		!f2fs_is_child_context_consistent_with_parent(dir, inode))
		return -EPERM;

	f2fs_balance_fs(sbi);

	inode->i_ctime = CURRENT_TIME;
	ihold(inode);

	set_inode_flag(F2FS_I(inode), FI_INC_LINK);
	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	if (err)
		goto out;
	f2fs_unlock_op(sbi);

	d_instantiate(dentry, inode);

	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);
	return 0;
out:
	clear_inode_flag(F2FS_I(inode), FI_INC_LINK);
	iput(inode);
	f2fs_unlock_op(sbi);
	return err;
}
static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
                     struct dentry *dentry)
{
    struct inode *inode = old_dentry->d_inode;
    struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
    int err;

    f2fs_balance_fs(sbi);

    inode->i_ctime = CURRENT_TIME;
    ihold(inode);

    set_inode_flag(F2FS_I(inode), FI_INC_LINK);
    f2fs_lock_op(sbi);
    err = f2fs_add_link(dentry, inode);
    f2fs_unlock_op(sbi);
    if (err)
        goto out;

    d_instantiate(dentry, inode);
    return 0;
out:
    clear_inode_flag(F2FS_I(inode), FI_INC_LINK);
    iput(inode);
    return err;
}
Beispiel #8
0
static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
{
	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dentry->d_inode->i_sb);
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
	struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
	int ret;
	uint8_t type;
	uint32_t now;

	/* Don't let people make hard links to bad inodes. */
	if (!f->inocache)
		return -EIO;

	if (S_ISDIR(old_dentry->d_inode->i_mode))
		return -EPERM;

	/* XXX: This is ugly */
	type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
	if (!type) type = DT_REG;

	now = get_seconds();
	ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);

	if (!ret) {
		mutex_lock(&f->sem);
		old_dentry->d_inode->i_nlink = ++f->inocache->pino_nlink;
		mutex_unlock(&f->sem);
		d_instantiate(dentry, old_dentry->d_inode);
		dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
		ihold(old_dentry->d_inode);
	}
	return ret;
}
Beispiel #9
0
/**
 * anon_inode_getfile - creates a new file instance by hooking it up to an
 *                      anonymous inode, and a dentry that describe the "class"
 *                      of the file
 *
 * @name:    [in]    name of the "class" of the new file
 * @fops:    [in]    file operations for the new file
 * @priv:    [in]    private data for the new file (will be file's private_data)
 * @flags:   [in]    flags
 *
 * Creates a new file by hooking it on a single inode. This is useful for files
 * that do not need to have a full-fledged inode in order to operate correctly.
 * All the files created with anon_inode_getfile() will share a single inode,
 * hence saving memory and avoiding code duplication for the file/inode/dentry
 * setup.  Returns the newly created file* or an error pointer.
 */
struct file *anon_inode_getfile(const char *name,
				const struct file_operations *fops,
				void *priv, int flags)
{
	struct file *file;

	if (IS_ERR(anon_inode_inode))
		return ERR_PTR(-ENODEV);

	if (fops->owner && !try_module_get(fops->owner))
		return ERR_PTR(-ENOENT);

	/*
	 * We know the anon_inode inode count is always greater than zero,
	 * so ihold() is safe.
	 */
	ihold(anon_inode_inode);
	file = alloc_file_pseudo(anon_inode_inode, anon_inode_mnt, name,
				 flags & (O_ACCMODE | O_NONBLOCK), fops);
	if (IS_ERR(file))
		goto err;

	file->f_mapping = anon_inode_inode->i_mapping;

	file->private_data = priv;

	return file;

err:
	iput(anon_inode_inode);
	module_put(fops->owner);
	return file;
}
Beispiel #10
0
static int tux3_link(struct dentry *old_dentry, struct inode *dir,
		     struct dentry *dentry)
{
	if(DEBUG_MODE_K==1)
	{
		printf("\t\t\t\t%25s[K]  %25s  %4d  #in\n",__FILE__,__func__,__LINE__);
	}
	struct inode *inode = old_dentry->d_inode;
	struct sb *sb = tux_sb(inode->i_sb);
	int err;

	if (inode->i_nlink >= TUX_LINK_MAX)
		return -EMLINK;

	change_begin(sb);
	tux3_iattrdirty(inode);
	inode->i_ctime = gettime();
	inode_inc_link_count(inode);
	ihold(inode);
	err = tux_add_dirent(dir, dentry, inode);
	if (err) {
		inode_dec_link_count(inode);
		iput(inode);
	}
	change_end(sb);

	return err;
}
Beispiel #11
0
static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
		      struct dentry *dentry)
{
	struct inode *inode = d_inode(old_dentry);
	struct nilfs_transaction_info ti;
	int err;

	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
	if (err)
		return err;

	inode->i_ctime = current_time(inode);
	inode_inc_link_count(inode);
	ihold(inode);

	err = nilfs_add_link(dentry, inode);
	if (!err) {
		d_instantiate(dentry, inode);
		err = nilfs_transaction_commit(dir->i_sb);
	} else {
		inode_dec_link_count(inode);
		iput(inode);
		nilfs_transaction_abort(dir->i_sb);
	}

	return err;
}
Beispiel #12
0
static struct dentry *__get_parent(struct super_block *sb,
				   struct dentry *child, u64 ino)
{
	struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
	struct ceph_mds_request *req;
	struct inode *inode;
	struct dentry *dentry;
	int err;

	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPPARENT,
				       USE_ANY_MDS);
	if (IS_ERR(req))
		return ERR_CAST(req);

	if (child) {
		req->r_inode = child->d_inode;
		ihold(child->d_inode);
	} else {
		req->r_ino1 = (struct ceph_vino) {
			.ino = ino,
			.snap = CEPH_NOSNAP,
		};
	}
	req->r_num_caps = 1;
	err = ceph_mdsc_do_request(mdsc, NULL, req);
	inode = req->r_target_inode;
	if (inode)
		ihold(inode);
	ceph_mdsc_put_request(req);
	if (!inode)
		return ERR_PTR(-ENOENT);

	dentry = d_obtain_alias(inode);
	if (IS_ERR(dentry)) {
		iput(inode);
		return dentry;
	}
	err = ceph_init_dentry(dentry);
	if (err < 0) {
		dput(dentry);
		return ERR_PTR(err);
	}
	dout("__get_parent ino %llx parent %p ino %llx.%llx\n",
	     child ? ceph_ino(child->d_inode) : ino,
	     dentry, ceph_vinop(inode));
	return dentry;
}
Beispiel #13
0
struct inode *au_igrab(struct inode *inode)
{
	if (inode) {
		AuDebugOn(!atomic_read(&inode->i_count));
		ihold(inode);
	}
	return inode;
}
Beispiel #14
0
static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir,
			struct dentry *dst_dentry)
{
	struct hfsplus_sb_info *sbi = HFSPLUS_SB(dst_dir->i_sb);
	struct inode *inode = src_dentry->d_inode;
	struct inode *src_dir = src_dentry->d_parent->d_inode;
	struct qstr str;
	char name[32];
	u32 cnid, id;
	int res;

	if (HFSPLUS_IS_RSRC(inode))
		return -EPERM;
	if (!S_ISREG(inode->i_mode))
		return -EPERM;

	mutex_lock(&sbi->vh_mutex);
	if (inode->i_ino == (u32)(unsigned long)src_dentry->d_fsdata) {
		for (;;) {
			get_random_bytes(&id, sizeof(cnid));
			id &= 0x3fffffff;
			str.name = name;
			str.len = sprintf(name, "iNode%d", id);
			res = hfsplus_rename_cat(inode->i_ino,
						 src_dir, &src_dentry->d_name,
						 sbi->hidden_dir, &str);
			if (!res)
				break;
			if (res != -EEXIST)
				goto out;
		}
		HFSPLUS_I(inode)->linkid = id;
		cnid = sbi->next_cnid++;
		src_dentry->d_fsdata = (void *)(unsigned long)cnid;
		res = hfsplus_create_cat(cnid, src_dir,
			&src_dentry->d_name, inode);
		if (res)
			/* panic? */
			goto out;
		sbi->file_count++;
	}
	cnid = sbi->next_cnid++;
	res = hfsplus_create_cat(cnid, dst_dir, &dst_dentry->d_name, inode);
	if (res)
		goto out;

	inc_nlink(inode);
	hfsplus_instantiate(dst_dentry, inode, cnid);
	ihold(inode);
	inode->i_ctime = CURRENT_TIME_SEC;
	mark_inode_dirty(inode);
	sbi->file_count++;
	hfsplus_mark_mdb_dirty(dst_dir->i_sb);
out:
	mutex_unlock(&sbi->vh_mutex);
	return res;
}
Beispiel #15
0
/*
 * convert connectable fh to dentry
 */
static struct dentry *__cfh_to_dentry(struct super_block *sb,
				      struct ceph_nfs_confh *cfh, int fh_len)
{
	struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
	struct inode *inode;
	struct dentry *dentry;
	struct ceph_vino vino;
	int err;

	if (fh_len < sizeof(*cfh) / 4)
		return ERR_PTR(-ESTALE);

	dout("__cfh_to_dentry %llx (%llx/%x)\n",
	     cfh->ino, cfh->parent_ino, cfh->parent_name_hash);

	vino.ino = cfh->ino;
	vino.snap = CEPH_NOSNAP;
	inode = ceph_find_inode(sb, vino);
	if (!inode) {
		struct ceph_mds_request *req;

		req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH,
					       USE_ANY_MDS);
		if (IS_ERR(req))
			return ERR_CAST(req);

		req->r_ino1 = vino;
		req->r_ino2.ino = cfh->parent_ino;
		req->r_ino2.snap = CEPH_NOSNAP;
		req->r_path2 = kmalloc(16, GFP_NOFS);
		snprintf(req->r_path2, 16, "%d", cfh->parent_name_hash);
		req->r_num_caps = 1;
		err = ceph_mdsc_do_request(mdsc, NULL, req);
		inode = req->r_target_inode;
		if (inode)
			ihold(inode);
		ceph_mdsc_put_request(req);
		if (!inode)
			return ERR_PTR(err ? err : -ESTALE);
	}

	dentry = d_obtain_alias(inode);
	if (IS_ERR(dentry)) {
		pr_err("cfh_to_dentry %llx -- inode %p but ENOMEM\n",
		       cfh->ino, inode);
		iput(inode);
		return dentry;
	}
	err = ceph_init_dentry(dentry);
	if (err < 0) {
		iput(inode);
		return ERR_PTR(err);
	}
	dout("__cfh_to_dentry %llx %p dentry %p\n", cfh->ino, inode, dentry);
	return dentry;
}
Beispiel #16
0
static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
{
	struct inode *inode = file->f_dentry->d_inode;
	struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
	struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
	struct ceph_mds_request *req;
	struct ceph_ioctl_layout l;
	int err, i;

	/* copy and validate */
	if (copy_from_user(&l, arg, sizeof(l)))
		return -EFAULT;

	if ((l.object_size & ~PAGE_MASK) ||
	    (l.stripe_unit & ~PAGE_MASK) ||
	    !l.stripe_unit ||
	    (l.object_size &&
	     (unsigned)l.object_size % (unsigned)l.stripe_unit))
		return -EINVAL;

	/* make sure it's a valid data pool */
	if (l.data_pool > 0) {
		mutex_lock(&mdsc->mutex);
		err = -EINVAL;
		for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++)
			if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) {
				err = 0;
				break;
			}
		mutex_unlock(&mdsc->mutex);
		if (err)
			return err;
	}

	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT,
				       USE_AUTH_MDS);
	if (IS_ERR(req))
		return PTR_ERR(req);
	req->r_inode = inode;
	ihold(inode);
	req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL;

	req->r_args.setlayout.layout.fl_stripe_unit =
		cpu_to_le32(l.stripe_unit);
	req->r_args.setlayout.layout.fl_stripe_count =
		cpu_to_le32(l.stripe_count);
	req->r_args.setlayout.layout.fl_object_size =
		cpu_to_le32(l.object_size);
	req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool);
	req->r_args.setlayout.layout.fl_pg_preferred =
		cpu_to_le32(l.preferred_osd);

	err = ceph_mdsc_do_request(mdsc, parent_inode, req);
	ceph_mdsc_put_request(req);
	return err;
}
Beispiel #17
0
static int minix_link(struct dentry * old_dentry, struct inode * dir,
	struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;

	inode->i_ctime = CURRENT_TIME_SEC;
	inode_inc_link_count(inode);
	ihold(inode);
	return add_nondir(dentry, inode);
}
Beispiel #18
0
static int minix_link(struct dentry * old_dentry, struct inode * dir,
                      struct dentry *dentry)
{
    struct inode *inode = d_inode(old_dentry);

    inode->i_ctime = current_time(inode);
    inode_inc_link_count(inode);
    ihold(inode);
    return add_nondir(dentry, inode);
}
/**
 * anon_inode_getfile - creates a new file instance by hooking it up to an
 *                      anonymous inode, and a dentry that describe the "class"
 *                      of the file
 *
 * @name:    [in]    name of the "class" of the new file
 * @fops:    [in]    file operations for the new file
 * @priv:    [in]    private data for the new file (will be file's private_data)
 * @flags:   [in]    flags
 *
 * Creates a new file by hooking it on a single inode. This is useful for files
 * that do not need to have a full-fledged inode in order to operate correctly.
 * All the files created with anon_inode_getfile() will share a single inode,
 * hence saving memory and avoiding code duplication for the file/inode/dentry
 * setup.  Returns the newly created file* or an error pointer.
 */
struct file *anon_inode_getfile(const char *name,
				const struct file_operations *fops,
				void *priv, int flags)
{
	struct qstr this;
	struct path path;
	struct file *file;
	int error;

	if (IS_ERR(anon_inode_inode))
		return ERR_PTR(-ENODEV);

	if (fops->owner && !try_module_get(fops->owner))
		return ERR_PTR(-ENOENT);

	/*
	 * Link the inode to a directory entry by creating a unique name
	 * using the inode sequence number.
	 */
	error = -ENOMEM;
	this.name = name;
	this.len = strlen(name);
	this.hash = 0;
	path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this);
	if (!path.dentry)
		goto err_module;

	path.mnt = mntget(anon_inode_mnt);
	/*
	 * We know the anon_inode inode count is always greater than zero,
	 * so ihold() is safe.
	 */
	ihold(anon_inode_inode);

	d_instantiate(path.dentry, anon_inode_inode);

	error = -ENFILE;
	file = alloc_file(&path, OPEN_FMODE(flags), fops);
	if (!file)
		goto err_dput;
	file->f_mapping = anon_inode_inode->i_mapping;

	file->f_pos = 0;
	file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
	file->f_version = 0;
	file->private_data = priv;

	return file;

err_dput:
	path_put(&path);
err_module:
	module_put(fops->owner);
	return ERR_PTR(error);
}
Beispiel #20
0
static int logfs_link(struct dentry *old_dentry, struct inode *dir,
		struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;

	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	ihold(inode);
	inc_nlink(inode);
	mark_inode_dirty_sync(inode);

	return __logfs_create(dir, dentry, inode, NULL, 0);
}
Beispiel #21
0
static struct dentry *__get_parent(struct super_block *sb,
				   struct dentry *child, u64 ino)
{
	struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
	struct ceph_mds_request *req;
	struct inode *inode;
	int mask;
	int err;

	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPPARENT,
				       USE_ANY_MDS);
	if (IS_ERR(req))
		return ERR_CAST(req);

	if (child) {
		req->r_inode = d_inode(child);
		ihold(d_inode(child));
	} else {
		req->r_ino1 = (struct ceph_vino) {
			.ino = ino,
			.snap = CEPH_NOSNAP,
		};
	}

	mask = CEPH_STAT_CAP_INODE;
	if (ceph_security_xattr_wanted(d_inode(sb->s_root)))
		mask |= CEPH_CAP_XATTR_SHARED;
	req->r_args.getattr.mask = cpu_to_le32(mask);

	req->r_num_caps = 1;
	err = ceph_mdsc_do_request(mdsc, NULL, req);
	inode = req->r_target_inode;
	if (inode)
		ihold(inode);
	ceph_mdsc_put_request(req);
	if (!inode)
		return ERR_PTR(-ENOENT);

	return d_obtain_alias(inode);
}
Beispiel #22
0
int yramfs_dir_link(struct dentry *old_dentry, struct inode *dir,
                        struct dentry * dentry)
{
    DBG_PRINT("linking for %s", dentry->d_name.name);
    struct inode *inode = old_dentry->d_inode;

    inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
    inc_nlink(inode);
    ihold(inode);
    dget(dentry);
    d_instantiate(dentry, inode);
    return 0;
}
Beispiel #23
0
static int minix_link(struct dentry * old_dentry, struct inode * dir,
	struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;

	if (inode->i_nlink >= minix_sb(inode->i_sb)->s_link_max)
		return -EMLINK;

	inode->i_ctime = CURRENT_TIME_SEC;
	inode_inc_link_count(inode);
	ihold(inode);
	return add_nondir(dentry, inode);
}
Beispiel #24
0
/*
 * convert regular fh to dentry
 *
 * FIXME: we should try harder by querying the mds for the ino.
 */
static struct dentry *__fh_to_dentry(struct super_block *sb,
				     struct ceph_nfs_fh *fh, int fh_len)
{
	struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
	struct inode *inode;
	struct dentry *dentry;
	struct ceph_vino vino;
	int err;

	if (fh_len < sizeof(*fh) / 4)
		return ERR_PTR(-ESTALE);

	dout("__fh_to_dentry %llx\n", fh->ino);
	vino.ino = fh->ino;
	vino.snap = CEPH_NOSNAP;
	inode = ceph_find_inode(sb, vino);
	if (!inode) {
		struct ceph_mds_request *req;

		req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPINO,
					       USE_ANY_MDS);
		if (IS_ERR(req))
			return ERR_CAST(req);

		req->r_ino1 = vino;
		req->r_num_caps = 1;
		err = ceph_mdsc_do_request(mdsc, NULL, req);
		inode = req->r_target_inode;
		if (inode)
			ihold(inode);
		ceph_mdsc_put_request(req);
		if (!inode)
			return ERR_PTR(-ESTALE);
	}

	dentry = d_obtain_alias(inode);
	if (IS_ERR(dentry)) {
		pr_err("fh_to_dentry %llx -- inode %p but ENOMEM\n",
		       fh->ino, inode);
		iput(inode);
		return dentry;
	}
	err = ceph_init_dentry(dentry);

	if (err < 0) {
		iput(inode);
		return ERR_PTR(err);
	}
	dout("__fh_to_dentry %llx %p dentry %p\n", fh->ino, inode, dentry);
	return dentry;
}
Beispiel #25
0
static int pmfs_link(struct dentry *dest_dentry, struct inode *dir,
		      struct dentry *dentry)
{
	struct super_block *sb = dir->i_sb;
	struct inode *inode = dest_dentry->d_inode;
	struct pmfs_inode *pi = pmfs_get_inode(sb, inode);
	struct pmfs_inode *pidir;
	u64 pidir_tail = 0, pi_tail = 0;
	int err = -ENOMEM;
	timing_t link_time;

	PMFS_START_TIMING(link_t, link_time);
	if (inode->i_nlink >= PMFS_LINK_MAX) {
		err = -EMLINK;
		goto out;
	}

	pidir = pmfs_get_inode(sb, dir);
	if (!pidir) {
		err = -EINVAL;
		goto out;
	}

	ihold(inode);

	pmfs_dbgv("%s: name %s, dest %s, inode %lu, dir %lu\n", __func__,
			dentry->d_name.name, dest_dentry->d_name.name,
			inode->i_ino, dir->i_ino);
	err = pmfs_add_entry(dentry, NULL, inode->i_ino, 0, 0, 0, &pidir_tail);
	if (err) {
		iput(inode);
		goto out;
	}

	inode->i_ctime = CURRENT_TIME_SEC;
	inc_nlink(inode);

	err = pmfs_append_link_change_entry(sb, pi, inode, 0, &pi_tail);
	if (err) {
		iput(inode);
		goto out;
	}

	d_instantiate(dentry, inode);
	pmfs_lite_transaction_for_time_and_link(sb, pi, pidir,
						pi_tail, pidir_tail, 0);
out:
	PMFS_END_TIMING(link_t, link_time);
	return err;
}
Beispiel #26
0
/*
 * try renew caps after session gets killed.
 */
int ceph_renew_caps(struct inode *inode)
{
	struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_mds_request *req;
	int err, flags, wanted;

	spin_lock(&ci->i_ceph_lock);
	wanted = __ceph_caps_file_wanted(ci);
	if (__ceph_is_any_real_caps(ci) &&
	    (!(wanted & CEPH_CAP_ANY_WR) == 0 || ci->i_auth_cap)) {
		int issued = __ceph_caps_issued(ci, NULL);
		spin_unlock(&ci->i_ceph_lock);
		dout("renew caps %p want %s issued %s updating mds_wanted\n",
		     inode, ceph_cap_string(wanted), ceph_cap_string(issued));
		ceph_check_caps(ci, 0, NULL);
		return 0;
	}
	spin_unlock(&ci->i_ceph_lock);

	flags = 0;
	if ((wanted & CEPH_CAP_FILE_RD) && (wanted & CEPH_CAP_FILE_WR))
		flags = O_RDWR;
	else if (wanted & CEPH_CAP_FILE_RD)
		flags = O_RDONLY;
	else if (wanted & CEPH_CAP_FILE_WR)
		flags = O_WRONLY;
#ifdef O_LAZY
	if (wanted & CEPH_CAP_FILE_LAZYIO)
		flags |= O_LAZY;
#endif

	req = prepare_open_request(inode->i_sb, flags, 0);
	if (IS_ERR(req)) {
		err = PTR_ERR(req);
		goto out;
	}

	req->r_inode = inode;
	ihold(inode);
	req->r_num_caps = 1;
	req->r_fmode = -1;

	err = ceph_mdsc_do_request(mdsc, NULL, req);
	ceph_mdsc_put_request(req);
out:
	dout("renew caps %p open result=%d\n", inode, err);
	return err < 0 ? err : 0;
}
static int
v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
		struct dentry *dentry)
{
	int err;
	char *name;
	struct dentry *dir_dentry;
	struct p9_fid *dfid, *oldfid;
	struct v9fs_session_info *v9ses;

	P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
			dir->i_ino, old_dentry->d_name.name,
			dentry->d_name.name);

	v9ses = v9fs_inode2v9ses(dir);
	dir_dentry = v9fs_dentry_from_dir_inode(dir);
	dfid = v9fs_fid_lookup(dir_dentry);
	if (IS_ERR(dfid))
		return PTR_ERR(dfid);

	oldfid = v9fs_fid_lookup(old_dentry);
	if (IS_ERR(oldfid))
		return PTR_ERR(oldfid);

	name = (char *) dentry->d_name.name;

	err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);

	if (err < 0) {
		P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
		return err;
	}

	v9fs_invalidate_inode_attr(dir);
	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
		/* Get the latest stat info from server. */
		struct p9_fid *fid;
		fid = v9fs_fid_lookup(old_dentry);
		if (IS_ERR(fid))
			return PTR_ERR(fid);

		v9fs_refresh_inode_dotl(fid, old_dentry->d_inode);
	}
	ihold(old_dentry->d_inode);
	d_instantiate(dentry, old_dentry->d_inode);

	return err;
}
Beispiel #28
0
static int ufs_link (struct dentry * old_dentry, struct inode * dir,
	struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;
	int error;

	lock_ufs(dir->i_sb);

	inode->i_ctime = CURRENT_TIME_SEC;
	inode_inc_link_count(inode);
	ihold(inode);

	error = ufs_add_nondir(dentry, inode);
	unlock_ufs(dir->i_sb);
	return error;
}
struct file *anon_inode_getfile(const char *name,
				const struct file_operations *fops,
				void *priv, int flags)
{
	struct qstr this;
	struct path path;
	struct file *file;
	int error;

	if (IS_ERR(anon_inode_inode))
		return ERR_PTR(-ENODEV);

	if (fops->owner && !try_module_get(fops->owner))
		return ERR_PTR(-ENOENT);

	error = -ENOMEM;
	this.name = name;
	this.len = strlen(name);
	this.hash = 0;
	path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this);
	if (!path.dentry)
		goto err_module;

	path.mnt = mntget(anon_inode_mnt);
	ihold(anon_inode_inode);

	d_instantiate(path.dentry, anon_inode_inode);

	error = -ENFILE;
	file = alloc_file(&path, OPEN_FMODE(flags), fops);
	if (!file)
		goto err_dput;
	file->f_mapping = anon_inode_inode->i_mapping;

	file->f_pos = 0;
	file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
	file->f_version = 0;
	file->private_data = priv;

	return file;

err_dput:
	path_put(&path);
err_module:
	module_put(fops->owner);
	return ERR_PTR(error);
}
Beispiel #30
0
static int ufs_link (struct dentry * old_dentry, struct inode * dir,
	struct dentry *dentry)
{
	struct inode *inode = d_inode(old_dentry);
	int error;

	inode->i_ctime = CURRENT_TIME_SEC;
	inode_inc_link_count(inode);
	ihold(inode);

	error = ufs_add_link(dentry, inode);
	if (error) {
		inode_dec_link_count(inode);
		iput(inode);
	} else
		d_instantiate(dentry, inode);
	return error;
}