1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
/**
* reiserfsclone.c - part of Partclone project
*
* Copyright (c) 2007~ Thomas Tsai <thomas at nchc org tw>
*
* read reiserfs super block and bitmap
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdint.h>
#include <malloc.h>
#include <stdarg.h>
#include <getopt.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <linux/types.h>
#ifdef REISERFS
#include <reiserfs/reiserfs.h>
#elif REISER4
#include <reiser4/libreiser4.h>
#endif
#include "partclone.h"
#include "reiserfsclone.h"
#include "progress.h"
#include "fs_common.h"
dal_t *dal;
reiserfs_fs_t *fs;
char *EXECNAME = "partclone.reiserfs";
extern fs_cmd_opt fs_opt;
/// open device
static void fs_open(char* device){
if (!(dal = (dal_t*)file_dal_open(device, DEFAULT_BLOCK_SIZE, O_RDONLY))) {
log_mesg(0, 1, 1, fs_opt.debug, "%s: Couldn't create device abstraction for %s.\n", __FILE__, device);
}
if (!(fs = reiserfs_fs_open(dal, dal))) {
log_mesg(0, 1, 1, fs_opt.debug, "%s: Couldn't open filesystem on %s.\n", __FILE__, device);
}
if(fs_opt.ignore_fschk){
log_mesg(1, 0, 0, fs_opt.debug, "%s: Ignore filesystem check\n", __FILE__);
}else{
if (get_sb_umount_state(fs->super) != FS_CLEAN)
log_mesg(0, 1, 1, fs_opt.debug, "%s: Filesystem isn't in valid state. May be it is not cleanly unmounted.\n\n", __FILE__);
}
}
/// close device
static void fs_close(){
reiserfs_fs_close(fs);
file_dal_close(dal);
}
/// readbitmap - read bitmap
extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui)
{
reiserfs_bitmap_t *fs_bitmap;
reiserfs_tree_t *tree;
reiserfs_block_t *node;
unsigned long long blk = 0;
unsigned long long bused = 0, bfree = 0;
int start = 0;
int bit_size = 1;
int done = 0;
fs_open(device);
tree = reiserfs_fs_tree(fs);
fs_bitmap = tree->fs->bitmap;
/// init progress
progress_bar bprog; /// progress_bar structure defined in progress.h
progress_init(&bprog, start, fs->super->s_v1.sb_block_count, fs->super->s_v1.sb_block_count, BITMAP, bit_size);
for( blk = 0; blk < (unsigned long long)fs->super->s_v1.sb_block_count; blk++ ){
log_mesg(3, 0, 0, fs_opt.debug, "%s: block sb_block_count %llu\n", __FILE__, fs->super->s_v1.sb_block_count);
log_mesg(3, 0, 0, fs_opt.debug, "%s: block bitmap check %llu\n", __FILE__, blk);
if(reiserfs_tools_test_bit(blk, fs_bitmap->bm_map)){
bused++;
pc_set_bit(blk, bitmap);
}else{
bfree++;
pc_clear_bit(blk, bitmap);
}
/// update progress
update_pui(&bprog, blk, blk, done);
}
if(bfree != fs->super->s_v1.sb_free_blocks)
log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap free count err, free:%i\n", __FILE__, bfree);
fs_close();
/// update progress
update_pui(&bprog, 1, 1, 1);
}
/// read super block and write to image head
extern void initial_image_hdr(char* device, image_head* image_hdr)
{
fs_open(device);
strncpy(image_hdr->magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE);
strncpy(image_hdr->fs, reiserfs_MAGIC, FS_MAGIC_SIZE);
image_hdr->block_size = (int)fs->super->s_v1.sb_block_size;
image_hdr->totalblock = (unsigned long long)fs->super->s_v1.sb_block_count;
image_hdr->usedblocks = (unsigned long long)(fs->super->s_v1.sb_block_count - fs->super->s_v1.sb_free_blocks);
image_hdr->device_size = (unsigned long long)(image_hdr->block_size * image_hdr->totalblock);
fs_close();
}
|