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

📄 suballoc.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	int status;	u64 bg_blkno;	BUG_ON(!ac);	BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted));	BUG_ON(ac->ac_which != OCFS2_AC_USE_META);	status = ocfs2_claim_suballoc_bits(osb,					   ac,					   handle,					   bits_wanted,					   1,					   suballoc_bit_start,					   num_bits,					   &bg_blkno);	if (status < 0) {		mlog_errno(status);		goto bail;	}	atomic_inc(&osb->alloc_stats.bg_allocs);	*blkno_start = bg_blkno + (u64) *suballoc_bit_start;	ac->ac_bits_given += (*num_bits);	status = 0;bail:	mlog_exit(status);	return status;}int ocfs2_claim_new_inode(struct ocfs2_super *osb,			  handle_t *handle,			  struct ocfs2_alloc_context *ac,			  u16 *suballoc_bit,			  u64 *fe_blkno){	int status;	unsigned int num_bits;	u64 bg_blkno;	mlog_entry_void();	BUG_ON(!ac);	BUG_ON(ac->ac_bits_given != 0);	BUG_ON(ac->ac_bits_wanted != 1);	BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE);	status = ocfs2_claim_suballoc_bits(osb,					   ac,					   handle,					   1,					   1,					   suballoc_bit,					   &num_bits,					   &bg_blkno);	if (status < 0) {		mlog_errno(status);		goto bail;	}	atomic_inc(&osb->alloc_stats.bg_allocs);	BUG_ON(num_bits != 1);	*fe_blkno = bg_blkno + (u64) (*suballoc_bit);	ac->ac_bits_given++;	status = 0;bail:	mlog_exit(status);	return status;}/* translate a group desc. blkno and it's bitmap offset into * disk cluster offset. */static inline u32 ocfs2_desc_bitmap_to_cluster_off(struct inode *inode,						   u64 bg_blkno,						   u16 bg_bit_off){	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);	u32 cluster = 0;	BUG_ON(!ocfs2_is_cluster_bitmap(inode));	if (bg_blkno != osb->first_cluster_group_blkno)		cluster = ocfs2_blocks_to_clusters(inode->i_sb, bg_blkno);	cluster += (u32) bg_bit_off;	return cluster;}/* given a cluster offset, calculate which block group it belongs to * and return that block offset. */static inline u64 ocfs2_which_cluster_group(struct inode *inode,					    u32 cluster){	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);	u32 group_no;	BUG_ON(!ocfs2_is_cluster_bitmap(inode));	group_no = cluster / osb->bitmap_cpg;	if (!group_no)		return osb->first_cluster_group_blkno;	return ocfs2_clusters_to_blocks(inode->i_sb,					group_no * osb->bitmap_cpg);}/* given the block number of a cluster start, calculate which cluster * group and descriptor bitmap offset that corresponds to. */static inline void ocfs2_block_to_cluster_group(struct inode *inode,						u64 data_blkno,						u64 *bg_blkno,						u16 *bg_bit_off){	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);	u32 data_cluster = ocfs2_blocks_to_clusters(osb->sb, data_blkno);	BUG_ON(!ocfs2_is_cluster_bitmap(inode));	*bg_blkno = ocfs2_which_cluster_group(inode,					      data_cluster);	if (*bg_blkno == osb->first_cluster_group_blkno)		*bg_bit_off = (u16) data_cluster;	else		*bg_bit_off = (u16) ocfs2_blocks_to_clusters(osb->sb,							     data_blkno - *bg_blkno);}/* * min_bits - minimum contiguous chunk from this total allocation we * can handle. set to what we asked for originally for a full * contig. allocation, set to '1' to indicate we can deal with extents * of any size. */int __ocfs2_claim_clusters(struct ocfs2_super *osb,			   handle_t *handle,			   struct ocfs2_alloc_context *ac,			   u32 min_clusters,			   u32 max_clusters,			   u32 *cluster_start,			   u32 *num_clusters){	int status;	unsigned int bits_wanted = max_clusters;	u64 bg_blkno = 0;	u16 bg_bit_off;	mlog_entry_void();	BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted);	BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL	       && ac->ac_which != OCFS2_AC_USE_MAIN);	if (ac->ac_which == OCFS2_AC_USE_LOCAL) {		status = ocfs2_claim_local_alloc_bits(osb,						      handle,						      ac,						      bits_wanted,						      cluster_start,						      num_clusters);		if (!status)			atomic_inc(&osb->alloc_stats.local_data);	} else {		if (min_clusters > (osb->bitmap_cpg - 1)) {			/* The only paths asking for contiguousness			 * should know about this already. */			mlog(ML_ERROR, "minimum allocation requested exceeds "				       "group bitmap size!");			status = -ENOSPC;			goto bail;		}		/* clamp the current request down to a realistic size. */		if (bits_wanted > (osb->bitmap_cpg - 1))			bits_wanted = osb->bitmap_cpg - 1;		status = ocfs2_claim_suballoc_bits(osb,						   ac,						   handle,						   bits_wanted,						   min_clusters,						   &bg_bit_off,						   num_clusters,						   &bg_blkno);		if (!status) {			*cluster_start =				ocfs2_desc_bitmap_to_cluster_off(ac->ac_inode,								 bg_blkno,								 bg_bit_off);			atomic_inc(&osb->alloc_stats.bitmap_data);		}	}	if (status < 0) {		if (status != -ENOSPC)			mlog_errno(status);		goto bail;	}	ac->ac_bits_given += *num_clusters;bail:	mlog_exit(status);	return status;}int ocfs2_claim_clusters(struct ocfs2_super *osb,			 handle_t *handle,			 struct ocfs2_alloc_context *ac,			 u32 min_clusters,			 u32 *cluster_start,			 u32 *num_clusters){	unsigned int bits_wanted = ac->ac_bits_wanted - ac->ac_bits_given;	return __ocfs2_claim_clusters(osb, handle, ac, min_clusters,				      bits_wanted, cluster_start, num_clusters);}static inline int ocfs2_block_group_clear_bits(handle_t *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;	unsigned int tmp;	int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;	struct ocfs2_group_desc *undo_bg = NULL;	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;	}	mlog(0, "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;	}	if (ocfs2_is_cluster_bitmap(alloc_inode))		undo_bg = (struct ocfs2_group_desc *) bh2jh(group_bh)->b_committed_data;	tmp = num_bits;	while(tmp--) {		ocfs2_clear_bit((bit_off + tmp),				(unsigned long *) bg->bg_bitmap);		if (ocfs2_is_cluster_bitmap(alloc_inode))			ocfs2_set_bit(bit_off + tmp,				      (unsigned long *) undo_bg->bg_bitmap);	}	le16_add_cpu(&bg->bg_free_bits_count, num_bits);	status = ocfs2_journal_dirty(handle, group_bh);	if (status < 0)		mlog_errno(status);bail:	return status;}/* * expects the suballoc inode to already be locked. */int ocfs2_free_suballoc_bits(handle_t *handle,			     struct inode *alloc_inode,			     struct buffer_head *alloc_bh,			     unsigned int start_bit,			     u64 bg_blkno,			     unsigned int count){	int status = 0;	u32 tmp_used;	struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb);	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) alloc_bh->b_data;	struct ocfs2_chain_list *cl = &fe->id2.i_chain;	struct buffer_head *group_bh = NULL;	struct ocfs2_group_desc *group;	mlog_entry_void();	if (!OCFS2_IS_VALID_DINODE(fe)) {		OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe);		status = -EIO;		goto bail;	}	BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl));	mlog(0, "%llu: freeing %u bits from group %llu, starting at %u\n",	     (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count,	     (unsigned long long)bg_blkno, start_bit);	status = ocfs2_read_block(osb, bg_blkno, &group_bh, OCFS2_BH_CACHED,				  alloc_inode);	if (status < 0) {		mlog_errno(status);		goto bail;	}	group = (struct ocfs2_group_desc *) group_bh->b_data;	status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, group);	if (status) {		mlog_errno(status);		goto bail;	}	BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits));	status = ocfs2_block_group_clear_bits(handle, alloc_inode,					      group, group_bh,					      start_bit, count);	if (status < 0) {		mlog_errno(status);		goto bail;	}	status = ocfs2_journal_access(handle, alloc_inode, alloc_bh,				      OCFS2_JOURNAL_ACCESS_WRITE);	if (status < 0) {		mlog_errno(status);		goto bail;	}	le32_add_cpu(&cl->cl_recs[le16_to_cpu(group->bg_chain)].c_free,		     count);	tmp_used = le32_to_cpu(fe->id1.bitmap1.i_used);	fe->id1.bitmap1.i_used = cpu_to_le32(tmp_used - count);	status = ocfs2_journal_dirty(handle, alloc_bh);	if (status < 0) {		mlog_errno(status);		goto bail;	}bail:	if (group_bh)		brelse(group_bh);	mlog_exit(status);	return status;}int ocfs2_free_dinode(handle_t *handle,		      struct inode *inode_alloc_inode,		      struct buffer_head *inode_alloc_bh,		      struct ocfs2_dinode *di){	u64 blk = le64_to_cpu(di->i_blkno);	u16 bit = le16_to_cpu(di->i_suballoc_bit);	u64 bg_blkno = ocfs2_which_suballoc_group(blk, bit);	return ocfs2_free_suballoc_bits(handle, inode_alloc_inode,					inode_alloc_bh, bit, bg_blkno, 1);}int ocfs2_free_clusters(handle_t *handle,		       struct inode *bitmap_inode,		       struct buffer_head *bitmap_bh,		       u64 start_blk,		       unsigned int num_clusters){	int status;	u16 bg_start_bit;	u64 bg_blkno;	struct ocfs2_dinode *fe;	/* You can't ever have a contiguous set of clusters	 * bigger than a block group bitmap so we never have to worry	 * about looping on them. */	mlog_entry_void();	/* This is expensive. We can safely remove once this stuff has	 * gotten tested really well. */	BUG_ON(start_blk != ocfs2_clusters_to_blocks(bitmap_inode->i_sb, ocfs2_blocks_to_clusters(bitmap_inode->i_sb, start_blk)));	fe = (struct ocfs2_dinode *) bitmap_bh->b_data;	ocfs2_block_to_cluster_group(bitmap_inode, start_blk, &bg_blkno,				     &bg_start_bit);	mlog(0, "want to free %u clusters starting at block %llu\n",	     num_clusters, (unsigned long long)start_blk);	mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n",	     (unsigned long long)bg_blkno, bg_start_bit);	status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,					  bg_start_bit, bg_blkno,					  num_clusters);	if (status < 0)		mlog_errno(status);	mlog_exit(status);	return status;}static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg){	printk("Block Group:\n");	printk("bg_signature:       %s\n", bg->bg_signature);	printk("bg_size:            %u\n", bg->bg_size);	printk("bg_bits:            %u\n", bg->bg_bits);	printk("bg_free_bits_count: %u\n", bg->bg_free_bits_count);	printk("bg_chain:           %u\n", bg->bg_chain);	printk("bg_generation:      %u\n", le32_to_cpu(bg->bg_generation));	printk("bg_next_group:      %llu\n",	       (unsigned long long)bg->bg_next_group);	printk("bg_parent_dinode:   %llu\n",	       (unsigned long long)bg->bg_parent_dinode);	printk("bg_blkno:           %llu\n",	       (unsigned long long)bg->bg_blkno);}static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe){	int i;	printk("Suballoc Inode %llu:\n", (unsigned long long)fe->i_blkno);	printk("i_signature:                  %s\n", fe->i_signature);	printk("i_size:                       %llu\n",	       (unsigned long long)fe->i_size);	printk("i_clusters:                   %u\n", fe->i_clusters);	printk("i_generation:                 %u\n",	       le32_to_cpu(fe->i_generation));	printk("id1.bitmap1.i_used:           %u\n",	       le32_to_cpu(fe->id1.bitmap1.i_used));	printk("id1.bitmap1.i_total:          %u\n",	       le32_to_cpu(fe->id1.bitmap1.i_total));	printk("id2.i_chain.cl_cpg:           %u\n", fe->id2.i_chain.cl_cpg);	printk("id2.i_chain.cl_bpc:           %u\n", fe->id2.i_chain.cl_bpc);	printk("id2.i_chain.cl_count:         %u\n", fe->id2.i_chain.cl_count);	printk("id2.i_chain.cl_next_free_rec: %u\n",	       fe->id2.i_chain.cl_next_free_rec);	for(i = 0; i < fe->id2.i_chain.cl_next_free_rec; i++) {		printk("fe->id2.i_chain.cl_recs[%d].c_free:  %u\n", i,		       fe->id2.i_chain.cl_recs[i].c_free);		printk("fe->id2.i_chain.cl_recs[%d].c_total: %u\n", i,		       fe->id2.i_chain.cl_recs[i].c_total);		printk("fe->id2.i_chain.cl_recs[%d].c_blkno: %llu\n", i,		       (unsigned long long)fe->id2.i_chain.cl_recs[i].c_blkno);	}}

⌨️ 快捷键说明

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