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

📄 resize_reiserfs.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
字号:
/*  * Copyright 2000-2004 by Hans Reiser, licensing governed by  * reiserfsprogs/README *//*   * Written by Alexander Zarochentcev. *  * FS resize utility  * */#define _GNU_SOURCE#include "resize.h"#include <limits.h>int opt_banner = 0;int opt_force = 0;int opt_verbose = 1;			/* now "verbose" option is default */int opt_nowrite = 0;int opt_safe = 0;int opt_skipj = 0;char * g_progname;/* calculate the new fs size (in blocks) from old fs size and the string   representation of new size */static long long int calc_new_fs_size(unsigned long count, 				      unsigned int bs, 				      char *bytes_str){    long long int bytes;    long long int blocks;    char *end;    int rel;    end = bytes_str + strlen(bytes_str) - 1;    rel = bytes_str[0] == '+' || bytes_str[0] == '-';    bytes = strtoll(bytes_str, &bytes_str, 10);        /* Some error occured while convertion or the specified        string is not valid. */    if (bytes == LONG_LONG_MIN || bytes == LONG_LONG_MAX || 	(bytes_str != end && bytes_str != end + 1))	return -EINVAL;    switch (*end) {    case 'G':    case 'g':	bytes *= 1024;    case 'M':    case 'm':	bytes *= 1024;    case 'K':    case 'k':	bytes *= 1024;    }	    blocks = bytes / bs;    return rel ? count + blocks : blocks;}/* print some fs parameters */static void sb_report(struct reiserfs_super_block * sb1,		      struct reiserfs_super_block * sb2){    printf(	"ReiserFS report:\n"	"blocksize             %d\n"	"block count           %d (%d)\n"	"free blocks           %d (%d)\n"	"bitmap block count    %d (%d)\n", 	get_sb_block_size(sb1),	get_sb_block_count(sb1), get_sb_block_count(sb2),	get_sb_free_blocks(sb1), get_sb_free_blocks(sb2),	get_sb_bmap_nr(sb1), get_sb_bmap_nr(sb2));};/* conditional bwrite */static int bwrite_cond (struct buffer_head * bh){    if(!opt_nowrite) { 	mark_buffer_uptodate(bh,1);	mark_buffer_dirty(bh);	bwrite(bh);    }    return 0;}/* the first one of the most important functions */static int expand_fs (reiserfs_filsys_t * fs, long long int block_count_new) {    unsigned int bmap_nr_new, bmap_nr_old;    struct reiserfs_super_block * sb;    unsigned int i;    reiserfs_reopen(fs, O_RDWR);    if (reiserfs_open_ondisk_bitmap (fs))	reiserfs_exit(1, "cannot open ondisk bitmap");    sb = fs->fs_ondisk_sb;    set_sb_fs_state (fs->fs_ondisk_sb, FS_ERROR);    bwrite_cond(fs->fs_super_bh);    if (reiserfs_expand_bitmap(fs->fs_bitmap2, block_count_new))	reiserfs_exit(1, "cannot expand bitmap\n");    /* count bitmap blocks in new fs */    bmap_nr_new = (block_count_new - 1) / (fs->fs_blocksize * 8) + 1;    bmap_nr_old = get_sb_bmap_nr(sb);	    /* update super block buffer*/    set_sb_free_blocks (sb, get_sb_free_blocks(sb) + 			(block_count_new - get_sb_block_count(sb)) - 			(bmap_nr_new - bmap_nr_old));    set_sb_block_count (sb, block_count_new);    set_sb_bmap_nr (sb, bmap_nr_new);    /* mark new bitmap blocks as used */    for (i = bmap_nr_old; i < bmap_nr_new; i++)	reiserfs_bitmap_set_bit (fs->fs_bitmap2, i * fs->fs_blocksize * 8);    /* normally, this is done by reiserfs_bitmap_set_bit, but if we    ** haven't actually added any bitmap blocks, the bitmap won't be dirtied.    **    ** In memory, reiserfsprogs puts zeros for the bits past the end of    ** the old filesystem.  But, on disk that bitmap is full of ones.      ** we explicitly dirty the bitmap here to make sure the zeros get written    ** to disk    */    fs->fs_bitmap2->bm_dirty = 1 ;        return 0;}static int resizer_check_fs_size(reiserfs_filsys_t *fs, long long int new_size) {    if (new_size < 0) {	    reiserfs_warning(stderr, "\nresizer_reiserfs: the new size "			     "value is wrong.\n\n");	    return new_size;    }        if (new_size == get_sb_block_count(fs->fs_ondisk_sb)) {	reiserfs_warning (stderr, "%s already is of the needed size. "			  "Nothing to be done\n\n", fs->fs_file_name);	return 1;    }    if (new_size < get_sb_block_count(fs->fs_ondisk_sb)) {	if (misc_device_mounted(fs->fs_file_name) > 0) {	    reiserfs_warning (stderr, "Can't shrink filesystem on-line.\n\n");	    return 1;	}    }    if (new_size >= get_sb_block_count(fs->fs_ondisk_sb)) {	loff_t offset = (loff_t)new_size * fs->fs_blocksize - 1;		if(!valid_offset(fs->fs_dev, offset)) {	    reiserfs_warning (stderr, "%s is of %lu blocks size only with "			      "reiserfs of %d blocks\nsize on it. You are "			      "trying to expand reiserfs up to %lu blocks "			      "size.\nYou probably forgot to expand your "			      "partition size.\n\n", fs->fs_file_name,			      count_blocks(fs->fs_file_name, fs->fs_blocksize),			      get_sb_block_count(fs->fs_ondisk_sb), new_size);	    return 1;	}    }    return 0;}int main(int argc, char *argv[]) {    char * bytes_count_str = NULL;    char * devname;    char * jdevice_name = NULL;    reiserfs_filsys_t * fs;    struct reiserfs_super_block * sb;    int c;    int error;    struct reiserfs_super_block *sb_old;    long long int block_count_new;    g_progname = basename(argv[0]);        if (argc < 2)	print_usage_and_exit();	    while ((c = getopt(argc, argv, "fvcqks:j:V")) != EOF) {	switch (c) {	case 's' :	    if (!optarg)		reiserfs_exit(1, "Missing argument to -s option");	    bytes_count_str = optarg;	    break;	case 'j' :	    if (!optarg) 		reiserfs_exit(1, "Missing argument to -j option");	    jdevice_name = optarg;	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;	case 'k':	    opt_skipj = 1;	    break;	case 'V':	    opt_banner++;	    break;	default:	    print_usage_and_exit ();	}    }    print_banner (g_progname);        if (opt_banner)	exit(0);        devname = argv[optind];    fs = reiserfs_open(devname, O_RDONLY, &error, 0, 1);    if (!fs) {	if (error) {		reiserfs_exit(1, "cannot open '%s': %s", 			      devname, strerror(error));        } else {		exit(1);	}    }    if (reiserfs_open_journal (fs, jdevice_name, O_RDWR | O_LARGEFILE)) {	reiserfs_exit(1, "Failed to open the journal device (%s).", 		      jdevice_name);    }        if (reiserfs_journal_params_check(fs)) {	if (!opt_skipj) {	    reiserfs_exit(1, "Wrong journal parameters detected on (%s)", 			  jdevice_name);	} else {	    reiserfs_close_journal(fs);	}    }    /* forced to continue without journal available/specified */    if (no_reiserfs_found (fs)) {	reiserfs_exit(1, "no reiserfs found on the device.");    }        if (!spread_bitmaps (fs)) {	reiserfs_exit(1, "cannot resize reiserfs in old (not spread "		      "bitmap) format.");    }    sb = fs->fs_ondisk_sb;    /* If size change was specified by user, calculate it,        otherwise take the whole device. */    block_count_new = bytes_count_str ? 	    calc_new_fs_size(get_sb_block_count(sb), 			     fs->fs_blocksize, bytes_count_str) :	    count_blocks(devname, fs->fs_blocksize);    if (resizer_check_fs_size(fs, block_count_new))	return 1;    if (misc_device_mounted(devname) > 0) {	reiserfs_close(fs);	error = resize_fs_online(devname, block_count_new);	reiserfs_warning(stderr, "\n\nresize_reiserfs: On-line resizing %s.\n\n",			 error ? "failed" : "finished successfully");	return error;    }    if (!reiserfs_is_fs_consistent (fs)) {	reiserfs_warning (stderr, "\n\nresize_reiserfs: run reiserfsck --check "	    "first\n\n");	reiserfs_close (fs);	return 1;    }    if (get_sb_umount_state(sb) != FS_CLEANLY_UMOUNTED)	/* fixme: shouldn't we check for something like: fsck guarantees: fs is ok */	reiserfs_exit(1, "the file system isn't in valid state.");		    /* Needed to keep idiot compiler from issuing false warning */    sb_old = 0;		        /* save SB for reporting */    if(opt_verbose) {	sb_old = getmem(SB_SIZE);	memcpy(sb_old, fs->fs_ondisk_sb, SB_SIZE);    }    error = (block_count_new > get_sb_block_count(fs->fs_ondisk_sb)) ? 	expand_fs(fs, block_count_new) : shrink_fs(fs, block_count_new);    if (error) {	reiserfs_warning(stderr, "\n\nresize_reiserfs: Resizing failed.\n\n ");	return error;    }    if(opt_verbose) {	sb_report(fs->fs_ondisk_sb, sb_old);	freemem(sb_old);    }    set_sb_fs_state (fs->fs_ondisk_sb, FS_CONSISTENT);    bwrite_cond(fs->fs_super_bh);	    if (opt_verbose) {	printf("\nSyncing..");	fflush(stdout);    }    reiserfs_close (fs);    if (opt_verbose)	printf("done\n");	    reiserfs_warning(stderr, "\n\nresize_reiserfs: Resizing finished "	"successfully.\n\n ");        return 0;}

⌨️ 快捷键说明

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