Пример #1
0
/* block moving */
static unsigned long move_generic_block(unsigned long block, unsigned long bnd, int h)
{
    struct buffer_head * bh, * bh2;

	/* primitive fsck */
	if (block > rs_block_count(rs)) {
		fprintf(stderr, "resize_reiserfs: invalid block number (%lu) found.\n", block);
		quit_resizer();
	}
	/* progress bar, 3D style :) */
	if (opt_verbose)
	    print_how_far(&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->s_dev, block, fs->s_blocksize);

	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();
	}

	/* blocknr changing */
	bh2 = getblk(fs->s_dev, unused_block, fs->s_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;
}
Пример #2
0
static void go_through (reiserfs_filsys_t fs)
{
    struct buffer_head * bh;
    int i;
    int what_node;
    unsigned long done = 0, total;

    if (fsck_mode (fs) == DO_TEST) {
	/* just to test pass0_correct_leaf */
	bh = bread (fs->s_dev, stats(fs)->test, fs->s_blocksize);

	/*
	if (is_leaf_bad (bh)) {
	    fsck_progress ("###############  bad #################\n");
	}
	*/
	pass0_correct_leaf (fs, bh);
	
	print_block (stdout, fs, bh, 3, -1, -1);

	if (is_leaf_bad (bh)) {
	    fsck_progress ("############### still bad #################\n");
	}
	brelse (bh);
	reiserfs_free (fs);
	exit(4);
    }


    total = reiserfs_bitmap_ones (fsck_disk_bitmap (fs));
    fsck_progress ("\nPass 0 (%lu (of %lu) blocks will be read):\n",
		   total, SB_BLOCK_COUNT (fs));


    for (i = 0; i < SB_BLOCK_COUNT (fs); i ++) {
	if (!is_to_be_read (fs, i))
	    continue;

	print_how_far (&done, total, 1, fsck_quiet (fs));

	bh = bread (fs->s_dev, i, fs->s_blocksize);
	if (!bh) {
	    /* we were reading one block at time, and failed, so mark
	       block bad */
	    fsck_progress ("pass0: reading block %lu failed\n", i);
	    continue;
	}

	if (not_data_block (fs, i))
	    reiserfs_panic ("not data block found");
	
	stats (fs)->analyzed ++;
	what_node = who_is_this (bh->b_data, fs->s_blocksize);
	if ( what_node != THE_LEAF ) {
	    brelse (bh);
	    continue;
	}
	pass0_correct_leaf (fs, bh);
	brelse (bh);
    }


#if 0
    for (i = 0; i < SB_BLOCK_COUNT (fs); i += nr_to_read) {
	to_scan = how_many_to_scan (fs, i, nr_to_read);
	if (to_scan) {
	    print_how_far (&done, total, to_scan, fsck_quiet (fs));

	    /* at least one of nr_to_read blocks is to be checked */
	    bbh = bread (fs->s_dev, i / nr_to_read, fs->s_blocksize * nr_to_read);
	    if (bbh) {
		for (j = 0; j < nr_to_read; j ++) {
		    if (!is_to_be_read (fs, i + j))
			continue;

		    if (not_data_block (fs, i + j))
			reiserfs_panic ("not data block found");

		    stats (fs)->analyzed ++;

		    data = bbh->b_data + j * fs->s_blocksize;
		    what_node = who_is_this (data, fs->s_blocksize);
		    if ( what_node != THE_LEAF ) {
			continue;
		    }

		    /* the node looks like a leaf, but it still can be
		       not perfect */
		    bh = make_buffer (fs->s_dev, i + j, fs->s_blocksize, data);

		    /*printf ("block %lu .. ", bh->b_blocknr);fflush(stdout);*/
		    pass0_correct_leaf (fs, bh);
		    /*printf ("ok\n");fflush(stdout);*/

		    brelse (bh);
		}

		if (buffer_dirty (bbh))
		    bwrite (bbh);
		bforget (bbh);
	    } else {
		done -= to_scan;
		/* bread failed */
		if (nr_to_read != 1) {
		    /* we tryied to read bunch of blocks. Try to read them by one */
		    nr_to_read = 1;
		    i --;
		    continue;
		} else {
		    /* we were reading one block at time, and failed, so mark
                       block bad */
		    fsck_progress ("pass0: block %lu is bad, marked used\n", i);
		}
	    }
	}

	if (nr_to_read == 1 && ((i + 1) % NR_TO_READ) == 0) {
	    /* we have read NR_TO_READ blocks one at time, switch back to
               reading NR_TO_READ blocks at time */
	    i -= (NR_TO_READ - 1);
	    nr_to_read = NR_TO_READ;
	}
    }
#endif


    /* just in case */
    mark_objectid_really_used (proper_id_map (fs), REISERFS_ROOT_OBJECTID);

    fsck_progress ("\n");

    if (fsck_save_leaf_bitmap (fs)) {
	reiserfs_bitmap_save (stats (fs)->new_bitmap_file_name, leaves_bitmap);
    }
}
Пример #3
0
//
// set up start journal block and journal size
// make journal unreplayable by kernel replay routine
//
void reset_journal (struct super_block * s)
{
    int i ;
    struct buffer_head *bh ;
    int done = 0;
    int len;
    int start;

    /* first block of journal */
    s->u.reiserfs_sb.s_rs->s_journal_block = get_journal_start (s);
    start = s->u.reiserfs_sb.s_rs->s_journal_block;

    /* journal size */
    s->u.reiserfs_sb.s_rs->s_orig_journal_size = get_journal_size (s);
    len = s->u.reiserfs_sb.s_rs->s_orig_journal_size + 1;

    printf ("Resetting journal - "); fflush (stdout);

    for (i = 0 ; i < len ; i++) {
	print_how_far (&done, len);
	bh = getblk (s->s_dev, start + i, s->s_blocksize) ;
	memset(bh->b_data, 0, s->s_blocksize) ;
	mark_buffer_dirty(bh,0) ;
	mark_buffer_uptodate(bh,0) ;
	bwrite (bh);
	brelse(bh) ;
    }
    printf ("\n"); fflush (stdout);
    
#if 0 /* need better way to make journal unreplayable */


    /* have journal_read to replay nothing: look for first non-desc
       block and set j_first_unflushed_offset to it */
    {   
	int offset;
	struct buffer_head * bh, *jh_bh;
	struct reiserfs_journal_header * j_head;
	struct reiserfs_journal_desc * desc;


	jh_bh = bread (s->s_dev, s->u.reiserfs_sb.s_rs->s_journal_block + s->u.reiserfs_sb.s_rs->s_orig_journal_size,
		       s->s_blocksize);
	j_head = (struct reiserfs_journal_header *)(jh_bh->b_data);

	for (offset = 0; offset < s->u.reiserfs_sb.s_rs->s_orig_journal_size; offset ++) {
	    bh = bread (s->s_dev, s->u.reiserfs_sb.s_rs->s_journal_block + offset, s->s_blocksize);
	    desc = (struct reiserfs_journal_desc *)((bh)->b_data);
	    if (memcmp(desc->j_magic, JOURNAL_DESC_MAGIC, 8)) {
		/* not desc block found */
		j_head->j_first_unflushed_offset = offset;
		brelse (bh);
		break;
	    }
	    brelse (bh);
	}

	mark_buffer_uptodate (jh_bh, 1);
	mark_buffer_dirty (jh_bh, 1);
	bwrite (jh_bh);
	brelse (jh_bh);
    }
#endif
}
Пример #4
0
void pack_partition (struct super_block * s)
{
    int i, j, k;
    uint32_t blocknumber32;
    uint16_t reclen16, data16;
    __u32 done = 0;
    char * data;
    long long bytes_to_transfer = 0;
    struct buffer_head * bh;
    int total_block_number;


    total_block_number = get_total_block_number ();
    

    /* write filesystem's block size to stdout as 16 bit number */
    reclen16 = htons (s->s_blocksize);
    if (opt_pack == 'p' || opt_pack_all == 'p')
	write (1, &reclen16, sizeof (uint16_t));
    bytes_to_transfer = sizeof (uint16_t);

    /* go through blocks which are marked used in cautious bitmap */
    for (i = 0; i < SB_BMAP_NR (s); i ++) {
	for (j = 0; j < s->s_blocksize; j ++) {
	    /* make sure, that we are not out of the device */
	    if (i * s->s_blocksize * 8 + j * 8 == SB_BLOCK_COUNT (s))
		goto out_of_bitmap;

	    if (i * s->s_blocksize * 8 + j * 8 + 8 > SB_BLOCK_COUNT (s))
		die ("build_the_tree: Out of bitmap");

	    if (opt_pack_all == 0)
		if (SB_AP_BITMAP (s)[i]->b_data[j] == 0) {
		    /* skip busy block if 'a' not specified */
		    continue;
		}

	    /* read 8 blocks at once */
	    bh = bread (s->s_dev, i * s->s_blocksize + j, s->s_blocksize * 8);
	    for (k = 0; k < 8; k ++) {
		__u32 block;
		
		block = i * s->s_blocksize * 8 + j * 8 + k;
		
		if (opt_pack_all == 0 && (SB_AP_BITMAP (s)[i]->b_data[j] & (1 << k)) == 0)
		    continue;
#if 0
		if ((SB_AP_BITMAP (s)[i]->b_data[j] & (1 << k)) == 0  || /* k-th block is free */
		    block < SB_BUFFER_WITH_SB (s)->b_blocknr) /* is in skipped for drive manager area */
		    continue;
#endif
		
		print_how_far (&done, total_block_number);
		
		data = bh->b_data + k * s->s_blocksize;

		if (not_formatted_node (data, s->s_blocksize)) {
		    /* ok, could not find formatted node here. But
                       this can be commit block, or bitmap which has
                       to be transferred */
		    if (!not_data_block (s, block)) {
			/* this is usual unformatted node. Transfer
                           its number only to erase previously existed
                           formatted nodes on the partition we will
                           apply transferred metadata to */
	    
			/* size of following record in network byte order */
			reclen16 = htons (2);

			/* the record record */
			data16 = htons (MAX_HEIGHT + 1);/*?*/
			data = (char *)&data16;
		    } else {
			/* write super block and bitmap block must be transferred as are */
			/* size of record  */
			reclen16 = htons (s->s_blocksize);
	    
			/* the record itself */
			data = data;
		    }
		} else {
		    /* any kind of formatted nodes gets here (super
                       block, desc block of journal): FIXME: it would
                       be useful to be able to find commit blocks */
		    zero_direct_items (data);
		    /* FIXME: do other packing */
		    /* write size of following record */
		    reclen16 = htons (s->s_blocksize);
		    
		    /* the record itself */
		    data = data;

#if 0
		    if (blkh->blk_level > DISK_LEAF_NODE_LEVEL) {
			/* block must look like internal node on the target
			   partition. But (currently) fsck do not consider internal
			   nodes, therefore we do not have to transfer contents of
			   internal nodes */
	    
			/* size of following record in network byte order */
			reclen16 = htons (2);
	    
			/* the record itself */
			data16 = htons (DISK_LEAF_NODE_LEVEL + 1);
			data = (char *)&data16;	  
		    } else {
	    
			/* leaf node found */
			ih = (struct item_head *)(blkh + 1);
	    
			/* fill direct items with 0s */
			for (l = 0; l < blkh->blk_nr_item; l ++, ih ++)
			    if (I_IS_DIRECT_ITEM (ih)) {
				direct_items ++;
				direct_item_total_length += ih->ih_item_len;
				memset ((char *)blkh + ih->ih_item_location, 0, ih->ih_item_len);
			    }
	    
			/* write size of following record */
			reclen16 = htons (s->s_blocksize);
	    
			/* the record itself */
			data = (char *)blkh;
		    }
#endif
		}
	  
		/*fprintf (stderr, "block %d, reclen %d\n", block, ntohs (reclen16));*/
	
		/* write block number */
		blocknumber32 = htonl (block);
		bytes_to_transfer += sizeof (uint32_t) + sizeof (uint16_t) + ntohs (reclen16);
		if (opt_pack == 'p' || opt_pack_all == 'p') {
		    write (1, &blocknumber32, sizeof (uint32_t));
		    /* write record len */
		    write (1, &reclen16, sizeof (uint16_t));
		    /* write the record */
		    write (1, data, ntohs (reclen16));
		}
	    }
      
	    bforget (bh);
	}
    }
    
 out_of_bitmap:
    fprintf (stderr, "done\n");
    if (opt_pack == 'c' || opt_pack_all == 'c')
	fprintf (stderr, "Bytes to transfer %Ld, sequential 0s %d in %d sequeneces (%items (%d unreacable))\n",
		 bytes_to_transfer, direct_item_total_length, direct_items, items, unreachable_items);
    else
	fprintf (stderr, "Bytes dumped %Ld, sequential 0s %d in %d sequeneces\n",
		 bytes_to_transfer, direct_item_total_length, direct_items);
    
    
}