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

📄 bitmap.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		DQUOT_FREE_BLOCK_NODIRTY(inode, 1);}void reiserfs_free_block(struct reiserfs_transaction_handle *th,			 struct inode *inode, b_blocknr_t block,			 int for_unformatted){	struct super_block *s = th->t_super;	BUG_ON(!th->t_trans_id);	RFALSE(!s, "vs-4061: trying to free block on nonexistent device");	if (!is_reusable(s, block, 1))		return;	if (block > sb_block_count(REISERFS_SB(s)->s_rs)) {		reiserfs_panic(th->t_super, "bitmap-4072",			       "Trying to free block outside file system "			       "boundaries (%lu > %lu)",			       block, sb_block_count(REISERFS_SB(s)->s_rs));		return;	}	/* mark it before we clear it, just in case */	journal_mark_freed(th, s, block);	_reiserfs_free_block(th, inode, block, for_unformatted);}/* preallocated blocks don't need to be run through journal_mark_freed */static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th,					 struct inode *inode, b_blocknr_t block){	BUG_ON(!th->t_trans_id);	RFALSE(!th->t_super,	       "vs-4060: trying to free block on nonexistent device");	if (!is_reusable(th->t_super, block, 1))		return;	_reiserfs_free_block(th, inode, block, 1);}static void __discard_prealloc(struct reiserfs_transaction_handle *th,			       struct reiserfs_inode_info *ei){	unsigned long save = ei->i_prealloc_block;	int dirty = 0;	struct inode *inode = &ei->vfs_inode;	BUG_ON(!th->t_trans_id);#ifdef CONFIG_REISERFS_CHECK	if (ei->i_prealloc_count < 0)		reiserfs_warning(th->t_super,				 "zam-4001:%s: inode has negative prealloc blocks count.",				 __FUNCTION__);#endif	while (ei->i_prealloc_count > 0) {		reiserfs_free_prealloc_block(th, inode, ei->i_prealloc_block);		ei->i_prealloc_block++;		ei->i_prealloc_count--;		dirty = 1;	}	if (dirty)		reiserfs_update_sd(th, inode);	ei->i_prealloc_block = save;	list_del_init(&(ei->i_prealloc_list));}/* FIXME: It should be inline function */void reiserfs_discard_prealloc(struct reiserfs_transaction_handle *th,			       struct inode *inode){	struct reiserfs_inode_info *ei = REISERFS_I(inode);	BUG_ON(!th->t_trans_id);	if (ei->i_prealloc_count)		__discard_prealloc(th, ei);}void reiserfs_discard_all_prealloc(struct reiserfs_transaction_handle *th){	struct list_head *plist = &SB_JOURNAL(th->t_super)->j_prealloc_list;	BUG_ON(!th->t_trans_id);	while (!list_empty(plist)) {		struct reiserfs_inode_info *ei;		ei = list_entry(plist->next, struct reiserfs_inode_info,				i_prealloc_list);#ifdef CONFIG_REISERFS_CHECK		if (!ei->i_prealloc_count) {			reiserfs_warning(th->t_super,					 "zam-4001:%s: inode is in prealloc list but has no preallocated blocks.",					 __FUNCTION__);		}#endif		__discard_prealloc(th, ei);	}}void reiserfs_init_alloc_options(struct super_block *s){	set_bit(_ALLOC_skip_busy, &SB_ALLOC_OPTS(s));	set_bit(_ALLOC_dirid_groups, &SB_ALLOC_OPTS(s));	set_bit(_ALLOC_packing_groups, &SB_ALLOC_OPTS(s));}/* block allocator related options are parsed here */int reiserfs_parse_alloc_options(struct super_block *s, char *options){	char *this_char, *value;	REISERFS_SB(s)->s_alloc_options.bits = 0;	/* clear default settings */	while ((this_char = strsep(&options, ":")) != NULL) {		if ((value = strchr(this_char, '=')) != NULL)			*value++ = 0;		if (!strcmp(this_char, "concentrating_formatted_nodes")) {			int temp;			SET_OPTION(concentrating_formatted_nodes);			temp = (value				&& *value) ? simple_strtoul(value, &value,							    0) : 10;			if (temp <= 0 || temp > 100) {				REISERFS_SB(s)->s_alloc_options.border = 10;			} else {				REISERFS_SB(s)->s_alloc_options.border =				    100 / temp;			}			continue;		}		if (!strcmp(this_char, "displacing_large_files")) {			SET_OPTION(displacing_large_files);			REISERFS_SB(s)->s_alloc_options.large_file_size =			    (value			     && *value) ? simple_strtoul(value, &value, 0) : 16;			continue;		}		if (!strcmp(this_char, "displacing_new_packing_localities")) {			SET_OPTION(displacing_new_packing_localities);			continue;		};		if (!strcmp(this_char, "old_hashed_relocation")) {			SET_OPTION(old_hashed_relocation);			continue;		}		if (!strcmp(this_char, "new_hashed_relocation")) {			SET_OPTION(new_hashed_relocation);			continue;		}		if (!strcmp(this_char, "dirid_groups")) {			SET_OPTION(dirid_groups);			continue;		}		if (!strcmp(this_char, "oid_groups")) {			SET_OPTION(oid_groups);			continue;		}		if (!strcmp(this_char, "packing_groups")) {			SET_OPTION(packing_groups);			continue;		}		if (!strcmp(this_char, "hashed_formatted_nodes")) {			SET_OPTION(hashed_formatted_nodes);			continue;		}		if (!strcmp(this_char, "skip_busy")) {			SET_OPTION(skip_busy);			continue;		}		if (!strcmp(this_char, "hundredth_slices")) {			SET_OPTION(hundredth_slices);			continue;		}		if (!strcmp(this_char, "old_way")) {			SET_OPTION(old_way);			continue;		}		if (!strcmp(this_char, "displace_based_on_dirid")) {			SET_OPTION(displace_based_on_dirid);			continue;		}		if (!strcmp(this_char, "preallocmin")) {			REISERFS_SB(s)->s_alloc_options.preallocmin =			    (value			     && *value) ? simple_strtoul(value, &value, 0) : 4;			continue;		}		if (!strcmp(this_char, "preallocsize")) {			REISERFS_SB(s)->s_alloc_options.preallocsize =			    (value			     && *value) ? simple_strtoul(value, &value,							 0) :			    PREALLOCATION_SIZE;			continue;		}		reiserfs_warning(s, "zam-4001: %s : unknown option - %s",				 __FUNCTION__, this_char);		return 1;	}	reiserfs_warning(s, "allocator options = [%08x]\n", SB_ALLOC_OPTS(s));	return 0;}static inline void new_hashed_relocation(reiserfs_blocknr_hint_t * hint){	char *hash_in;	if (hint->formatted_node) {		hash_in = (char *)&hint->key.k_dir_id;	} else {		if (!hint->inode) {			//hint->search_start = hint->beg;			hash_in = (char *)&hint->key.k_dir_id;		} else		    if (TEST_OPTION(displace_based_on_dirid, hint->th->t_super))			hash_in = (char *)(&INODE_PKEY(hint->inode)->k_dir_id);		else			hash_in =			    (char *)(&INODE_PKEY(hint->inode)->k_objectid);	}	hint->search_start =	    hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);}/* * Relocation based on dirid, hashing them into a given bitmap block * files. Formatted nodes are unaffected, a seperate policy covers them */static void dirid_groups(reiserfs_blocknr_hint_t * hint){	unsigned long hash;	__u32 dirid = 0;	int bm = 0;	struct super_block *sb = hint->th->t_super;	if (hint->inode)		dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);	else if (hint->formatted_node)		dirid = hint->key.k_dir_id;	if (dirid) {		bm = bmap_hash_id(sb, dirid);		hash = bm * (sb->s_blocksize << 3);		/* give a portion of the block group to metadata */		if (hint->inode)			hash += sb->s_blocksize / 2;		hint->search_start = hash;	}}/* * Relocation based on oid, hashing them into a given bitmap block * files. Formatted nodes are unaffected, a seperate policy covers them */static void oid_groups(reiserfs_blocknr_hint_t * hint){	if (hint->inode) {		unsigned long hash;		__u32 oid;		__u32 dirid;		int bm;		dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);		/* keep the root dir and it's first set of subdirs close to		 * the start of the disk		 */		if (dirid <= 2)			hash = (hint->inode->i_sb->s_blocksize << 3);		else {			oid = le32_to_cpu(INODE_PKEY(hint->inode)->k_objectid);			bm = bmap_hash_id(hint->inode->i_sb, oid);			hash = bm * (hint->inode->i_sb->s_blocksize << 3);		}		hint->search_start = hash;	}}/* returns 1 if it finds an indirect item and gets valid hint info * from it, otherwise 0 */static int get_left_neighbor(reiserfs_blocknr_hint_t * hint){	struct treepath *path;	struct buffer_head *bh;	struct item_head *ih;	int pos_in_item;	__le32 *item;	int ret = 0;	if (!hint->path)	/* reiserfs code can call this function w/o pointer to path				 * structure supplied; then we rely on supplied search_start */		return 0;	path = hint->path;	bh = get_last_bh(path);	RFALSE(!bh, "green-4002: Illegal path specified to get_left_neighbor");	ih = get_ih(path);	pos_in_item = path->pos_in_item;	item = get_item(path);	hint->search_start = bh->b_blocknr;	if (!hint->formatted_node && is_indirect_le_ih(ih)) {		/* for indirect item: go to left and look for the first non-hole entry		   in the indirect item */		if (pos_in_item == I_UNFM_NUM(ih))			pos_in_item--;//          pos_in_item = I_UNFM_NUM (ih) - 1;		while (pos_in_item >= 0) {			int t = get_block_num(item, pos_in_item);			if (t) {				hint->search_start = t;				ret = 1;				break;			}			pos_in_item--;		}	}	/* does result value fit into specified region? */	return ret;}/* should be, if formatted node, then try to put on first part of the device   specified as number of percent with mount option device, else try to put   on last of device.  This is not to say it is good code to do so,   but the effect should be measured.  */static inline void set_border_in_hint(struct super_block *s,				      reiserfs_blocknr_hint_t * hint){	b_blocknr_t border =	    SB_BLOCK_COUNT(s) / REISERFS_SB(s)->s_alloc_options.border;	if (hint->formatted_node)		hint->end = border - 1;	else		hint->beg = border;}static inline void displace_large_file(reiserfs_blocknr_hint_t * hint){	if (TEST_OPTION(displace_based_on_dirid, hint->th->t_super))		hint->search_start =		    hint->beg +		    keyed_hash((char *)(&INODE_PKEY(hint->inode)->k_dir_id),			       4) % (hint->end - hint->beg);	else		hint->search_start =		    hint->beg +		    keyed_hash((char *)(&INODE_PKEY(hint->inode)->k_objectid),			       4) % (hint->end - hint->beg);}static inline void hash_formatted_node(reiserfs_blocknr_hint_t * hint){	char *hash_in;	if (!hint->inode)		hash_in = (char *)&hint->key.k_dir_id;	else if (TEST_OPTION(displace_based_on_dirid, hint->th->t_super))		hash_in = (char *)(&INODE_PKEY(hint->inode)->k_dir_id);	else		hash_in = (char *)(&INODE_PKEY(hint->inode)->k_objectid);	hint->search_start =	    hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);}static inline intthis_blocknr_allocation_would_make_it_a_large_file(reiserfs_blocknr_hint_t *						   hint){	return hint->block ==	    REISERFS_SB(hint->th->t_super)->s_alloc_options.large_file_size;}#ifdef DISPLACE_NEW_PACKING_LOCALITIESstatic inline void displace_new_packing_locality(reiserfs_blocknr_hint_t * hint){	struct in_core_key *key = &hint->key;	hint->th->displace_new_blocks = 0;	hint->search_start =	    hint->beg + keyed_hash((char *)(&key->k_objectid),				   4) % (hint->end - hint->beg);}#endifstatic inline int old_hashed_relocation(reiserfs_blocknr_hint_t * hint){	b_blocknr_t border;	u32 hash_in;	if (hint->formatted_node || hint->inode == NULL) {		return 0;	}	hash_in = le32_to_cpu((INODE_PKEY(hint->inode))->k_dir_id);	border =	    hint->beg + (u32) keyed_hash(((char *)(&hash_in)),					 4) % (hint->end - hint->beg - 1);	if (border > hint->search_start)		hint->search_start = border;	return 1;}static inline int old_way(reiserfs_blocknr_hint_t * hint){	b_blocknr_t border;	if (hint->formatted_node || hint->inode == NULL) {		return 0;	}	border =	    hint->beg +	    le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id) % (hint->end -							      hint->beg);	if (border > hint->search_start)		hint->search_start = border;	return 1;}

⌨️ 快捷键说明

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