int main(int argc, char *argv[]) {
    char * bytes_count_str = NULL;
    char * devname;
    reiserfs_filsys_t fs;
    struct reiserfs_super_block * rs;

    int c;
    int error;

    struct reiserfs_super_block *sb_old;

    unsigned long block_count_new;

    print_banner ("resize_reiserfs");

    while ((c = getopt(argc, argv, "fvcqs:")) != EOF) {
        switch (c) {
        case 's' :
            if (!optarg)
                die("%s: Missing argument to -s option", argv[0]);
            bytes_count_str = optarg;
            break;
        case 'f':
            opt_force = 1;
            break;
        case 'v':
            opt_verbose++;
            break;
        case 'n':
            /* no nowrite option at this moment */
            /* opt_nowrite = 1; */
            break;
        case 'c':
            opt_safe = 1;
            break;
        case 'q':
            opt_verbose = 0;
            break;
        default:
            print_usage_and_exit ();
        }
    }

    if (optind == argc )
        print_usage_and_exit();
    devname = argv[optind];

    fs = reiserfs_open(devname, O_RDONLY, &error, 0);
    if (!fs)
        die ("%s: can not open '%s': %s", argv[0], devname, strerror(error));

    if (no_reiserfs_found (fs)) {
        die ("resize_reiserfs: no reiserfs found on the device");
    }
    if (!spread_bitmaps (fs)) {
        die ("resize_reiserfs: cannot resize reiserfs in old (not spread bitmap) format.\n");
    }

    rs = fs->s_rs;

    if(bytes_count_str) {	/* new fs size is specified by user */
        block_count_new = calc_new_fs_size(rs_block_count(rs), fs->s_blocksize, bytes_count_str);
    } else {		/* use whole device */
        block_count_new = count_blocks(devname, fs->s_blocksize, -1);
    }

    if (is_mounted (devname)) {
        reiserfs_close(fs);
        return resize_fs_online(devname, block_count_new);
    }

    if (rs_state(rs) != REISERFS_VALID_FS)
        die ("%s: the file system isn't in valid state\n", argv[0]);

    if(!valid_offset(fs->s_dev, (loff_t) block_count_new * fs->s_blocksize - 1))
        die ("%s: %s too small", argv[0], devname);

    sb_old = 0;		/* Needed to keep idiot compiler from issuing false warning */
    /* save SB for reporting */
    if(opt_verbose) {
        sb_old = getmem(SB_SIZE);
        memcpy(sb_old, SB_DISK_SUPER_BLOCK(fs), SB_SIZE);
    }

    if (block_count_new == SB_BLOCK_COUNT(fs))
        die ("%s: Calculated fs size is the same as the previous one.", argv[0]);

    if (block_count_new > SB_BLOCK_COUNT(fs))
        expand_fs(fs, block_count_new);
    else
        shrink_fs(fs, block_count_new);

    if(opt_verbose) {
        sb_report(rs, sb_old);
        freemem(sb_old);
    }

    set_state (rs, REISERFS_VALID_FS);
    bwrite_cond(SB_BUFFER_WITH_SB(fs));

    if (opt_verbose) {
        printf("\nSyncing..");
        fflush(stdout);
    }
    reiserfs_close (fs);
    if (opt_verbose)
        printf("done\n");

    return 0;
}
int main(int argc, char *argv[]) {
	char * bytes_count_str = NULL;
	char * devname;
	struct stat statbuf;
	int c;

	int dev;
	struct reiserfs_super_block *sb, *sb_old;
	
	while ((c = getopt(argc, argv, "fvcqs:")) != EOF) {
		switch (c) {
		case 's' :
			  if (!optarg) 
				  die("%s: Missing argument to -s option", argv[0]);		
			  bytes_count_str = optarg;
			  break;
		case 'f':
		    opt_force = 1;
		    break;		 
		case 'v':
			opt_verbose++; 
			break;
		case 'n':
			/* no nowrite option at this moment */
			/* opt_nowrite = 1; */
			break;
		case 'c':
			opt_safe = 1;
			break;
		case 'q':
			opt_verbose = 0;
			break;
		default:
			print_usage_and_exit ();
		}
	}

	if (optind == argc || (!bytes_count_str))
		print_usage_and_exit();
	devname = argv[optind];

	/* open_device will die if it could not open device */
	dev = open (devname, O_RDWR);
	if (dev == -1)
		die ("%s: can not open '%s': %s", argv[0], devname, strerror (errno));

	if (fstat (dev, &statbuf) < 0)
		die ("%s: unable to stat %s", argv[0], devname);
  
	if (!S_ISBLK (statbuf.st_mode) && opt_force )
		die ("%s: '%s (%o)' is not a block device", 
			 argv[0], devname, statbuf.st_mode);

	read_superblock(dev);
	
	sb = (struct reiserfs_super_block *) g_sb_bh->b_data;
	g_block_count_new = calc_new_fs_size(sb->s_block_count,
					     sb->s_blocksize, bytes_count_str);
	if (is_mounted (devname)) {
		close(dev);
		if (!opt_force) 
	    	die ("%s: '%s' contains a mounted file system,\n"
			     "\tspecify -f option to resize the fs online\n", 
				 argv[0], devname);
		resize_fs_online(devname, g_block_count_new);
		return 0;
	}	

	if (sb->s_state != REISERFS_VALID_FS) 
		die ("%s: the file system isn't in valid state\n", argv[0]);
		
	if(!valid_offset(dev, (loff_t) g_block_count_new * sb->s_blocksize - 1))
		die ("%s: %s too small", argv[0], devname);

	sb_old = 0;		/* Needed to keep idiot compiler from issuing false warning */
	/* save SB for reporting */
	if(opt_verbose) {
		sb_old = getmem(sizeof(struct reiserfs_super_block));
		memcpy(sb_old, sb, sizeof(struct reiserfs_super_block));
    }

	if (g_block_count_new == sb->s_block_count) 
		die ("%s: Calculated fs size is the same as the previous one.",
			 argv[0]);
	if (g_block_count_new > sb->s_block_count) 
		expand_fs();
	else
		shrink_fs(g_block_count_new);

	if(opt_verbose) {
		sb_report(sb, sb_old);
		freemem(sb_old);
	}

	check_and_free_mem ();		
	
	if (opt_verbose) {
		printf("\nSyncing..");
		fflush(stdout);
	}
	fsync (dev);
	if (opt_verbose)
		printf("done\n");
	

	close(dev);
	
	return 0;
}