[Ocfs2-devel] [PATCH 04/15] Make extend allocation generic.

Joel Becker Joel.Becker at oracle.com
Thu Aug 14 13:01:44 PDT 2008


On Thu, Aug 07, 2008 at 06:31:26AM +0800, Tao Ma wrote:
> The old ocfs2_do_extend_allocation is restrictly to be used in file
> extension. Now a new function named ocfs2_do_cluster_allocation will
> handle the issue of generic extend allocation and it is created in
> suballoc.c.

<snip> 

> +int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
> +				struct inode *inode,
> +				u32 *logical_offset,
> +				u32 clusters_to_add,
> +				int mark_unwritten,
> +				struct buffer_head *root_bh,
> +				struct ocfs2_extent_list *root_el,
> +				handle_t *handle,
> +				struct ocfs2_alloc_context *data_ac,
> +				struct ocfs2_alloc_context *meta_ac,
> +				enum ocfs2_alloc_restarted *reason_ret,
> +				enum ocfs2_extent_tree_type type)

	It seems to me that if you have root_bh and type, you can create
an ocfs2_extent_tree and calculate root_el from that.  So you don't need
root_el in this function's arguments, and callers don't need to know how
to compute it.

Joel

> +{
> +	int status = 0;
> +	int free_extents;
> +	enum ocfs2_alloc_restarted reason = RESTART_NONE;
> +	u32 bit_off, num_bits;
> +	u64 block;
> +	u8 flags = 0;
> +
> +	BUG_ON(!clusters_to_add);
> +
> +	if (mark_unwritten)
> +		flags = OCFS2_EXT_UNWRITTEN;
> +
> +	free_extents = ocfs2_num_free_extents(osb, inode, root_bh, type);
> +	if (free_extents < 0) {
> +		status = free_extents;
> +		mlog_errno(status);
> +		goto leave;
> +	}
> +
> +	/* there are two cases which could cause us to EAGAIN in the
> +	 * we-need-more-metadata case:
> +	 * 1) we haven't reserved *any*
> +	 * 2) we are so fragmented, we've needed to add metadata too
> +	 *    many times. */
> +	if (!free_extents && !meta_ac) {
> +		mlog(0, "we haven't reserved any metadata!\n");
> +		status = -EAGAIN;
> +		reason = RESTART_META;
> +		goto leave;
> +	} else if ((!free_extents)
> +		   && (ocfs2_alloc_context_bits_left(meta_ac)
> +		       < ocfs2_extend_meta_needed(root_el))) {
> +		mlog(0, "filesystem is really fragmented...\n");
> +		status = -EAGAIN;
> +		reason = RESTART_META;
> +		goto leave;
> +	}
> +
> +	status = __ocfs2_claim_clusters(osb, handle, data_ac, 1,
> +					clusters_to_add, &bit_off, &num_bits);
> +	if (status < 0) {
> +		if (status != -ENOSPC)
> +			mlog_errno(status);
> +		goto leave;
> +	}
> +
> +	BUG_ON(num_bits > clusters_to_add);
> +
> +	/* reserve our write early -- insert_extent may update the inode */
> +	status = ocfs2_journal_access(handle, inode, root_bh,
> +				      OCFS2_JOURNAL_ACCESS_WRITE);
> +	if (status < 0) {
> +		mlog_errno(status);
> +		goto leave;
> +	}
> +
> +	block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
> +	mlog(0, "Allocating %u clusters at block %u for inode %llu\n",
> +	     num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
> +	status = ocfs2_insert_extent(osb, handle, inode, root_bh,
> +				     *logical_offset, block, num_bits,
> +				     flags, meta_ac, type);
> +	if (status < 0) {
> +		mlog_errno(status);
> +		goto leave;
> +	}
> +
> +	status = ocfs2_journal_dirty(handle, root_bh);
> +	if (status < 0) {
> +		mlog_errno(status);
> +		goto leave;
> +	}
> +
> +	clusters_to_add -= num_bits;
> +	*logical_offset += num_bits;
> +
> +	if (clusters_to_add) {
> +		mlog(0, "need to alloc once more, wanted = %u\n",
> +		     clusters_to_add);
> +		status = -EAGAIN;
> +		reason = RESTART_TRANS;
> +	}
> +
> +leave:
> +	mlog_exit(status);
> +	if (reason_ret)
> +		*reason_ret = reason;
> +	return status;
> +}

-- 

"You don't make the poor richer by making the rich poorer."
	- Sir Winston Churchill

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127



More information about the Ocfs2-devel mailing list