⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 suballoc.c

📁 ocfs1.2.7 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe);		status = -EIO;		goto bail;	}	if (!(fe->i_flags & cpu_to_le32(OCFS2_CHAIN_FL))) {		ocfs2_error(alloc_inode->i_sb, "Invalid chain allocator "			    "# %"MLFu64, le64_to_cpu(fe->i_blkno));		status = -EIO;		goto bail;	}	free_bits = le32_to_cpu(fe->id1.bitmap1.i_total) -		le32_to_cpu(fe->id1.bitmap1.i_used);	if (bits_wanted > free_bits) {		/* cluster bitmap never grows */		if (ocfs2_is_cluster_bitmap(alloc_inode)) {			mlog(0, "Disk Full: wanted=%u, free_bits=%u\n",			     bits_wanted, free_bits);			status = -ENOSPC;			goto bail;		}		status = ocfs2_block_group_alloc(osb, alloc_inode, bh);		if (status < 0) {			if (status != -ENOSPC)				mlog_errno(status);			goto bail;		}		atomic_inc(&osb->alloc_stats.bg_extends);		/* You should never ask for this much metadata */		BUG_ON(bits_wanted >		       (le32_to_cpu(fe->id1.bitmap1.i_total)			- le32_to_cpu(fe->id1.bitmap1.i_used)));	}	get_bh(bh);	ac->ac_bh = bh;bail:	if (bh)		brelse(bh);	mlog_exit(status);	return status;}int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,			       struct ocfs2_journal_handle *handle,			       struct ocfs2_dinode *fe,			       struct ocfs2_alloc_context **ac){	int status;	struct inode *alloc_inode = NULL;	*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);	if (!(*ac)) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	(*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe);	(*ac)->ac_handle = handle;	(*ac)->ac_which = OCFS2_AC_USE_META;#ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS	alloc_inode = ocfs2_get_system_file_inode(osb,						  EXTENT_ALLOC_SYSTEM_INODE,						  0);#else	alloc_inode = ocfs2_get_system_file_inode(osb,						  EXTENT_ALLOC_SYSTEM_INODE,						  osb->slot_num);#endif	if (!alloc_inode) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	(*ac)->ac_inode = igrab(alloc_inode);	(*ac)->ac_group_search = ocfs2_block_group_search;	status = ocfs2_reserve_suballoc_bits(osb, (*ac));	if (status < 0) {		if (status != -ENOSPC)			mlog_errno(status);		goto bail;	}	status = 0;bail:	if ((status < 0) && *ac) {		ocfs2_free_alloc_context(*ac);		*ac = NULL;	}	if (alloc_inode)		iput(alloc_inode);	mlog_exit(status);	return status;}int ocfs2_reserve_new_inode(struct ocfs2_super *osb,			    struct ocfs2_journal_handle *handle,			    struct ocfs2_alloc_context **ac){	int status;	struct inode *alloc_inode = NULL;	*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);	if (!(*ac)) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	(*ac)->ac_bits_wanted = 1;	(*ac)->ac_handle = handle;	(*ac)->ac_which = OCFS2_AC_USE_INODE;	alloc_inode = ocfs2_get_system_file_inode(osb,						  INODE_ALLOC_SYSTEM_INODE,						  osb->slot_num);	if (!alloc_inode) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	(*ac)->ac_inode = igrab(alloc_inode);	(*ac)->ac_group_search = ocfs2_block_group_search;	status = ocfs2_reserve_suballoc_bits(osb, *ac);	if (status < 0) {		if (status != -ENOSPC)			mlog_errno(status);		goto bail;	}	status = 0;bail:	if ((status < 0) && *ac) {		ocfs2_free_alloc_context(*ac);		*ac = NULL;	}	if (alloc_inode)		iput(alloc_inode);	mlog_exit(status);	return status;}/* local alloc code has to do the same thing, so rather than do this * twice.. */int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb,				      struct ocfs2_alloc_context *ac){	int status;	ac->ac_inode = ocfs2_get_system_file_inode(osb,						   GLOBAL_BITMAP_SYSTEM_INODE,						   OCFS2_INVALID_SLOT);	if (!ac->ac_inode) {		status = -EINVAL;		mlog(ML_ERROR, "Could not get bitmap inode!\n");		goto bail;	}	ac->ac_which = OCFS2_AC_USE_MAIN;	ac->ac_group_search = ocfs2_cluster_group_search;	status = ocfs2_reserve_suballoc_bits(osb, ac);	if (status < 0 && status != -ENOSPC)		mlog_errno(status);bail:	return status;}/* Callers don't need to care which bitmap (local alloc or main) to * use so we figure it out for them, but unfortunately this clutters * things a bit. */int ocfs2_reserve_clusters(struct ocfs2_super *osb,			   struct ocfs2_journal_handle *handle,			   u32 bits_wanted,			   struct ocfs2_alloc_context **ac){	int status;	mlog_entry_void();	BUG_ON(!handle);	*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);	if (!(*ac)) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	(*ac)->ac_bits_wanted = bits_wanted;	(*ac)->ac_handle = handle;	status = -ENOSPC;	if (ocfs2_alloc_should_use_local(osb, bits_wanted)) {		status = ocfs2_reserve_local_alloc_bits(osb,							handle,							bits_wanted,							*ac);		if ((status < 0) && (status != -ENOSPC)) {			mlog_errno(status);			goto bail;		} else if (status == -ENOSPC) {			/* reserve_local_bits will return enospc with			 * the local alloc inode still locked, so we			 * can change this safely here. */			mlog(0, "Disabling local alloc\n");			/* We set to OCFS2_LA_DISABLED so that umount			 * can clean up what's left of the local			 * allocation */			osb->local_alloc_state = OCFS2_LA_DISABLED;		}	}	if (status == -ENOSPC) {		status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);		if (status < 0) {			if (status != -ENOSPC)				mlog_errno(status);			goto bail;		}	}	status = 0;bail:	if ((status < 0) && *ac) {		ocfs2_free_alloc_context(*ac);		*ac = NULL;	}	mlog_exit(status);	return status;}/* * More or less lifted from ext3. I'll leave their description below: * * "For ext3 allocations, we must not reuse any blocks which are * allocated in the bitmap buffer's "last committed data" copy.  This * prevents deletes from freeing up the page for reuse until we have * committed the delete transaction. * * If we didn't do this, then deleting something and reallocating it as * data would allow the old block to be overwritten before the * transaction committed (because we force data to disk before commit). * This would lead to corruption if we crashed between overwriting the * data and committing the delete. * * @@@ We may want to make this allocation behaviour conditional on * data-writes at some point, and disable it for metadata allocations or * sync-data inodes." * * Note: OCFS2 already does this differently for metadata vs data * allocations, as those bitmaps are seperate and undo access is never * called on a metadata group descriptor. */static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,					 int nr){	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;	if (ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap))		return 0;	if (!buffer_jbd(bg_bh) || !bh2jh(bg_bh)->b_committed_data)		return 1;	bg = (struct ocfs2_group_desc *) bh2jh(bg_bh)->b_committed_data;	return !ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap);}static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb,					     struct buffer_head *bg_bh,					     unsigned int bits_wanted,					     unsigned int total_bits,					     u16 *bit_off,					     u16 *bits_found){	void *bitmap;	u16 best_offset, best_size;	int offset, start, found, status = 0;	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;	if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {		OCFS2_RO_ON_INVALID_GROUP_DESC(osb->sb, bg);		return -EIO;	}	found = start = best_offset = best_size = 0;	bitmap = bg->bg_bitmap;	while((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) != -1) {		if (offset == total_bits)			break;		if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) {			/* We found a zero, but we can't use it as it			 * hasn't been put to disk yet! */			found = 0;			start = offset + 1;		} else if (offset == start) {			/* we found a zero */			found++;			/* move start to the next bit to test */			start++;		} else {			/* got a zero after some ones */			found = 1;			start = offset + 1;		}		if (found > best_size) {			best_size = found;			best_offset = start - found;		}		/* we got everything we needed */		if (found == bits_wanted) {			/* mlog(0, "Found it all!\n"); */			break;		}	}	/* XXX: I think the first clause is equivalent to the second	 * 	- jlbec */	if (found == bits_wanted) {		*bit_off = start - found;		*bits_found = found;	} else if (best_size) {		*bit_off = best_offset;		*bits_found = best_size;	} else {		status = -ENOSPC;		/* No error log here -- see the comment above		 * ocfs2_test_bg_bit_allocatable */	}	return status;}static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle,					     struct inode *alloc_inode,					     struct ocfs2_group_desc *bg,					     struct buffer_head *group_bh,					     unsigned int bit_off,					     unsigned int num_bits){	int status;	void *bitmap = bg->bg_bitmap;	int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;	mlog_entry_void();	if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);		status = -EIO;		goto bail;	}	BUG_ON(le16_to_cpu(bg->bg_free_bits_count) < num_bits);	mlog(0, "block_group_set_bits: off = %u, num = %u\n", bit_off,	     num_bits);	if (ocfs2_is_cluster_bitmap(alloc_inode))		journal_type = OCFS2_JOURNAL_ACCESS_UNDO;	status = ocfs2_journal_access(handle,				      alloc_inode,				      group_bh,				      journal_type);	if (status < 0) {		mlog_errno(status);		goto bail;	}	le16_add_cpu(&bg->bg_free_bits_count, -num_bits);	while(num_bits--)		ocfs2_set_bit(bit_off++, bitmap);	status = ocfs2_journal_dirty(handle,				     group_bh);	if (status < 0) {		mlog_errno(status);		goto bail;	}bail:	mlog_exit(status);	return status;}/* find the one with the most empty bits */static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl){	u16 curr, best;	BUG_ON(!cl->cl_next_free_rec);	best = curr = 0;	while (curr < le16_to_cpu(cl->cl_next_free_rec)) {		if (le32_to_cpu(cl->cl_recs[curr].c_free) >		    le32_to_cpu(cl->cl_recs[best].c_free))			best = curr;		curr++;	}	BUG_ON(best >= le16_to_cpu(cl->cl_next_free_rec));	return best;}static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle,				    struct inode *alloc_inode,				    struct buffer_head *fe_bh,				    struct buffer_head *bg_bh,				    struct buffer_head *prev_bg_bh,				    u16 chain){	int status;	/* there is a really tiny chance the journal calls could fail,	 * but we wouldn't want inconsistent blocks in *any* case. */	u64 fe_ptr, bg_ptr, prev_bg_ptr;	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -