int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS; 
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); 
int reiserfs_get_block (struct inode * inode, sector_t block,			struct buffer_head * bh_result, int create){    int repeat, retval = 0;    b_blocknr_t allocated_block_nr = 0;// b_blocknr_t is (unsigned) 32 bit int    INITIALIZE_PATH(path);    int pos_in_item;    struct cpu_key key;    struct buffer_head * bh, * unbh = NULL;    struct item_head * ih, tmp_ih;    __le32 * item;    int done;    int fs_gen;    struct reiserfs_transaction_handle *th = NULL;    /* space reserved in transaction batch:         . 3 balancings in direct->indirect conversion        . 1 block involved into reiserfs_update_sd()       XXX in practically impossible worst case direct2indirect()       can incur (much) more than 3 balancings.       quota update for user, group */    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS;    int version;    int dangle = 1;    loff_t new_offset = (((loff_t)block) << inode->i_sb->s_blocksize_bits) + 1 ;				/* bad.... */    reiserfs_write_lock(inode->i_sb);    version = get_inode_item_key_version (inode);    if (block < 0) {	reiserfs_write_unlock(inode->i_sb);	return -EIO;    }    if (!file_capable (inode, block)) {	reiserfs_write_unlock(inode->i_sb);	return -EFBIG;    }    /* if !create, we aren't changing the FS, so we don't need to    ** log anything, so we don't need to start a transaction    */    if (!(create & GET_BLOCK_CREATE)) {	int ret ;	/* find number of block-th logical block of the file */	ret = _get_block_create_0 (inode, block, bh_result, 	                           create | GET_BLOCK_READ_DIRECT) ;	reiserfs_write_unlock(inode->i_sb);	return ret;    }    /*     * if we're already in a transaction, make sure to close     * any new transactions we start in this func     */    if ((create & GET_BLOCK_NO_DANGLE) ||        reiserfs_transaction_running(inode->i_sb))        dangle = 0;    /* If file is of such a size, that it might have a tail and tails are enabled    ** we should mark it as possibly needing tail packing on close    */    if ( (have_large_tails (inode->i_sb) && inode->i_size < i_block_size (inode)*4) ||	 (have_small_tails (inode->i_sb) && inode->i_size < i_block_size(inode)) )	REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;    /* set the key of the first byte in the 'block'-th block of file */    make_cpu_key (&key, inode, new_offset,		  TYPE_ANY, 3/*key length*/);    if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) {start_trans:	th = reiserfs_persistent_transaction(inode->i_sb, jbegin_count);	if (!th) {	    retval = -ENOMEM;	    goto failure;	}	reiserfs_update_inode_transaction(inode) ;    } research:    retval = search_for_position_by_key (inode->i_sb, &key, &path);    if (retval == IO_ERROR) {	retval = -EIO;	goto failure;    }	    bh = get_last_bh (&path);    ih = get_ih (&path);    item = get_item (&path);    pos_in_item = path.pos_in_item;    fs_gen = get_generation (inode->i_sb);    copy_item_head (&tmp_ih, ih);    if (allocation_needed (retval, allocated_block_nr, ih, item, pos_in_item)) {	/* we have to allocate block for the unformatted node */	if (!th) {	    pathrelse(&path) ;	    goto start_trans;	}	repeat = _allocate_block(th, block, inode, &allocated_block_nr, &path, create);	if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) {	    /* restart the transaction to give the journal a chance to free	    ** some blocks.  releases the path, so we have to go back to	    ** research if we succeed on the second try	    */	    SB_JOURNAL(inode->i_sb)->j_next_async_flush = 1;	    retval = restart_transaction(th, inode, &path) ;            if (retval)                goto failure;	    repeat = _allocate_block(th, block, inode, &allocated_block_nr, NULL, create);	    if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) {		goto research ;	    }	    if (repeat == QUOTA_EXCEEDED)		retval = -EDQUOT;	    else		retval = -ENOSPC;	    goto failure;	}	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {	    goto research;	}    }    if (indirect_item_found (retval, ih)) {        b_blocknr_t unfm_ptr;	/* 'block'-th block is in the file already (there is	   corresponding cell in some indirect item). But it may be	   zero unformatted node pointer (hole) */        unfm_ptr = get_block_num (item, pos_in_item);	if (unfm_ptr == 0) {	    /* use allocated block to plug the hole */	    reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;	    if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {		reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;		goto research;	    }	    set_buffer_new(bh_result);	    if (buffer_dirty(bh_result) && reiserfs_data_ordered(inode->i_sb))	    	reiserfs_add_ordered_list(inode, bh_result);	    put_block_num(item, pos_in_item, allocated_block_nr) ;            unfm_ptr = allocated_block_nr;	    journal_mark_dirty (th, inode->i_sb, bh);	    reiserfs_update_sd(th, inode) ;	}	set_block_dev_mapped(bh_result, unfm_ptr, inode);	pathrelse (&path);        retval = 0;	if (!dangle && th)	    retval = reiserfs_end_persistent_transaction(th);	reiserfs_write_unlock(inode->i_sb);	 	/* the item was found, so new blocks were not added to the file	** there is no need to make sure the inode is updated with this 	** transaction	*/	return retval;    }    if (!th) {	pathrelse(&path) ;	goto start_trans;    }    /* desired position is not found or is in the direct item. We have       to append file with holes up to 'block'-th block converting       direct items to indirect one if necessary */    done = 0;    do {	if (is_statdata_le_ih (ih)) {	    __le32 unp = 0;	    struct cpu_key tmp_key;	    /* indirect item has to be inserted */	    make_le_item_head (&tmp_ih, &key, version, 1, TYPE_INDIRECT, 			       UNFM_P_SIZE, 0/* free_space */);	    if (cpu_key_k_offset (&key) == 1) {		/* we are going to add 'block'-th block to the file. Use		   allocated block for that */		unp = cpu_to_le32 (allocated_block_nr);		set_block_dev_mapped (bh_result, allocated_block_nr, inode);		set_buffer_new(bh_result);		done = 1;	    }	    tmp_key = key; // ;)	    set_cpu_key_k_offset (&tmp_key, 1);	    PATH_LAST_POSITION(&path) ++;	    retval = reiserfs_insert_item (th, &path, &tmp_key, &tmp_ih, inode, (char *)&unp);	    if (retval) {		reiserfs_free_block (th, inode, allocated_block_nr, 1);		goto failure; // retval == -ENOSPC, -EDQUOT or -EIO or -EEXIST	    }	    //mark_tail_converted (inode);	} else if (is_direct_le_ih (ih)) {	    /* direct item has to be converted */	    loff_t tail_offset;	    tail_offset = ((le_ih_k_offset (ih) - 1) & ~(inode->i_sb->s_blocksize - 1)) + 1;	    if (tail_offset == cpu_key_k_offset (&key)) {		/* direct item we just found fits into block we have                   to map. Convert it into unformatted node: use                   bh_result for the conversion */		set_block_dev_mapped (bh_result, allocated_block_nr, inode);		unbh = bh_result;		done = 1;	    } else {		/* we have to padd file tail stored in direct item(s)		   up to block size and convert it to unformatted		   node. FIXME: this should also get into page cache */		pathrelse(&path) ;		/*		 * ugly, but we can only end the transaction if		 * we aren't nested		 */		BUG_ON (!th->t_refcount);		if (th->t_refcount == 1) {		    retval = reiserfs_end_persistent_transaction(th);		    th = NULL;		    if (retval)			goto failure;		}		retval = convert_tail_for_hole(inode, bh_result, tail_offset) ;		if (retval) {		    if ( retval != -ENOSPC )			reiserfs_warning (inode->i_sb, "clm-6004: convert tail failed inode %lu, error %d", inode->i_ino, retval) ;		    if (allocated_block_nr) {			/* the bitmap, the super, and the stat data == 3 */			if (!th)			    th = reiserfs_persistent_transaction(inode->i_sb,3);			if (th)			    reiserfs_free_block (th,inode,allocated_block_nr,1);		    }		    goto failure ;		}		goto research ;	    }	    retval = direct2indirect (th, inode, &path, unbh, tail_offset);	    if (retval) {		reiserfs_unmap_buffer(unbh);		reiserfs_free_block (th, inode, allocated_block_nr, 1);		goto failure;	    }	    /* it is important the set_buffer_uptodate is done after	    ** the direct2indirect.  The buffer might contain valid	    ** data newer than the data on disk (read by readpage, changed,	    ** and then sent here by writepage).  direct2indirect needs	    ** to know if unbh was already up to date, so it can decide	    ** if the data in unbh needs to be replaced with data from	    ** the disk	    */	    set_buffer_uptodate (unbh);	    /* unbh->b_page == NULL in case of DIRECT_IO request, this means	       buffer will disappear shortly, so it should not be added to	     */	    if ( unbh->b_page ) {		/* we've converted the tail, so we must		** flush unbh before the transaction commits		*/		reiserfs_add_tail_list(inode, unbh) ;		/* mark it dirty now to prevent commit_write from adding		** this buffer to the inode's dirty buffer list		*/		/*		 * AKPM: changed __mark_buffer_dirty to mark_buffer_dirty().		 * It's still atomic, but it sets the page dirty too,		 * which makes it eligible for writeback at any time by the		 * VM (which was also the case with __mark_buffer_dirty())		 */		mark_buffer_dirty(unbh) ;	    }	} else {	    /* append indirect item with holes if needed, when appending	       pointer to 'block'-th block use block, which is already	       allocated */	    struct cpu_key tmp_key;	    unp_t unf_single=0; // We use this in case we need to allocate only				// one block which is a fastpath	    unp_t *un;	    __u64 max_to_insert=MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE;	    __u64 blocks_needed;	    RFALSE( pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,		    "vs-804: invalid position for append");	    /* indirect item has to be appended, set up key of that position */	    make_cpu_key (&tmp_key, inode,			  le_key_k_offset (version, &(ih->ih_key)) + op_bytes_number (ih, inode->i_sb->s_blocksize),			  //pos_in_item * inode->i_sb->s_blocksize,			  TYPE_INDIRECT, 3);// key type is unimportant	    blocks_needed = 1 + ((cpu_key_k_offset (&key) - cpu_key_k_offset (&tmp_key)) >> inode->i_sb->s_blocksize_bits);	    RFALSE( blocks_needed < 0, "green-805: invalid offset");	    if ( blocks_needed == 1 ) {		un = &unf_single;	    } else {		un=kmalloc( min(blocks_needed,max_to_insert)*UNFM_P_SIZE,			    GFP_ATOMIC); // We need to avoid scheduling.		if ( !un) {		    un = &unf_single;		    blocks_needed = 1;		    max_to_insert = 0;		} else		    memset(un, 0, UNFM_P_SIZE * min(blocks_needed,max_to_insert));	    }	    if ( blocks_needed <= max_to_insert) {		/* we are going to add target block to the file. Use allocated		   block for that */		un[blocks_needed-1] = cpu_to_le32 (allocated_block_nr);		set_block_dev_mapped (bh_result, allocated_block_nr, inode);		set_buffer_new(bh_result);		done = 1;	    } else {		/* paste hole to the indirect item */		/* If kmalloc failed, max_to_insert becomes zero and it means we		   only have space for one block */		blocks_needed=max_to_insert?max_to_insert:1;	    }	    retval = reiserfs_paste_into_item (th, &path, &tmp_key, inode, (char *)un, UNFM_P_SIZE * blocks_needed);	    if (blocks_needed != 1)		kfree(un);	    if (retval) {		reiserfs_free_block (th, inode, allocated_block_nr, 1);		goto failure;	    }	    if (!done) {		/* We need to mark new file size in case this function will be		   interrupted/aborted later on. And we may do this only for		   holes. */		inode->i_size += inode->i_sb->s_blocksize * blocks_needed;	    }	}	if (done == 1)	    break;	/* this loop could log more blocks than we had originally asked	** for.  So, we have to allow the transaction to end if it is	** too big or too full.  Update the inode so things are 	** consistent if we crash before the function returns	**	** release the path so that anybody waiting on the path before	** ending their transaction will be able to continue.	*/	if (journal_transaction_should_end(th, th->t_blocks_allocated)) {	  retval = restart_transaction(th, inode, &path) ;	  if (retval)	    goto failure;	}	/* inserting indirect pointers for a hole can take a 	** long time.  reschedule if needed	*/	cond_resched();	retval = search_for_position_by_key (inode->i_sb, &key, &path);	if (retval == IO_ERROR) {	    retval = -EIO;	    goto failure;	}	if (retval == POSITION_FOUND) {	    reiserfs_warning (inode->i_sb, "vs-825: reiserfs_get_block: "			      "%K should not be found", &key);	    retval = -EEXIST;	    if (allocated_block_nr)	        reiserfs_free_block (th, inode, allocated_block_nr, 1);	    pathrelse(&path) ;	    goto failure;	}	bh = get_last_bh (&path);	ih = get_ih (&path);	item = get_item (&path);	pos_in_item = path.pos_in_item;    } while (1);    retval = 0; failure:    if (th && (!dangle || (retval && !th->t_trans_id))) {        int err;        if (th->t_trans_id)            reiserfs_update_sd(th, inode);        err = reiserfs_end_persistent_transaction(th);        if (err)            retval = err;    }    reiserfs_write_unlock(inode->i_sb);    reiserfs_check_path(&path) ;    return retval;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/556a2a45bce1740f035befaa7201e4ad836c7257/inode.c/buggy/fs/reiserfs/inode.c