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

📄 semantic_rebuild.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright 1996-2004 by Hans Reiser, licensing governed by  * reiserfsprogs/README */#include "fsck.h"int screen_width;int screen_curr_pos;char *screen_savebuffer;int screen_savebuffer_len;#define MIN(a, b) (((a)>(b))?(b):(a))/* semantic pass progress */void print_name (char * name, int len){    int i;    if (fsck_quiet (fs))	return;    if ( len + screen_curr_pos + 1 > screen_savebuffer_len) {	char *t;		t = expandmem(screen_savebuffer, screen_savebuffer_len + 1, 	    len + screen_curr_pos - screen_savebuffer_len + 1);	if (!t) {	    fsck_progress("\nOut of memory\n");	    return; // ????	}	screen_savebuffer = t;	screen_savebuffer_len = len + screen_curr_pos + 1;    }    strcat(screen_savebuffer,"/");    strncat(screen_savebuffer,name,len);    i = screen_curr_pos;    screen_curr_pos += len+1;    for ( ; i<screen_curr_pos; i++)	if ( screen_savebuffer[i] < 32 )	    screen_savebuffer[i] = '?';    screen_savebuffer[screen_curr_pos]=0;    if ( screen_width < screen_curr_pos ) {	printf("\r... %.*s",screen_width - 4, 	    screen_savebuffer + ( screen_curr_pos - (screen_width - 4)));    } else	printf("/%.*s", len, screen_savebuffer + screen_curr_pos - len);    fflush (stdout);}void erase_name (int len){    int i;    if (fsck_quiet (fs))	return;    if ( screen_curr_pos < screen_width ) {	screen_curr_pos-=len+1;	screen_savebuffer[screen_curr_pos]=0;	for (i = 0; i<=len; i++)	    printf("\b");	for (i = 0; i<=len+1; i++)	    printf(" ");	for (i = 0; i<=len+1; i++)	    printf("\b");    } else {	screen_curr_pos-=len+1;	if (screen_curr_pos < 0 )	    die("%s: Get out of buffer's data!\n", __FUNCTION__);	screen_savebuffer[screen_curr_pos]=0;	printf("\r");	if (screen_curr_pos >= screen_width ) {	    int t_preface=MIN(screen_curr_pos-screen_width,4);	    printf("%.*s%.*s", t_preface, "... ", screen_width-t_preface - 1, 		screen_savebuffer + ( screen_curr_pos - (screen_width - t_preface)) + 1);	} else {	    int space_used=printf("%s", screen_savebuffer);	    for ( i=space_used; i < screen_width; i++)		printf(" ");	    for ( i=space_used; i < screen_width; i++)		printf("\b");	}    }	        fflush (stdout);}/* *size is "real" file size, sd_size - size from stat data */int wrong_st_size (struct key * key, unsigned long long max_file_size,     int blocksize, __u64 * size, __u64 sd_size, int type){    if (sd_size <= max_file_size) {	if (sd_size == *size)	    return 0;	if (type == TYPE_DIRENTRY) {	    /* directory size must match to the sum of length of its entries */	    fsck_log ("vpf-10650: The directory %K has the wrong size in the StatData "		"(%Lu)%s(%Lu)\n", key, sd_size, fsck_mode(fs) == FSCK_CHECK ? 		", should be " : " - corrected to ", *size);	    return 1;	}		if (sd_size > *size) {	    /* size in stat data can be bigger than size calculated by items */	    if (fsck_adjust_file_size (fs) || type == TYPE_SYMLINK) {		/* but it -o is given - fix that */		fsck_log ("vpf-10660: The file %K has too big size in the StatData "		    "(%Lu)%s(%Lu)\n", key, sd_size, fsck_mode(fs) == FSCK_CHECK ? 		    ", should be " : " - corrected to ", *size);		sem_pass_stat (fs)->fixed_sizes ++;		return 1;	    }	    *size = sd_size;	    return 0;	}		if (!(*size % blocksize)) {	    /* last item is indirect */	    if (((sd_size & ~(blocksize - 1)) == (*size - blocksize)) && 		sd_size % blocksize) 	    {		/* size in stat data is correct */		*size = sd_size;		return 0;	    }	} else {	    /* last item is a direct one */	    if (!(*size % 8)) {		if (((sd_size & ~7) == (*size - 8)) && sd_size % 8) {		    /* size in stat data is correct */		    *size = sd_size;		    return 0;		}	    }	}    }    fsck_log ("vpf-10670: The file %K has the wrong size in the StatData (%Lu)%s(%Lu)\n", key, 	sd_size, fsck_mode(fs) == FSCK_CHECK ? ", should be " : " - corrected to ", 	*size);    sem_pass_stat (fs)->fixed_sizes ++;    return 1;}/* sd_blocks is 32 bit only *//* old stat data shares sd_block and sd_dev - do not wipe sd_rdev out *//* we should fix it as following:|------------------------------------------------------------------||                    |        3.6                   |       3.5    ||---------------------------------------------------|              ||                    |  blocks |  r_dev|generation  | blocks/r_dev ||------------------------------------------------------------------||   fifo, sockets    |    0    |    generation      |      0       ||   chr/blk_dev      |    0    |     maj:min        |   maj:min    ||   file, dir, link  |  blocks |    generation      |   blocks     ||------------------------------------------------------------------|*/int wrong_st_blocks (struct key * key, __u32 * blocks, __u32 sd_blocks, __u16 mode,     int new_format){    int ret = 0;    if (S_ISREG (mode) || S_ISLNK (mode) || S_ISDIR (mode)) {	if ((!S_ISLNK(mode) && *blocks != sd_blocks) ||	    (S_ISLNK(mode) && *blocks != sd_blocks && (ROUND_UP(*blocks) != sd_blocks))) {	    fsck_log ("vpf-10680: The %s %K has the wrong block count in the StatData "		"(%u)%s(%u)\n", S_ISDIR (mode) ? "directory" : S_ISREG (mode) ? "file" : "link",  key, sd_blocks, 		fsck_mode(fs) == FSCK_CHECK ? ", should be " : " - corrected to ", *blocks);	    ret = 1;	}    } else if (new_format || (S_ISFIFO (mode) || S_ISSOCK (mode))) {	if (sd_blocks != 0) {	    fsck_log ("vpf-10690: The object %K has the wrong block count in the StatData "		"(%u)%s(%u)\n",	key, sd_blocks, fsck_mode(fs) == FSCK_CHECK ? 		", should be " : " - corrected to ", 0);	    *blocks = 0;		    ret = 1;	}    }    return ret;}/*int wrong_st_rdev (struct key * key, __u32 * sd_rdev, __u16 mode, int new_format){    int ret = 0;    if (!new_format)	return 0;    if (!S_ISCHR (mode) && !S_ISBLK (mode)) {	if (*sd_rdev != 0) {	    fsck_log ("%s %K has wrong sd_rdev %u, has to be 0\n",		S_ISDIR (mode) ? "dir" : "file", key, *sd_rdev);	    *sd_rdev = 0;	    ret = 1;	}    }    return ret;}*//* only regular files and symlinks may have items but stat   data. Symlink should have body */int wrong_mode (struct key * key, __u16 * mode, __u64 real_size, int symlink){    int retval = 0;    if (S_ISLNK (*mode) && !symlink) {	fsck_log ("The file %K (%M) is too big to be the symlink%s regfile\n", 	    key, *mode, fsck_mode(fs) == FSCK_CHECK ? ", should be the" : " - corrected "	    "to the");	*mode &= ~S_IFMT;	*mode |= S_IFREG;	retval = 1;    }    if (ftypelet (*mode) != '?') {	/* mode looks reasonable */	if (S_ISREG (*mode) || S_ISLNK (*mode))	    return retval;		/* device, pipe, socket have no items */	if (!real_size)	    return retval;    }    /* there are items, so change file mode to regular file. Otherwise       - file bodies do not get deleted */    if (fsck_mode(fs) == FSCK_CHECK) {	fsck_log ("The object %K has wrong mode (%M)\n", key, *mode);    } else {	fsck_log("The object %K has wrong mode (%M) - corrected to %M\n", 	    key, *mode, (S_IFREG | 0600));    }    *mode = (S_IFREG | 0600);    return 1;}/* key is a key of last file item */int wrong_first_direct_byte (struct key * key, int blocksize, 			     __u32 * first_direct_byte,			     __u32 sd_first_direct_byte, __u32 size){    if (!size || is_indirect_key (key)) {	/* there is no direct item */	*first_direct_byte = NO_BYTES_IN_DIRECT_ITEM;	if (sd_first_direct_byte != NO_BYTES_IN_DIRECT_ITEM) {	    if (fsck_mode(fs) == FSCK_CHECK) {		fsck_log ("The file %K: The wrong info about the tail in the StatData, "		    "first_direct_byte (%d) - should be (%d)\n", key, 		    sd_first_direct_byte, *first_direct_byte);	    } else {		fsck_log ("The file %K: The wrong info about the tail in the StatData, "		    "first_direct_byte (%d) - corrected to (%d)\n", key, 		    sd_first_direct_byte, *first_direct_byte);	    }	    return 1;	}	return 0;    }    /* there is direct item */    *first_direct_byte = (get_offset (key) & ~(blocksize - 1)) + 1;    if (*first_direct_byte != sd_first_direct_byte) {	if (fsck_mode(fs) == FSCK_CHECK) {	    fsck_log ("The file %K: The wrong info about the tail in the StatData, "		"first_direct_byte (%d) - should be (%d)\n", key, sd_first_direct_byte, 		*first_direct_byte);	} else {	    fsck_log ("The file %K: The wrong info about the tail in the StatData, "		"first_direct_byte (%d) - corrected to (%d)\n", key, sd_first_direct_byte, 		*first_direct_byte);	}	    	return 1;    }    return 0;}/* delete all items (but directory ones) with the same key 'ih' has   (including stat data of not a directory) and put them back at the   other place */void relocate_dir (struct item_head * ih, int change_ih){    struct key key;    struct key * rkey;    struct path path;    struct item_head * path_ih;    struct si * si;    __u32 new_objectid;    /* starting with the leftmost one - look for all items of file,       store them and delete */    key = ih->ih_key;    set_type_and_offset (KEY_FORMAT_1, &key, SD_OFFSET, TYPE_STAT_DATA);    si = 0;    while (1) {	reiserfs_search_by_key_4 (fs, &key, &path);		if (get_item_pos (&path) == B_NR_ITEMS (get_bh (&path))) {	    rkey = uget_rkey (&path);	    if (rkey && !not_of_one_file (&key, rkey)) {		/* file continues in the right neighbor */		key = *rkey;		pathrelse (&path);		continue;	    }	    /* there is no more items of a directory */	    pathrelse (&path);	    break;	}	if (is_stat_data_ih (get_ih(&path)))	    fix_obviously_wrong_sd_mode (&path);		path_ih = get_ih (&path);	if (not_of_one_file (&key, &(path_ih->ih_key))) {	    /* there are no more item with this key */	    pathrelse (&path);	    break;	}	/* ok, item found, but make sure that it is not a directory one */	if ((is_stat_data_ih (path_ih) && not_a_directory (get_item (&path))) ||	    is_direct_ih (path_ih) || is_indirect_ih (path_ih)) {	    /* item of not a directory found. Leave it in the               tree. FIXME: should not happen */	    key = path_ih->ih_key;	    set_offset (KEY_FORMAT_1, &key, get_offset (&key) + 1);	    pathrelse (&path);	    continue;	}	/* directory stat data ro directory item */	si = save_and_delete_file_item (si, &path);    }    if (!si) {	fsck_log ("relocate_dir: WARNING: No one item of the directory %K found\n", &key);	return;    }    /* get new objectid for relocation or get objectid with which file       was relocated already */    new_objectid = objectid_for_relocation (&ih->ih_key);    set_key_objectid (&ih->ih_key, new_objectid);    /* put all items removed back into tree */    while (si) {	fsck_log ("relocate_dir: Moving %k to ", &si->si_ih.ih_key);		set_key_objectid (&si->si_ih.ih_key, new_objectid);	fsck_log ("%k\n", &si->si_ih.ih_key);	if (get_offset (&(si->si_ih.ih_key)) == DOT_OFFSET) {	    /* fix "." entry to point to a directtory properly */	    struct reiserfs_de_head * deh;	    deh = (struct reiserfs_de_head *)si->si_dnm_data;	    set_deh_objectid (deh, new_objectid);	}	insert_item_separately (&(si->si_ih), si->si_dnm_data, 1/*was in tree*/);	si = remove_saved_item (si);    }}/* path is path to stat data. If file will be relocated - new_ih will contain   a key file was relocated with */int rebuild_check_regular_file (struct path * path, void * sd,				struct item_head * new_ih){    int is_new_file;//    struct key sd_key;    __u16 mode;    __u32 nlink;    __u64 real_size, saved_size;    __u32 blocks, saved_blocks;	/* proper values and value in stat data */    __u32 first_direct_byte, saved_first_direct_byte;    struct buffer_head * bh;    struct item_head * ih, sd_ih;    int fix_sd;    int symlnk = 0;    int retval;    retval = OK;    /* stat data of a file */    ih = get_ih (path);    bh = get_bh (path);    if (new_ih) {	/* this objectid is used already */	*new_ih = *ih;	pathrelse (path);	rewrite_file (new_ih, 1, 1);	linked_already(&new_ih->ih_key);	sem_pass_stat (fs)->oid_sharing_files_relocated ++;	retval = RELOCATED;	if (reiserfs_search_by_key_4 (fs, &(new_ih->ih_key), path) == ITEM_NOT_FOUND)	    reiserfs_panic ("%s: Could not find the StatData of the relocated file %k", 		__FUNCTION__, &(new_ih->ih_key));	/* stat data is marked unreachable again due to relocation, fix that */

⌨️ 快捷键说明

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