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

📄 stree.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		(*p_n_removed)++;		tmp = get_block_num(p_n_unfm_pointer,0);		put_block_num(p_n_unfm_pointer, 0, 0);		journal_mark_dirty (th, p_s_sb, p_s_bh);		inode->i_blocks -= p_s_sb->s_blocksize / 512;		reiserfs_free_block(th, tmp);		if ( item_moved (&s_ih, p_s_path) )  {			need_research = 1;			break ;		}	    }	    /* a trick.  If the buffer has been logged, this	    ** will do nothing.  If we've broken the loop without	    ** logging it, it will restore the buffer	    **	    */	    reiserfs_restore_prepared_buffer(p_s_sb, p_s_bh);	    /* This loop can be optimized. */	} while ( (*p_n_removed < n_unfm_number || need_research) &&		  search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND );	RFALSE( *p_n_removed < n_unfm_number, 		"PAP-5310: indirect item is not found");	RFALSE( item_moved (&s_ih, p_s_path), 		"after while, comp failed, retry") ;	if (c_mode == M_CUT)	    pos_in_item (p_s_path) *= UNFM_P_SIZE;	return c_mode;    }}/* Calculate bytes number which will be deleted or cutted in the balance. */int calc_deleted_bytes_number(    struct  tree_balance  * p_s_tb,    char                    c_mode    ) {    int                     n_del_size;    struct  item_head     * p_le_ih = PATH_PITEM_HEAD(p_s_tb->tb_path);    if ( is_statdata_le_ih (p_le_ih) )	return 0;    if ( is_direntry_le_ih (p_le_ih) ) {	// return EMPTY_DIR_SIZE; /* We delete emty directoris only. */	// we can't use EMPTY_DIR_SIZE, as old format dirs have a different	// empty size.  ick. FIXME, is this right?	//	return ih_item_len(p_le_ih);    }    n_del_size = ( c_mode == M_DELETE ) ? ih_item_len(p_le_ih) : -p_s_tb->insert_size[0];    if ( is_indirect_le_ih (p_le_ih) )	n_del_size = (n_del_size/UNFM_P_SIZE)*	  (PATH_PLAST_BUFFER(p_s_tb->tb_path)->b_size);// - get_ih_free_space (p_le_ih);    return n_del_size;}static void init_tb_struct(    struct reiserfs_transaction_handle *th,    struct tree_balance * p_s_tb,    struct super_block  * p_s_sb,    struct path         * p_s_path,    int                   n_size    ) {    memset (p_s_tb,'\0',sizeof(struct tree_balance));    p_s_tb->transaction_handle = th ;    p_s_tb->tb_sb = p_s_sb;    p_s_tb->tb_path = p_s_path;    PATH_OFFSET_PBUFFER(p_s_path, ILLEGAL_PATH_ELEMENT_OFFSET) = NULL;    PATH_OFFSET_POSITION(p_s_path, ILLEGAL_PATH_ELEMENT_OFFSET) = 0;    p_s_tb->insert_size[0] = n_size;}void padd_item (char * item, int total_length, int length){    int i;    for (i = total_length; i > length; )	item [--i] = 0;}/* Delete object item. */int reiserfs_delete_item (struct reiserfs_transaction_handle *th, 			  struct path * p_s_path, /* Path to the deleted item. */			  const struct cpu_key * p_s_item_key, /* Key to search for the deleted item.  */			  struct inode * p_s_inode,/* inode is here just to update i_blocks */			  struct buffer_head  * p_s_un_bh)    /* NULL or unformatted node pointer.    */{    struct super_block * p_s_sb = p_s_inode->i_sb;    struct tree_balance   s_del_balance;    struct item_head      s_ih;    int                   n_ret_value,	n_del_size,	n_removed;#ifdef CONFIG_REISERFS_CHECK    char                  c_mode;    int			n_iter = 0;#endif    init_tb_struct(th, &s_del_balance, p_s_sb, p_s_path, 0/*size is unknown*/);    while ( 1 ) {	n_removed = 0;#ifdef CONFIG_REISERFS_CHECK	n_iter++;	c_mode =#endif	    prepare_for_delete_or_cut(th, p_s_inode, p_s_path, p_s_item_key, &n_removed, &n_del_size, max_reiserfs_offset (p_s_inode));	RFALSE( c_mode != M_DELETE, "PAP-5320: mode must be M_DELETE");	copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));	s_del_balance.insert_size[0] = n_del_size;	n_ret_value = fix_nodes(M_DELETE, &s_del_balance, NULL, 0);	if ( n_ret_value != REPEAT_SEARCH )	    break;	// file system changed, repeat search	n_ret_value = search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);	if (n_ret_value == IO_ERROR)	    break;	if (n_ret_value == FILE_NOT_FOUND) {	    reiserfs_warning ("vs-5340: reiserfs_delete_item: "			      "no items of the file %K found\n", p_s_item_key);	    break;	}    } /* while (1) */    if ( n_ret_value != CARRY_ON ) {	unfix_nodes(&s_del_balance);	return 0;    }    // reiserfs_delete_item returns item length when success    n_ret_value = calc_deleted_bytes_number(&s_del_balance, M_DELETE);    if ( p_s_un_bh )  {	int off;        char *data ;	/* We are in direct2indirect conversion, so move tail contents           to the unformatted node */	/* note, we do the copy before preparing the buffer because we	** don't care about the contents of the unformatted node yet.	** the only thing we really care about is the direct item's data	** is in the unformatted node.	**	** Otherwise, we would have to call reiserfs_prepare_for_journal on	** the unformatted node, which might schedule, meaning we'd have to	** loop all the way back up to the start of the while loop.	**	** The unformatted node must be dirtied later on.  We can't be	** sure here if the entire tail has been deleted yet.        **        ** p_s_un_bh is from the page cache (all unformatted nodes are        ** from the page cache) and might be a highmem page.  So, we        ** can't use p_s_un_bh->b_data.  But, the page has already been        ** kmapped, so we can use page_address()	** -clm	*/        data = page_address(p_s_un_bh->b_page) ;	off = ((le_ih_k_offset (&s_ih) - 1) & (PAGE_CACHE_SIZE - 1));	memcpy(data + off,	       B_I_PITEM(PATH_PLAST_BUFFER(p_s_path), &s_ih), n_ret_value);    }    /* Perform balancing after all resources have been collected at once. */     do_balance(&s_del_balance, NULL, NULL, M_DELETE);    /* Return deleted body length */    return n_ret_value;}/* Summary Of Mechanisms For Handling Collisions Between Processes: deletion of the body of the object is performed by iput(), with the result that if multiple processes are operating on a file, the deletion of the body of the file is deferred until the last process that has an open inode performs its iput(). writes and truncates are protected from collisions by use of semaphores. creates, linking, and mknod are protected from collisions with other processes by making the reiserfs_add_entry() the last step in the creation, and then rolling back all changes if there was a collision. - Hans*//* this deletes item which never gets split */void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,				 struct key * key){    struct tree_balance tb;    INITIALIZE_PATH (path);    int item_len;    int tb_init = 0 ;    struct cpu_key cpu_key;    int retval;        le_key2cpu_key (&cpu_key, key);        while (1) {	retval = search_item (th->t_super, &cpu_key, &path);	if (retval == IO_ERROR) {	    reiserfs_warning ("vs-5350: reiserfs_delete_solid_item: "			      "i/o failure occurred trying to delete %K\n", &cpu_key);	    break;	}	if (retval != ITEM_FOUND) {	    pathrelse (&path);	    reiserfs_warning ("vs-5355: reiserfs_delete_solid_item: %k not found",			      key);	    break;	}	if (!tb_init) {	    tb_init = 1 ;	    item_len = ih_item_len( PATH_PITEM_HEAD(&path) );	    init_tb_struct (th, &tb, th->t_super, &path, - (IH_SIZE + item_len));	}	retval = fix_nodes (M_DELETE, &tb, NULL, 0);	if (retval == REPEAT_SEARCH)	    continue;	if (retval == CARRY_ON) {	    do_balance (&tb, 0, 0, M_DELETE);	    break;	}	// IO_ERROR, NO_DISK_SPACE, etc	reiserfs_warning ("vs-5360: reiserfs_delete_solid_item: "			  "could not delete %K due to fix_nodes failure\n", &cpu_key);	unfix_nodes (&tb);	break;    }    reiserfs_check_path(&path) ;}void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * inode){    inode->i_size = 0;    /* for directory this deletes item containing "." and ".." */    reiserfs_do_truncate (th, inode, NULL, 0/*no timestamp updates*/);    #if defined( USE_INODE_GENERATION_COUNTER )    if( !old_format_only ( th -> t_super ) )      {       __u32 *inode_generation;              inode_generation =          &th -> t_super -> u.reiserfs_sb.s_rs -> s_inode_generation;       *inode_generation = cpu_to_le32( le32_to_cpu( *inode_generation ) + 1 );      }/* USE_INODE_GENERATION_COUNTER */#endif    reiserfs_delete_solid_item (th, INODE_PKEY (inode));}static int maybe_indirect_to_direct (struct reiserfs_transaction_handle *th, 			      struct inode * p_s_inode,			      struct page *page, 			      struct path         * p_s_path,			      const struct cpu_key      * p_s_item_key,			      loff_t         n_new_file_size,			      char                * p_c_mode			      ) {    struct super_block * p_s_sb = p_s_inode->i_sb;    int n_block_size = p_s_sb->s_blocksize;    int cut_bytes;    if (n_new_file_size != p_s_inode->i_size)	BUG ();    /* the page being sent in could be NULL if there was an i/o error    ** reading in the last block.  The user will hit problems trying to    ** read the file, but for now we just skip the indirect2direct    */    if (atomic_read(&p_s_inode->i_count) > 1 ||         !tail_has_to_be_packed (p_s_inode) ||         !page || (p_s_inode->u.reiserfs_i.i_flags & i_nopack_mask)) {	// leave tail in an unformatted node		*p_c_mode = M_SKIP_BALANCING;	cut_bytes = n_block_size - (n_new_file_size & (n_block_size - 1));	pathrelse(p_s_path);	return cut_bytes;    }    /* Permorm the conversion to a direct_item. */    /*return indirect_to_direct (p_s_inode, p_s_path, p_s_item_key, n_new_file_size, p_c_mode);*/    return indirect2direct (th, p_s_inode, page, p_s_path, p_s_item_key, n_new_file_size, p_c_mode);}/* we did indirect_to_direct conversion. And we have inserted direct   item successesfully, but there were no disk space to cut unfm   pointer being converted. Therefore we have to delete inserted   direct item(s) */static void indirect_to_direct_roll_back (struct reiserfs_transaction_handle *th, struct inode * inode, struct path * path){    struct cpu_key tail_key;    int tail_len;    int removed;    make_cpu_key (&tail_key, inode, inode->i_size + 1, TYPE_DIRECT, 4);// !!!!    tail_key.key_length = 4;    tail_len = (cpu_key_k_offset (&tail_key) & (inode->i_sb->s_blocksize - 1)) - 1;    while (tail_len) {	/* look for the last byte of the tail */	if (search_for_position_by_key (inode->i_sb, &tail_key, path) == POSITION_NOT_FOUND)	    reiserfs_panic (inode->i_sb, "vs-5615: indirect_to_direct_roll_back: found invalid item");	RFALSE( path->pos_in_item != ih_item_len(PATH_PITEM_HEAD (path)) - 1,	        "vs-5616: appended bytes found");	PATH_LAST_POSITION (path) --;		removed = reiserfs_delete_item (th, path, &tail_key, inode, 0/*unbh not needed*/);	RFALSE( removed <= 0 || removed > tail_len,	        "vs-5617: there was tail %d bytes, removed item length %d bytes",                tail_len, removed);	tail_len -= removed;	set_cpu_key_k_offset (&tail_key, cpu_key_k_offset (&tail_key) - removed);    }    printk ("indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space\n");    //mark_file_without_tail (inode);    mark_inode_dirty (inode);}/* (Truncate or cut entry) or delete object item. Returns < 0 on failure */int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th, 			    struct path * p_s_path,			    struct cpu_key * p_s_item_key,			    struct inode * p_s_inode,			    struct page *page, 			    loff_t n_new_file_size){    struct super_block * p_s_sb = p_s_inode->i_sb;    /* Every function which is going to call do_balance must first       create a tree_balance structure.  Then it must fill up this       structure by using the init_tb_struct and fix_nodes functions.       After that we can make tree balancing. */    struct tree_balance s_cut_balance;    int n_cut_size = 0,        /* Amount to be cut. */	n_ret_value = CARRY_ON,	n_removed = 0,     /* Number of the removed unformatted nodes. */	n_is_inode_locked = 0;    char                c_mode;            /* Mode of the balance. */    int retval2 = -1;            init_tb_struct(th, &s_cut_balance, p_s_inode->i_sb, p_s_path, n_cut_size);    /* Repeat this loop until we either cut the item without needing

⌨️ 快捷键说明

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