Commit 04f7ec60 authored by root's avatar root
Browse files

extract md and write on files per group

parent c62b6015
No preview for this file type
......@@ -10,8 +10,6 @@
#include <asm/uaccess.h>
#include <linux/buffer_head.h>
#include "extractmd.h"
#include "linux-4.0.9/fs/ext4/ext4.h"
......@@ -24,13 +22,15 @@ static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static struct ext4_group_desc *extractmd_get_group_desc(struct super_block *sb, ext4_group_t block_group);
static int extractmd_get_inode_loc(struct inode *, struct ext4_iloc *);
//static int extractmd_get_inode_loc(struct inode *, struct ext4_iloc *);
ext4_fsblk_t extractmd_block_bitmap(struct super_block *, struct ext4_group_desc *);
ext4_fsblk_t extractmd_inode_table(struct super_block *, struct ext4_group_desc *);
ext4_fsblk_t extractmd_inode_bitmap(struct super_block *, struct ext4_group_desc *);
__u32 extractmd_itable_unused_count(struct super_block *, struct ext4_group_desc *);
static struct ext4_inode *extractmd_get_ext4_inode(struct super_block *, unsigned long);
//static struct ext4_inode *extractmd_get_ext4_inode(struct super_block *, unsigned long);
long extractmd_write_file(struct file* file, char* data, unsigned long);
long extractmd_write_file(char *, char *, unsigned long);
long extractmd_write_file_per_group(char *, char*, unsigned long, int);
#define DEVICE_NAME "extractmd" /* Dev name as it appears in /proc/devices */
#define MAJOR_NUM 199 /* Device MAJOR number */
......@@ -68,78 +68,99 @@ static void __exit cleanup_extractmd(void)
static int extractmd_ioctl(struct inode *inode, struct file *f, struct extractmd_path *p)
{
struct file *fp = filp_open("/mnt", O_RDONLY, 0);
struct file *super_block_fp = filp_open(p->path_super_block, O_WRONLY | O_APPEND | O_CREAT, 0777);
struct file *group_descriptor_fp = filp_open(p->path_group_descriptor, O_WRONLY | O_APPEND | O_CREAT, 0777);
struct file *reserved_gdt_fp = filp_open(p->path_reserved_gdt, O_WRONLY | O_APPEND | O_CREAT, 0777);
struct file *inode_datablock_bitmap_fp = filp_open(p->path_inode_datablock_bitmap, O_WRONLY | O_APPEND | O_CREAT, 0777);
struct file *inode_table_fp = filp_open(p->path_inode_table, O_WRONLY | O_APPEND | O_CREAT, 0777);
struct file *fp = filp_open(p->path_mount_point, O_RDONLY, 0);
struct file *fp_dev = filp_open(p->path_device, O_RDONLY, 0);
//struct file *super_block_fp = filp_open(p->path_super_block, O_WRONLY | O_CREAT, 0777);
//struct file *group_descriptor_fp = filp_open(p->path_group_descriptor, O_WRONLY | O_CREAT, 0777);
//struct file *reserved_gdt_fp = filp_open(p->path_reserved_gdt, O_WRONLY | O_CREAT, 0777);
//struct file *block_bitmap_fp = filp_open(p->path_block_bitmap, O_WRONLY | O_CREAT, 0777);
//struct file *inode_bitmap_fp = filp_open(p->path_inode_bitmap, O_WRONLY | O_CREAT, 0777);
//struct file *inode_table_fp = filp_open(p->path_inode_table, O_WRONLY | O_CREAT, 0777);
int i = 0;
unsigned long nr_gd; // number of groupd descriptors
unsigned long nr_inode_table_block; // number of inode table blocks
struct buffer_head *bh_sb;
/*
* Super block part.
*/
struct super_block *sb = fp->f_inode->i_sb; // get super_block of vfs
//struct super_block *sb = fp->f_path.mnt->mnt_sb;
struct ext4_sb_info *sbi = EXT4_SB(sb); // get ext4_sb_info
struct ext4_super_block *sbt = sbi->s_es; // get ext4_super_block
ext4_group_t nr_group = sbi->s_groups_count;
struct block_device *bdev;
bdev = I_BDEV(fp_dev->f_mapping->host);
nr_gd = sbi->s_gdb_count * sbi->s_desc_per_block;
nr_inode_table_block = sbi->s_itb_per_group;
/* sync */
freeze_super(sb);
thaw_super(sb);
/*
* Goup desc part.
* EXCTRACTING SECTION!
*/
printk(KERN_INFO "Extractmd start!\n");
unsigned int i;
ext4_group_t nr_group = sbi->s_groups_count;
struct ext4_group_desc *gdp[nr_group];
//__le32 bitmaps[nr_group*2];
for (i = 0; i < nr_group; i++)
{
gdp[i] = extractmd_get_group_desc(sb,i);
//bitmaps[2*i] = gdp[i]->bg_block_bitmap_lo;
//bitmaps[2*i + 1] = gdp[i]->bg_inode_bitmap_lo;
/* super block in Group 0 */
bh_sb = __bread(bdev, 0, EXT4_BLOCK_SIZE(sb));
extractmd_write_file(p->path_super_block, bh_sb->b_data, EXT4_BLOCK_SIZE(sb));
//extractmd_write_file_per_group(p->path_super_block, bh_sb->b_data, EXT4_BLOCK_SIZE(sb), 0);
/* group descriptors, bit maps, inode tables */
for(i = 0; i < nr_group; i++)
{
struct ext4_group_desc *group = extractmd_get_group_desc(sb, i);
struct buffer_head *bh_group_descriptor = __bread(bdev, 1, EXT4_DESC_SIZE(sb) * nr_gd);
struct buffer_head *bh_block_bitmap = __bread(bdev, extractmd_block_bitmap(sb, group), EXT4_BLOCK_SIZE(sb));
struct buffer_head *bh_inode_bitmap = __bread(bdev, extractmd_inode_bitmap(sb, group), EXT4_BLOCK_SIZE(sb));
struct buffer_head *bh_inode_table = __bread(bdev, extractmd_inode_table(sb, group), EXT4_BLOCK_SIZE(sb) * nr_inode_table_block);
extractmd_write_file_per_group(p->path_group_descriptor, bh_group_descriptor->b_data, EXT4_DESC_SIZE(sb) * nr_gd, i);
extractmd_write_file_per_group(p->path_block_bitmap, bh_block_bitmap->b_data, EXT4_BLOCK_SIZE(sb), i);
extractmd_write_file_per_group(p->path_inode_bitmap, bh_inode_bitmap->b_data, EXT4_BLOCK_SIZE(sb), i);
extractmd_write_file_per_group(p->path_inode_table , bh_inode_table->b_data, EXT4_BLOCK_SIZE(sb) * nr_inode_table_block, i);
}
/*
* Inode part.
*/
//struct ext4_iloc iloc;
//extractmd_get_inode_loc(fp->f_inode, &iloc);
//struct ext4_inode *raw_inode = ext4_raw_inode(&iloc);
/*
* EXCTRACTING SECTION!
*/
printk(KERN_INFO "Extractmd start!\n");
freeze_super(sb);
// Super blocks //
struct ext4_super_block *super_block_buffer = sbt;
unsigned long super_block_size = sizeof(*sbt);
//extractmd_write_file(inode_table_fp, inode_table_buffer, nr_group * EXT4_BLOCK_SIZE(sb) * nr_inode_table_block);
// Group descriptors //
struct ext4_group_desc group_descriptor_buffer[nr_group];
unsigned int k;
for (k = 0; k < nr_group; k++)
{
group_descriptor_buffer[k] = *gdp[k];
}
unsigned long group_descriptor_size = sizeof(group_descriptor_buffer);
thaw_super(sb);
printk(KERN_INFO "Extractmd finish!\n");
/* inode table */
// Super blocks //
//ext4_group_t nr_super_block = 0;
extractmd_write_file(super_block_fp, super_block_buffer, super_block_size);
extractmd_write_file(group_descriptor_fp, group_descriptor_buffer, group_descriptor_size);
//struct ext4_super_block *super_block_buffer = (struct ext4_super_block *)bh->b_data;
//struct ext4_super_block *super_block_buffer;
//struct super_block *tmp = sb;
printk(KERN_INFO "Write file finish!\n");
//unsigned long super_block_size = sizeof(struct ext4_super_block);
// Group descriptors //
//struct ext4_group_desc group_descriptor_buffer[nr_group];
// unsigned int k;
// for (k = 0; k < nr_group; k++)
// {
// group_descriptor_buffer[k] = *gdp[k];
// }
//unsigned long group_descriptor_size = sizeof(group_descriptor_buffer);
//extractmd_write_file(group_descriptor_fp, group_descriptor_buffer, group_descriptor_size);
filp_close(fp, NULL);
filp_close(super_block_fp, NULL);
filp_close(group_descriptor_fp, NULL);
filp_close(reserved_gdt_fp, NULL);
filp_close(inode_datablock_bitmap_fp, NULL);
filp_close(inode_table_fp, NULL);
filp_close(fp_dev, NULL);
return 0;
}
......@@ -152,143 +173,146 @@ static struct ext4_group_desc *extractmd_get_group_desc(struct super_block *sb,
return (struct ext4_group_desc *)((__u8 *)sbi->s_group_desc[group_desc]->b_data + offset * EXT4_DESC_SIZE(sb));
}
static int extractmd_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
// static int extractmd_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
// {
// int in_mem = !ext4_test_inode_state(inode, EXT4_STATE_XATTR);
// struct ext4_group_desc *gdp;
// struct buffer_head *bh;
// struct super_block *sb = inode->i_sb;
// ext4_fsblk_t block;
// int inodes_per_block, inode_offset;
// iloc->bh = NULL;
// if (!ext4_valid_inum(sb, inode->i_ino))
// return -EIO;
// iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
// gdp = extractmd_get_group_desc(sb, iloc->block_group);
// if (!gdp)
// return -EIO;
// /*
// * Figure out the offset within the block group inode table
// */
// inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
// inode_offset = ((inode->i_ino - 1) %
// EXT4_INODES_PER_GROUP(sb));
// block = extractmd_inode_table(sb, gdp) + (inode_offset / inodes_per_block);
// iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb);
// bh = sb_getblk(sb, block);
// if (unlikely(!bh))
// return -ENOMEM;
// if (!buffer_uptodate(bh)) {
// lock_buffer(bh);
// /*
// * If the buffer has the write error flag, we have failed
// * to write out another inode in the same block. In this
// * case, we don't have to read the block because we may
// * read the old inode data successfully.
// */
// if (buffer_write_io_error(bh) && !buffer_uptodate(bh))
// set_buffer_uptodate(bh);
// if (buffer_uptodate(bh)) {
// /* someone brought it uptodate while we waited */
// unlock_buffer(bh);
// goto has_buffer;
// }
// /*
// * If we have all information of the inode in memory and this
// * is the only valid inode in the block, we need not read the
// * block.
// */
// if (in_mem) {
// struct buffer_head *bitmap_bh;
// int i, start;
// start = inode_offset & ~(inodes_per_block - 1);
// /* Is the inode bitmap in cache? */
// bitmap_bh = sb_getblk(sb, extractmd_inode_bitmap(sb, gdp));
// if (unlikely(!bitmap_bh))
// goto make_io;
// /*
// * If the inode bitmap isn't in cache then the
// * optimisation may end up performing two reads instead
// * of one, so skip it.
// */
// if (!buffer_uptodate(bitmap_bh)) {
// brelse(bitmap_bh);
// goto make_io;
// }
// for (i = start; i < start + inodes_per_block; i++) {
// if (i == inode_offset)
// continue;
// if (ext4_test_bit(i, bitmap_bh->b_data))
// break;
// }
// brelse(bitmap_bh);
// if (i == start + inodes_per_block) {
// /* all other inodes are free, so skip I/O */
// memset(bh->b_data, 0, bh->b_size);
// set_buffer_uptodate(bh);
// unlock_buffer(bh);
// goto has_buffer;
// }
// }
// make_io:
// /*
// * If we need to do any I/O, try to pre-readahead extra
// * blocks from the inode table.
// */
// if (EXT4_SB(sb)->s_inode_readahead_blks) {
// ext4_fsblk_t b, end, table;
// unsigned num;
// __u32 ra_blks = EXT4_SB(sb)->s_inode_readahead_blks;
// table = extractmd_inode_table(sb, gdp);
// /* s_inode_readahead_blks is always a power of 2 */
// b = block & ~((ext4_fsblk_t) ra_blks - 1);
// if (table > b)
// b = table;
// end = b + ra_blks;
// num = EXT4_INODES_PER_GROUP(sb);
// if (ext4_has_group_desc_csum(sb))
// num -= extractmd_itable_unused_count(sb, gdp);
// table += num / inodes_per_block;
// if (end > table)
// end = table;
// while (b <= end)
// sb_breadahead(sb, b++);
// }
// /*
// * There are other valid inodes in the buffer, this inode
// * has in-inode xattrs, or we don't have this inode in memory.
// * Read the block from disk.
// */
// //trace_ext4_load_inode(inode);
// get_bh(bh);
// bh->b_end_io = end_buffer_read_sync;
// submit_bh(READ | REQ_META | REQ_PRIO, bh);
// wait_on_buffer(bh);
// if (!buffer_uptodate(bh)) {
// brelse(bh);
// return -EIO;
// }
// }
// has_buffer:
// iloc->bh = bh;
// return 0;
// }
ext4_fsblk_t extractmd_block_bitmap(struct super_block *sb, struct ext4_group_desc *bg)
{
int in_mem = !ext4_test_inode_state(inode, EXT4_STATE_XATTR);
struct ext4_group_desc *gdp;
struct buffer_head *bh;
struct super_block *sb = inode->i_sb;
ext4_fsblk_t block;
int inodes_per_block, inode_offset;
iloc->bh = NULL;
if (!ext4_valid_inum(sb, inode->i_ino))
return -EIO;
iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
gdp = extractmd_get_group_desc(sb, iloc->block_group);
if (!gdp)
return -EIO;
/*
* Figure out the offset within the block group inode table
*/
inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
inode_offset = ((inode->i_ino - 1) %
EXT4_INODES_PER_GROUP(sb));
block = extractmd_inode_table(sb, gdp) + (inode_offset / inodes_per_block);
iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb);
bh = sb_getblk(sb, block);
if (unlikely(!bh))
return -ENOMEM;
if (!buffer_uptodate(bh)) {
lock_buffer(bh);
/*
* If the buffer has the write error flag, we have failed
* to write out another inode in the same block. In this
* case, we don't have to read the block because we may
* read the old inode data successfully.
*/
if (buffer_write_io_error(bh) && !buffer_uptodate(bh))
set_buffer_uptodate(bh);
if (buffer_uptodate(bh)) {
/* someone brought it uptodate while we waited */
unlock_buffer(bh);
goto has_buffer;
}
/*
* If we have all information of the inode in memory and this
* is the only valid inode in the block, we need not read the
* block.
*/
if (in_mem) {
struct buffer_head *bitmap_bh;
int i, start;
start = inode_offset & ~(inodes_per_block - 1);
/* Is the inode bitmap in cache? */
bitmap_bh = sb_getblk(sb, extractmd_inode_bitmap(sb, gdp));
if (unlikely(!bitmap_bh))
goto make_io;
/*
* If the inode bitmap isn't in cache then the
* optimisation may end up performing two reads instead
* of one, so skip it.
*/
if (!buffer_uptodate(bitmap_bh)) {
brelse(bitmap_bh);
goto make_io;
}
for (i = start; i < start + inodes_per_block; i++) {
if (i == inode_offset)
continue;
if (ext4_test_bit(i, bitmap_bh->b_data))
break;
}
brelse(bitmap_bh);
if (i == start + inodes_per_block) {
/* all other inodes are free, so skip I/O */
memset(bh->b_data, 0, bh->b_size);
set_buffer_uptodate(bh);
unlock_buffer(bh);
goto has_buffer;
}
}
make_io:
/*
* If we need to do any I/O, try to pre-readahead extra
* blocks from the inode table.
*/
if (EXT4_SB(sb)->s_inode_readahead_blks) {
ext4_fsblk_t b, end, table;
unsigned num;
__u32 ra_blks = EXT4_SB(sb)->s_inode_readahead_blks;
table = extractmd_inode_table(sb, gdp);
/* s_inode_readahead_blks is always a power of 2 */
b = block & ~((ext4_fsblk_t) ra_blks - 1);
if (table > b)
b = table;
end = b + ra_blks;
num = EXT4_INODES_PER_GROUP(sb);
if (ext4_has_group_desc_csum(sb))
num -= extractmd_itable_unused_count(sb, gdp);
table += num / inodes_per_block;
if (end > table)
end = table;
while (b <= end)
sb_breadahead(sb, b++);
}
/*
* There are other valid inodes in the buffer, this inode
* has in-inode xattrs, or we don't have this inode in memory.
* Read the block from disk.
*/
//trace_ext4_load_inode(inode);
get_bh(bh);
bh->b_end_io = end_buffer_read_sync;
submit_bh(READ | REQ_META | REQ_PRIO, bh);
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
brelse(bh);
return -EIO;
}
}
has_buffer:
iloc->bh = bh;
return 0;
return le32_to_cpu(bg->bg_block_bitmap_lo) | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
}
ext4_fsblk_t extractmd_inode_table(struct super_block *sb, struct ext4_group_desc *bg)
{
return le32_to_cpu(bg->bg_inode_table_lo) | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
......@@ -316,7 +340,7 @@ static int device_release(struct inode *inode, struct file *file)
return 0;
}
static struct ext4_inode *extractmd_get_ext4_inode(struct super_block *sb, unsigned long ino)
/*static struct ext4_inode *extractmd_get_ext4_inode(struct super_block *sb, unsigned long ino)
{
struct inode *inode = ilookup(sb, ino);
struct ext4_iloc iloc;
......@@ -324,21 +348,49 @@ static struct ext4_inode *extractmd_get_ext4_inode(struct super_block *sb, unsig
struct ext4_inode *ret = ext4_raw_inode(&iloc);
return ret;
}
}*/
long extractmd_write_file(struct file* file, char* data, unsigned long size)
long extractmd_write_file(char *path, char* data, unsigned long size)
{
long ret;
struct file *fp;
mm_segment_t fs;
fs = get_fs();
set_fs(KERNEL_DS);
ret = vfs_write(file, data, size, &file->f_pos);
fp = filp_open(path, O_WRONLY | O_CREAT, 0777);
ret = vfs_write(fp, data, size, &fp->f_pos);
set_fs(fs);
filp_close(fp, NULL);
return ret;
}
long extractmd_write_file_per_group(char * path, char* data, unsigned long size, int num)
{
long ret;
char filename[255] = {0};
struct file *fp;
mm_segment_t fs;
fs = get_fs();
set_fs(KERNEL_DS);
sprintf(filename, "%s%d", path, num);
fp = filp_open(filename, O_WRONLY | O_CREAT, 0777);
ret = vfs_write(fp, data, size, &fp->f_pos);
set_fs(fs);
filp_close(fp, NULL);
return ret;
}
module_init(init_extractmd);
module_exit(cleanup_extractmd);
......
......@@ -5,6 +5,7 @@ typedef unsigned int ext4_group_t;
* Structure of the super block
*/
struct extractmd_super_block {
__le64 padding[128];
/*00*/ __le32 s_inodes_count; /* Inodes count */
__le32 s_blocks_count_lo; /* Blocks count */
__le32 s_r_blocks_count_lo; /* Reserved blocks count */
......@@ -146,7 +147,6 @@ struct extractmd_group_desc
__le32 bg_exclude_bitmap_hi; /* Exclude bitmap block MSB */
__le16 bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bbitmap) BE */
__le16 bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+ibitmap) BE */
__u32 bg_reserved;
};
struct extractmd_inode {
......@@ -211,9 +211,12 @@ struct extractmd_inode {
struct extractmd_path
{
char *path_device;
char *path_mount_point;
char *path_super_block;
char *path_group_descriptor;
char *path_reserved_gdt;
char *path_inode_datablock_bitmap;
char *path_inode_bitmap;
char *path_block_bitmap;
char *path_inode_table;
};
\ No newline at end of file
No preview for this file type
No preview for this file type
No preview for this file type
#include <stdio.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <linux/fs.h>
#include "extractmd.h"
int main()
{
FILE *fp;
char buffer[5120];
struct extractmd_group_desc *gd;
unsigned int i;
fp = fopen("/home/user/md/group_descriptor", "r");
fgets(buffer, 5120, (FILE*)fp);
gd = (struct extractmd_group_desc *)buffer;
// printf("block bitmap : %hu\n",gd[4].bg_block_bitmap_lo);
// printf("block bitmap : %hu\n",gd[5].bg_block_bitmap_lo);
for (i =0; i<80; i++)
{
printf("block bitmap : %lu\n",gd[i].bg_block_bitmap_lo);
//printf("inode bitmap : %lu\n",gd[i].bg_inode_bitmap_lo);
}
fclose(fp);
}
\ No newline at end of file
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/fs.h>
#include "extractmd.h"
int main()
{
FILE *fp;
unsigned char *buffer = (unsigned char *)malloc(4096);
struct extractmd_group_desc *gd;
unsigned int i;
fp = fopen("/home/user/md/group_descriptor", "r");
fread(buffer, 4096, 1, (FILE*)fp);
gd = (struct extractmd_group_desc *)buffer;
printf("%lu\n",gd[1].bg_block_bitmap_lo);
printf("%lu\n",gd[1].bg_inode_bitmap_lo);
printf("%lu\n",gd[1].bg_inode_table_lo);
printf("%lu\n",gd[1].bg_free_blocks_count_lo);
printf("%lu\n",gd[1].bg_free_inodes_count_lo);
printf("%lu\n",gd[1].bg_used_dirs_count_lo);
printf("%lu\n",gd[1].bg_flags);
printf("%lu\n",gd[2].bg_block_bitmap_lo);
printf("%lu\n",gd[2].bg_inode_bitmap_lo);
printf("%lu\n",gd[2].bg_inode_table_lo);
printf("%lu\n",gd[2].bg_free_blocks_count_lo);