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

📄 do_shrink.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
字号:
/* * Copyright 2000-2004 by Hans Reiser, licensing governed by  * reiserfsprogs/README */#include "resize.h"#include <time.h>static unsigned long int_node_cnt   = 0, int_moved_cnt   = 0;static unsigned long leaf_node_cnt  = 0, leaf_moved_cnt  = 0;static unsigned long unfm_node_cnt  = 0, unfm_moved_cnt  = 0;static unsigned long total_node_cnt = 0;static unsigned long total_moved_cnt = 0;static unsigned long unused_block;static unsigned long blocks_used;static int block_count_mismatch = 0;static reiserfs_bitmap_t * bmp;static struct reiserfs_super_block * ondisk_sb;/* abnornal exit from block reallocation process */static void quit_resizer(reiserfs_filsys_t * fs){	/* save changes to bitmap blocks */	reiserfs_close (fs);	/* leave fs in ERROR state */	reiserfs_exit(1, "fs shrinking was not completed successfully, "		      "run reiserfsck.");}/* block moving */static unsigned long move_generic_block(reiserfs_filsys_t * fs, 					unsigned long block, 					unsigned long bnd, int h){    struct buffer_head * bh, * bh2;	/* primitive fsck */	if (block > get_sb_block_count(ondisk_sb)) {		fprintf(stderr, "resize_reiserfs: invalid block number "			"(%lu) found.\n", block);		quit_resizer(fs);	}		/* progress bar, 3D style :) */	if (opt_verbose)	    print_how_far(stderr, &total_node_cnt, blocks_used, 1, 0);	else	    total_node_cnt ++;	/* infinite loop check */	if( total_node_cnt > blocks_used && !block_count_mismatch) {		fputs("resize_reiserfs: warning: block count exeeded\n",stderr);		block_count_mismatch = 1;	}	if (block < bnd) /* block will not be moved */		return 0;		/* move wrong block */ 	bh = bread(fs->fs_dev, block, fs->fs_blocksize);	if (!bh)	    reiserfs_exit (1, "move_generic_block: bread failed.\n");	reiserfs_bitmap_find_zero_bit(bmp, &unused_block);	if (unused_block == 0 || unused_block >= bnd) {		fputs ("resize_reiserfs: can\'t find free block\n", stderr);		quit_resizer(fs);	}	/* blocknr changing */	bh2 = getblk(fs->fs_dev, unused_block, fs->fs_blocksize);	memcpy(bh2->b_data, bh->b_data, bh2->b_size);	reiserfs_bitmap_clear_bit(bmp, block);	reiserfs_bitmap_set_bit(bmp, unused_block);	brelse(bh);	mark_buffer_uptodate(bh2,1);	mark_buffer_dirty(bh2);	bwrite(bh2);	brelse(bh2);	total_moved_cnt++;	return unused_block;}static unsigned long move_unformatted_block(reiserfs_filsys_t * fs, unsigned long block, unsigned long bnd, int h){	unsigned long b;	unfm_node_cnt++;	b = move_generic_block(fs, block, bnd, h);	if (b)		unfm_moved_cnt++;	return b;		}/* recursive function processing all tree nodes */static unsigned long move_formatted_block(reiserfs_filsys_t * fs, unsigned long block, unsigned long bnd, int h){	struct buffer_head * bh;	struct item_head *ih;	unsigned long new_blocknr = 0;	int node_is_internal = 0;	unsigned int i, j;		bh = bread(fs->fs_dev, block, fs->fs_blocksize);	if (!bh)	    reiserfs_exit (1, "move_formatted_block: bread failed");		if (is_leaf_node (bh)) {				leaf_node_cnt++;				for (i = 0; i < B_NR_ITEMS(bh); i++) {			ih = B_N_PITEM_HEAD(bh, i);						/* skip the bad blocks. */			if (get_key_objectid (&ih->ih_key) == BADBLOCK_OBJID &&			    get_key_dirid (&ih->ih_key) == BADBLOCK_DIRID)				continue;						if (is_indirect_ih(ih)) {				__u32 * indirect;				indirect = (__u32 *)B_I_PITEM (bh, ih);				for (j = 0; j < I_UNFM_NUM(ih); j++) {					unsigned long  unfm_block;					if (d32_get (indirect, j) == 0) /* hole */						continue;					unfm_block = move_unformatted_block(fs, d32_get (indirect, j), bnd, h + 1);					if (unfm_block) {						d32_put (indirect, j, unfm_block);						mark_buffer_dirty(bh);					}				}			}			}	} else if (is_internal_node (bh)) { /* internal node */				int_node_cnt++;		node_is_internal = 1;				for (i=0; i <= B_NR_ITEMS(bh); i++) {			unsigned long moved_block;			moved_block = move_formatted_block(fs, get_dc_child_blocknr (B_N_CHILD (bh, i)), bnd, h+1);			if (moved_block) {			    	set_dc_child_blocknr (B_N_CHILD (bh, i), moved_block);				mark_buffer_dirty(bh);			}		}		} else {		DIE ("block (%lu) has invalid format\n", block);	}		if (buffer_dirty(bh)) {		mark_buffer_uptodate(bh,1);		bwrite(bh);	}		brelse(bh);			new_blocknr = move_generic_block(fs, block, bnd, h);	if (new_blocknr) {		if (node_is_internal)			int_moved_cnt++;		else			leaf_moved_cnt++;	}		return new_blocknr;}int shrink_fs(reiserfs_filsys_t * fs, long long int blocks){	unsigned long n_root_block;	unsigned int bmap_nr_new;	unsigned long bad_count;		ondisk_sb = fs->fs_ondisk_sb;			bmap_nr_new = (blocks - 1) / (8 * fs->fs_blocksize) + 1;	/* is shrinking possible ? */	if (get_sb_block_count(ondisk_sb) - blocks > 	    get_sb_free_blocks(ondisk_sb) + get_sb_bmap_nr(ondisk_sb) - 	    bmap_nr_new) 	{	    fprintf(stderr, "resize_reiserfs: can\'t shrink fs; too many "		"blocks already allocated\n");	    return -1;	}	/* warn about alpha version */	{		int c;		printf(		    "You are running BETA version of reiserfs shrinker.\n"		    "This version is only for testing or VERY CAREFUL use.\n"		    "Backup of you data is recommended.\n\n"		    "Do you want to continue? [y/N]:"		);		fflush(stdout);		c = getchar();		if (c != 'y' && c != 'Y')			exit(1);	}	reiserfs_reopen(fs, O_RDWR);	if (reiserfs_open_ondisk_bitmap (fs))	    reiserfs_exit(1, "cannot open ondisk bitmap");	bmp = fs->fs_bitmap2;	ondisk_sb = fs->fs_ondisk_sb;	set_sb_fs_state (fs->fs_ondisk_sb, FS_ERROR);	mark_buffer_uptodate(fs->fs_super_bh, 1);	mark_buffer_dirty(fs->fs_super_bh);	bwrite(fs->fs_super_bh);	/* calculate number of data blocks */			blocks_used = 	    get_sb_block_count(fs->fs_ondisk_sb)	    - get_sb_free_blocks(fs->fs_ondisk_sb)	    - get_sb_bmap_nr(fs->fs_ondisk_sb)	    - get_jp_journal_size(sb_jp (fs->fs_ondisk_sb))	    - REISERFS_DISK_OFFSET_IN_BYTES / fs->fs_blocksize	    - 2; /* superblock itself and 1 descriptor after the journal */	unused_block = 1;	if (opt_verbose) {		printf("Processing the tree: ");		fflush(stdout);	}	n_root_block = move_formatted_block(fs, get_sb_root_block(ondisk_sb), 	    blocks, 0);		if (n_root_block)	    set_sb_root_block (ondisk_sb, n_root_block);	if (opt_verbose)	    printf ("\n\nnodes processed (moved):\n"		    "int        %lu (%lu),\n"		    "leaves     %lu (%lu),\n" 		    "unfm       %lu (%lu),\n"		    "total      %lu (%lu).\n\n",		    int_node_cnt, int_moved_cnt,		    leaf_node_cnt, leaf_moved_cnt, 		    unfm_node_cnt, unfm_moved_cnt,		    (unsigned long)total_node_cnt, total_moved_cnt);	if (block_count_mismatch) {	    fprintf(stderr, "resize_reiserfs: data block count %lu"		    " doesn\'t match data block count %lu from super block\n",		    (unsigned long)total_node_cnt, blocks_used);	}	{	    unsigned long l;	    /* make sure that none of truncated block are in use */	    printf("check for used blocks in truncated region\n");	    for (l = blocks; l < fs->fs_bitmap2->bm_bit_size; l ++) {		if ((l % (fs->fs_blocksize * 8)) == 0)		    continue;		if (reiserfs_bitmap_test_bit (fs->fs_bitmap2, l))		    printf ("<%lu>", l);	    }	    printf("\n");	}	badblock_list(fs, mark_badblock, NULL);		if (fs->fs_badblocks_bm) {		bad_count = reiserfs_bitmap_ones(fs->fs_badblocks_bm);		reiserfs_shrink_bitmap (fs->fs_badblocks_bm, blocks);		add_badblock_list(fs, 1);		bad_count -= reiserfs_bitmap_ones(fs->fs_badblocks_bm);	} else		bad_count = 0;		reiserfs_shrink_bitmap (fs->fs_bitmap2, blocks);	set_sb_free_blocks (ondisk_sb, get_sb_free_blocks(ondisk_sb)			    - (get_sb_block_count(ondisk_sb) - blocks)			    + (get_sb_bmap_nr(ondisk_sb) - bmap_nr_new)			    + bad_count);	set_sb_block_count (ondisk_sb, blocks);	set_sb_bmap_nr (ondisk_sb, bmap_nr_new);	return 0;}

⌨️ 快捷键说明

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