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

📄 ufile.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright 1996-2004 by Hans Reiser, licensing governed by  * reiserfsprogs/README */#include "fsck.h"static int do_items_have_the_same_type (struct item_head * ih, struct key * key){    return (get_type (&ih->ih_key) == get_type (key)) ? 1 : 0;}static int are_items_in_the_same_node (struct path * path){  return (PATH_LAST_POSITION (path) < B_NR_ITEMS (PATH_PLAST_BUFFER (path)) - 1) ? 1 : 0;}static void cut_last_unfm_pointer (struct path * path, struct item_head * ih){    set_ih_free_space(ih, 0);    if (I_UNFM_NUM (ih) == 1)	reiserfsck_delete_item (path, 0);    else	reiserfsck_cut_from_item (path, -((int)UNFM_P_SIZE));}/*    if this is not a symlink - make it of_this_size;    otherwise find a size and return it in symlink_size;*/static unsigned long indirect_to_direct (struct path * path, __u64 len, int symlink){    struct buffer_head * bh = PATH_PLAST_BUFFER (path);    struct item_head * ih = PATH_PITEM_HEAD (path);    __u32 unfm_ptr;    struct buffer_head * unfm_bh = 0;    struct item_head ins_ih;    char * buf;    char bad_drct[fs->fs_blocksize];    /* direct item to insert */    memset (&ins_ih, 0, sizeof (ins_ih));    if (symlink) {	set_ih_key_format (&ins_ih, KEY_FORMAT_1);    } else {	set_ih_key_format (&ins_ih, get_ih_key_format (ih));    }    set_key_dirid (&ins_ih.ih_key, get_key_dirid (&ih->ih_key));    set_key_objectid (&ins_ih.ih_key, get_key_objectid (&ih->ih_key));    set_type_and_offset (get_ih_key_format (&ins_ih), &ins_ih.ih_key,			 get_offset (&ih->ih_key) + (I_UNFM_NUM (ih) - 1) * bh->b_size, 			 TYPE_DIRECT);    // we do not know what length this item should be    unfm_ptr = d32_get ((__u32 *)get_item (path), I_UNFM_NUM (ih) - 1);    if (unfm_ptr && (unfm_bh = bread (bh->b_dev, unfm_ptr, bh->b_size))) {        /* we can read the block */	buf = unfm_bh->b_data;	    } else {        /* we cannot read the block */ 	if (unfm_ptr)	    fsck_log ("indirect_to_direct: Reading of the block (%lu), pointed to by the file %K, failed\n", 		unfm_ptr, &ih->ih_key);	memset (bad_drct, 0, fs->fs_blocksize);	buf = bad_drct;    }/*    if (len > MAX_DIRECT_ITEM_LEN (fs->fs_blocksize)) {	fsck_log ("indirect_to_direct: canot create such a long item %d (%K), "	    "Cutting it down to %d byte\n", len,  &ih->ih_key, MAX_DIRECT_ITEM_LEN (fs->fs_blocksize) - 8);	len = MAX_DIRECT_ITEM_LEN (fs->fs_blocksize) - 8;    }        if (!len) {	buf = bad_link;	len = strlen (bad_link);    }*/    set_ih_item_len (&ins_ih, (get_ih_key_format (ih) == KEY_FORMAT_2) ? ROUND_UP(len) : len);    set_ih_free_space (&ins_ih, MAX_US_INT);    mark_ih_become_tail(ih);    mark_buffer_dirty(bh);    // last last unformatted node pointer    path->pos_in_item = I_UNFM_NUM (ih) - 1;    cut_last_unfm_pointer (path, ih);    /* insert direct item */    if (reiserfs_search_by_key_4 (fs, &(ins_ih.ih_key), path) == ITEM_FOUND)	reiserfs_panic ("indirect_to_direct: The direct item %k should not exist yet.", &(ins_ih.ih_key));    reiserfsck_insert_item (path, &ins_ih, (const char *)(buf));    brelse (unfm_bh);    /* put to stat data offset of first byte in direct item */    return get_offset (&ins_ih.ih_key); //offset;}/*  start_key is the key after which N items need to be deleted    save_here is a pointer where deleted items need to be saved if save is set.    start_key is the first undeleted item.    return whether we are sure there is nothing else of this file */int delete_N_items_after_key(struct key * start_key, struct si ** save_here, int skip_dir_items, int n_to_delete) {    struct path path;//    struct key key = *start_key;    struct key * rkey;    int count = 0;    while (1) {	reiserfs_search_by_key_4 (fs, start_key, &path);		if (get_item_pos (&path) == B_NR_ITEMS (get_bh (&path))) {	    rkey = uget_rkey (&path);	    if (rkey && !not_of_one_file (start_key, rkey)) {		/* file continues in the right neighbor */		copy_key (start_key, rkey);		pathrelse (&path);		continue;	    }	    /* there is no more items with this key */	    pathrelse (&path);	    return 1;	}	if (is_stat_data_ih (get_ih(&path)))	    fix_obviously_wrong_sd_mode (&path);	    		rkey = &(get_ih (&path))->ih_key;	if (not_of_one_file (start_key, rkey)) {	    /* there are no more item with this key */	    pathrelse (&path);	    return 1;	}	copy_key (start_key, rkey);	/* ok, item found, but make sure that it is not a directory one */	if ((is_stat_data_key (rkey) && !not_a_directory (get_item (&path))) ||	    (is_direntry_key (rkey)))	{	    if (skip_dir_items) {	    	/* item of directory found. Leave it in the tree */	    	set_offset (KEY_FORMAT_1, start_key, get_offset (start_key) + 1);	    	pathrelse (&path);	    	continue;	    } else {	    	reiserfs_panic ("delete_N_items_after_key: No directory item of %K are "		    "expected", start_key);	    }	}	if (save_here != NULL)	    *save_here = save_and_delete_file_item (*save_here, &path);	else	    reiserfsck_delete_item (&path, 0);     	count++;    	if (count == n_to_delete)	    break;	pathrelse (&path);    }    return 0;}/* returns 1 when file looks correct, -1 if directory items appeared   there, 0 - only holes in the file found *//* when it returns, key->k_offset is offset of the last item of file *//* sd_size is zero if we do not need to convert any indirect to direct */int are_file_items_correct (struct item_head * sd_ih, void * sd, __u64 * size, __u32 * blocks,				int mark_passed_items, int * symlink){    struct path path;    struct item_head * ih;    struct key * next_key, * key;    __u32 sd_first_direct_byte = 0;    __u64 sd_size;    unsigned int i;    int retval, was_tail = 0;    int had_direct = 0;    int key_version = get_ih_key_format (sd_ih);    int next_is_another_object = 0;    __u64 last_unfm_offset = 0;    int will_convert = 0;    int should_convert;    should_convert = (fsck_mode (fs) != FSCK_REBUILD) || mark_passed_items;    key = &sd_ih->ih_key;    get_sd_size (sd_ih, sd, &sd_size);    if (key_version == KEY_FORMAT_1)    	get_sd_first_direct_byte (sd_ih, sd, &sd_first_direct_byte);    set_offset (key_version, key, 1);    set_type (key_version, key, TYPE_DIRECT);    /* correct size and st_blocks */    *size = 0;    *blocks = 0;    path.path_length = ILLEGAL_PATH_ELEMENT_OFFSET;    do {	retval = usearch_by_position (fs, key, key_version, &path);	if (retval == POSITION_FOUND && path.pos_in_item != 0)	    die ("are_file_items_correct: All bytes we look for must be first items byte (position 0).");	switch (retval) {	case POSITION_FOUND:/**/	    ih = PATH_PITEM_HEAD (&path);	    if (ih_was_tail (ih)) {	    	was_tail = 1;	    }		    set_type (key_version, key, get_type (&ih->ih_key));		    if (mark_passed_items == 1) {		mark_item_reachable (ih, PATH_PLAST_BUFFER (&path));	    }		    // does not change path	    next_key = reiserfs_next_key(&path);	    if (next_key == 0 || not_of_one_file (key, next_key) || 		(!is_indirect_key (next_key) && !is_direct_key(next_key))) 	    {		next_is_another_object = 1;		will_convert = (is_indirect_ih (ih) && sd_size && (I_UNFM_NUM (ih) > 0));		if (will_convert) {		    last_unfm_offset = get_offset (key) + fs->fs_blocksize * (I_UNFM_NUM (ih) - 1);		    /* if symlink or		       [ 1. sd_size points somewhere into last unfm block		         2. one item of the file was direct before for 3_6 || FDB points to the tail correctly for 3_5		         3. we can have a tail in the file of a such size ] */		    will_convert = will_convert && (sd_size >= last_unfm_offset) && 			(sd_size < last_unfm_offset + fs->fs_blocksize) && 			!STORE_TAIL_IN_UNFM (sd_size, sd_size - last_unfm_offset + 1, fs->fs_blocksize);		    		    will_convert = will_convert && (*symlink || ((key_version == KEY_FORMAT_1) && 			(sd_first_direct_byte == last_unfm_offset)) || ((key_version == KEY_FORMAT_2) && was_tail));		}	    }	    if (should_convert) {		*symlink = *symlink && (will_convert || is_direct_key(&ih->ih_key));	    		if (!(*symlink) && key_version != get_ih_key_format (ih)) {		    if (fsck_mode(fs) == FSCK_CHECK) {			fsck_log("are_file_items_correct: vpf-10250: block %lu, item (%d): The item format (%H)"\			    " is not equal to SD format (%d)\n",			    get_bh(&path)->b_blocknr, PATH_LAST_POSITION(&path), ih, key_version);			one_more_corruption (fs, FIXABLE);		    } else {			fsck_log("are_file_items_correct: vpf-10280: block %lu, item (%d): The item format (%H)"\			    " is not equal to SD format (%d) - fixed.\n",			    get_bh(&path)->b_blocknr, PATH_LAST_POSITION(&path), ih, key_version);					set_type_and_offset (key_version, &ih->ih_key, get_offset (&ih->ih_key), get_type (&ih->ih_key));			set_ih_key_format(ih, key_version);			mark_buffer_dirty(get_bh(&path));		    }		}		if (*symlink && is_direct_key(&ih->ih_key)) {		    /* symlink. Check that it is of KEY_FORMAT_1 */		    if (fsck_mode(fs) == FSCK_CHECK) {			if ((get_ih_key_format(ih) != KEY_FORMAT_1) || (key_format(&ih->ih_key) != KEY_FORMAT_1)) {			    fsck_log("are_file_items_correct: vpf-10732: block %lu, item (%d): The symlink format (%H)"\				" is not equal to 3.5 format (%d)\n", get_bh(&path)->b_blocknr, PATH_LAST_POSITION(&path), 				ih, KEY_FORMAT_1);			    one_more_corruption (fs, FIXABLE);			}		    } else {			if ((get_ih_key_format(ih) != KEY_FORMAT_1) || (key_format(&ih->ih_key) != KEY_FORMAT_1)) {			    fsck_log("are_file_items_correct: vpf-10732: block %lu, item (%d): The symlink format (%H)"\				" is not equal to 3.5 format (%d)\n", get_bh(&path)->b_blocknr, PATH_LAST_POSITION(&path), 				ih, KEY_FORMAT_1);			    set_type_and_offset(KEY_FORMAT_1, &ih->ih_key, get_offset(&ih->ih_key), get_type(&ih->ih_key));			    set_ih_key_format(ih, KEY_FORMAT_1);			    mark_buffer_dirty(get_bh(&path));			}					    }		}				if (will_convert)		    *size = sd_size;		else		    *size = get_offset (&ih->ih_key) + get_bytes_number (ih, fs->fs_blocksize) - 1;	    		if (get_type (&ih->ih_key) == TYPE_INDIRECT) {		    if (*symlink) /* symlinks must be calculated as dirs */			*blocks = dir_size2st_blocks (*size);		    else			for (i = 0; i < I_UNFM_NUM (ih); i ++) {			    __u32 * ind = (__u32 *)get_item(&path);			    if (d32_get(ind, i) != 0)				*blocks += (fs->fs_blocksize >> 9);			}		} else if (get_type (&ih->ih_key) == TYPE_DIRECT) {		    if (*symlink) /* symlinks must be calculated as dirs */			*blocks = dir_size2st_blocks (*size);		    else if (!had_direct)			*blocks += (fs->fs_blocksize >> 9);		    /* calculate only the first direct byte */		    had_direct++;		}	    }	    if (next_is_another_object)             {		/* next item does not exists or is of another object,                   therefore all items of file are correct */		if (will_convert) {		    if (fsck_mode (fs) == FSCK_CHECK) {			/* here it can be symlink only */			fsck_log ("are_file_items_correct: The indirect item should be converted back"			    " to direct %K\n", &ih->ih_key);			one_more_corruption (fs, FIXABLE);			pathrelse (&path);		    } else {			__u32 * ind = (__u32 *)get_item(&path);			/*   DEBUG message.			fsck_log ("are_file_items_correct: The indirect item is converted back to direct %K\n", &ih->ih_key);			*/			if (d32_get(ind, I_UNFM_NUM (ih) - 1) == 0)			    *blocks += (fs->fs_blocksize >> 9);			/* path is released here. */			sd_first_direct_byte = indirect_to_direct (&path, sd_size - last_unfm_offset + 1, *symlink);			/* last item of the file is direct item */			set_offset (key_version, key, sd_first_direct_byte);			set_type (key_version, key, TYPE_DIRECT);		    }		} else 		    pathrelse (&path);				return 1;	    }	    /* next item is item of this file */	    if (get_offset (&ih->ih_key) + get_bytes_number(ih, fs->fs_blocksize) != get_offset (next_key))	    {				/* next item has incorrect offset (hole or overlapping) */		pathrelse (&path);		return 0;	    }	    if (do_items_have_the_same_type (ih, next_key) == 1 && are_items_in_the_same_node (&path) == 1) 	    {		/* two indirect items or two direct items in the same leaf. FIXME: Second will be deleted */		pathrelse (&path);		return 0;	    }	    /* items are of different types or are in different nodes *//*	    if (get_offset (&ih->ih_key) + get_bytes_number (ih, fs->fs_blocksize) != get_offset (next_key))            {		// indirect item free space is not set properly 		if (!is_indirect_ih (ih) ) //|| get_ih_free_space(ih) == 0)		    fsck_log ("are_file_items_correct: "			      "item must be indirect and must have invalid free space (%H)", ih);	                if (fsck_mode (fs) == FSCK_REBUILD)                {		                    set_ih_free_space(ih, 0);                    mark_buffer_dirty (PATH_PLAST_BUFFER (&path));        	}	    }*/	    /* next item exists */	    set_type_and_offset(key_version, key, get_offset (next_key), get_type(next_key));		    if (comp_keys (key, next_key))		reiserfs_panic ("are_file_items_correct: Internal tree is in inconsistent state, "		    "the current item key %K and the next key %K must match", key, next_key);	    pathrelse (&path);	    break;	case POSITION_NOT_FOUND:	    /* We always must have next key found. Exception is first byte. It does not have to exist */	    if (get_offset (key) != 1)		reiserfs_panic ("are_file_items_correct: Position (offset == %llu) in the middle of"		    "the file %K was not found.", get_offset(key), key);	    pathrelse (&path);	    return 0;      	case FILE_NOT_FOUND:	    if (get_offset (key) != 1)		reiserfs_panic ("are_file_items_correct: File %K must be found as we found its StatData.", key);	    pathrelse (&path);	    return 1;	case DIRECTORY_FOUND:	    pathrelse (&path);	    return -1;	}    } while (1);    die ("are_file_items_correct: Cannot reach here");    return 0;

⌨️ 快捷键说明

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