static int reserve_tail2extent_iteration(struct inode *inode)
{
	reiser4_block_nr unformatted_nodes;
	reiser4_tree *tree;

	tree = reiser4_tree_by_inode(inode);

	/* number of unformatted nodes which will be created */
	unformatted_nodes = TAIL2EXTENT_PAGE_NUM;

	/*
	 * space required for one iteration of extent->tail conversion:
	 *
	 *     1. kill N tail items
	 *
	 *     2. insert TAIL2EXTENT_PAGE_NUM unformatted nodes
	 *
	 *     3. insert TAIL2EXTENT_PAGE_NUM (worst-case single-block
	 *     extents) extent units.
	 *
	 *     4. drilling to the leaf level by coord_by_key()
	 *
	 *     5. possible update of stat-data
	 *
	 */
	grab_space_enable();
	return reiser4_grab_space
	    (2 * tree->height +
	     TAIL2EXTENT_PAGE_NUM +
	     TAIL2EXTENT_PAGE_NUM * estimate_one_insert_into_item(tree) +
	     1 + estimate_one_insert_item(tree) +
	     inode_file_plugin(inode)->estimate.update(inode), BA_CAN_COMMIT);
}
示例#2
0
/**
 * reiser4_delete_dir_common - delete_object of file_plugin
 * @inode: inode to be deleted
 *
 * This is common implementation of delete_object method of file_plugin for
 * typical directory. It calls done method of dir_plugin to remove "." and
 * removes stat data and safe-link.
 */
int reiser4_delete_dir_common(struct inode *inode)
{
	int result;
	dir_plugin *dplug;

	assert("", (get_current_context() &&
		    get_current_context()->trans->atom == NULL));

	dplug = inode_dir_plugin(inode);
	assert("vs-1101", dplug && dplug->done);

	/* kill cursors which might be attached to inode */
	reiser4_kill_cursors(inode);

	/* grab space enough for removing two items */
	if (reiser4_grab_space
	    (2 * estimate_one_item_removal(reiser4_tree_by_inode(inode)),
	     BA_RESERVED | BA_CAN_COMMIT))
		return RETERR(-ENOSPC);

	result = dplug->done(inode);
	if (!result)
		result = common_object_delete_no_reserve(inode);
	return result;
}
示例#3
0
/* this is common implementation of create_object method of file plugin
 */
int reiser4_create_object_common(struct inode *object, struct inode *parent,
				 reiser4_object_create_data * data)
{
	reiser4_block_nr reserve;
	assert("nikita-744", object != NULL);
	assert("nikita-745", parent != NULL);
	assert("nikita-747", data != NULL);
	assert("nikita-748", reiser4_inode_get_flag(object, REISER4_NO_SD));

	reserve = estimate_create_common(object);
	if (reiser4_grab_space(reserve, BA_CAN_COMMIT))
		return RETERR(-ENOSPC);
	return write_sd_by_inode_common(object);
}
示例#4
0
int reiser4_grab_reserved(struct super_block *super,
			  __u64 count, reiser4_ba_flags_t flags)
{
	reiser4_super_info_data *sbinfo = get_super_private(super);

	assert("nikita-3175", flags & BA_CAN_COMMIT);

	/* Check the delete mutex already taken by us, we assume that
	 * reading of machine word is atomic. */
	if (sbinfo->delete_mutex_owner == current) {
		if (reiser4_grab_space
		    (count, (flags | BA_RESERVED) & ~BA_CAN_COMMIT)) {
			warning("zam-1003",
				"nested call of grab_reserved fails count=(%llu)",
				(unsigned long long)count);
			reiser4_release_reserved(super);
			return RETERR(-ENOSPC);
		}
		return 0;
	}

	if (reiser4_grab_space(count, flags)) {
		mutex_lock(&sbinfo->delete_mutex);
		assert("nikita-2929", sbinfo->delete_mutex_owner == NULL);
		sbinfo->delete_mutex_owner = current;

		if (reiser4_grab_space(count, flags | BA_RESERVED)) {
			warning("zam-833",
				"reserved space is not enough (%llu)",
				(unsigned long long)count);
			reiser4_release_reserved(super);
			return RETERR(-ENOSPC);
		}
	}
	return 0;
}
/* clear stat data's flag indicating that conversion is being converted */
static int complete_conversion(struct inode *inode)
{
	int result;

	grab_space_enable();
	result =
	    reiser4_grab_space(inode_file_plugin(inode)->estimate.update(inode),
			       BA_CAN_COMMIT);
	if (result == 0) {
		reiser4_inode_clr_flag(inode, REISER4_PART_MIXED);
		result = reiser4_update_sd(inode);
	}
	if (result)
		warning("vs-1696", "Failed to clear converting bit of %llu: %i",
			(unsigned long long)get_inode_oid(inode), result);
	return 0;
}
static int reserve_extent2tail_iteration(struct inode *inode)
{
	reiser4_tree *tree;

	tree = reiser4_tree_by_inode(inode);
	/*
	 * reserve blocks for (in this order):
	 *
	 *     1. removal of extent item
	 *
	 *     2. insertion of tail by insert_flow()
	 *
	 *     3. drilling to the leaf level by coord_by_key()
	 *
	 *     4. possible update of stat-data
	 */
	grab_space_enable();
	return reiser4_grab_space
	    (estimate_one_item_removal(tree) +
	     estimate_insert_flow(tree->height) +
	     1 + estimate_one_insert_item(tree) +
	     inode_file_plugin(inode)->estimate.update(inode), BA_CAN_COMMIT);
}
示例#7
0
/*
 * common sync method for regular files.
 *
 * We are trying to be smart here. Instead of committing all atoms (original
 * solution), we scan dirty pages of this file and commit all atoms they are
 * part of.
 *
 * Situation is complicated by anonymous pages: i.e., extent-less pages
 * dirtied through mmap. Fortunately sys_fsync() first calls
 * filemap_fdatawrite() that will ultimately call reiser4_writepages(), insert
 * all missing extents and capture anonymous pages.
 */
int reiser4_sync_file_common(struct file *file,
			     struct dentry *dentry, int datasync)
{
	reiser4_context *ctx;
	txn_atom *atom;
	reiser4_block_nr reserve;

	ctx = reiser4_init_context(dentry->d_inode->i_sb);
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);

	reserve = estimate_update_common(dentry->d_inode);
	if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) {
		reiser4_exit_context(ctx);
		return RETERR(-ENOSPC);
	}
	write_sd_by_inode_common(dentry->d_inode);

	atom = get_current_atom_locked();
	spin_lock_txnh(ctx->trans);
	force_commit_atom(ctx->trans);
	reiser4_exit_context(ctx);
	return 0;
}