bitmap.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,146 行 · 第 1/3 页

C
1,146
字号
    RFALSE(!s, "vs-4061: trying to free block on nonexistent device");    RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block");    /* 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 */void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, 			  struct inode *inode, b_blocknr_t block) {    RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device");    RFALSE(is_reusable (th->t_super, block, 1) == 0, "vs-4070: can not free such block");    _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;#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);    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;    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 voiddirid_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 voidoid_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 path * path;    struct buffer_head * bh;    struct item_head * ih;    int pos_in_item;    __u32 * 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 int this_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 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;}static inline void hundredth_slices (reiserfs_blocknr_hint_t * hint){    struct key * key = &hint->key;    b_blocknr_t slice_start;    slice_start = (keyed_hash((char*)(&key->k_dir_id),4) % 100) * (hint->end / 100);    if ( slice_start > hint->search_start || slice_start + (hint->end / 100) <= hint->search_start) {	hint->search_start = slice_start;

⌨️ 快捷键说明

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