adjust algorithm, add inode map impl based on reallocated "vector"

master
Vitaliy Filippov 2013-12-26 13:00:03 +00:00
parent 0007290747
commit 6cb0239e7e
1 changed files with 74 additions and 6 deletions

View File

@ -3,16 +3,22 @@
*
* In theory it shouldn't be that hard:
* 1) If shrinking:
* 1.1) move inodes so that the end of inode table is empty
* 1.2) mark some blocks that belonged to inode table as free
* 1.1) mark the end of each inode table as reserved (to make sure the inode allocator won't allocate it)
* 1.2) if there were some inodes, move them away:
* 1.2.1) allocate a new place for each inode, copy it there
* 1.2.2) remember the old->new inode number mapping
* 1.3) mark some blocks that belonged to inode table as free
* 2) If growing:
* 2.1) move data blocks so there is enough space reserved for new inode table
* 2.2) mark some blocks that should belong to inode table as occupied
* 2.1) check all extra blocks that will be occupied by the growing inode tables,
* mark them as occupied if there are free ()
* 2.2) move data away from 'extra blocks' that were occupied
* 3) Change all inode numbers in directory entries so that
* new_num = (old_num/old_inodes_per_group)*new_inodes_per_group + (old_num%inodes_per_group)
* also translate old->new inode numbers remembered at (1.2.2)
* 4) Change superblock: s_inodes_count, s_free_inodes_count, s_inodes_per_group
* 5) Change block group descriptors: bg_inode_table_(lo,hi), bg_free_inodes_count_(lo,hi),
* bg_inode_bitmap_csum_(lo,hi), bg_itable_unused_(lo,hi)
* 6) If flex_bg is enabled, move parts of old inode tables so they are consecutive again
*
* This is a destructive process involving metadata change so it would be good if
* we could first write a file containing all necessary changes, then backup all
@ -29,11 +35,73 @@
#include <sys/time.h>
#include <errno.h>
#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
#include <ext2fs/ext2_fs.h>
#include <ext2fs/ext2fs.h>
#define _(a) (a)
typedef struct
{
__u32 *inode_map, inode_map_size, inode_map_alloc;
} realloc_data;
void add_inode_map(realloc_data *rd, __u32 old, __u32 new)
{
if (!old || !new)
{
return;
}
if (2*rd->inode_map_size >= rd->inode_map_alloc)
{
rd->inode_map_alloc += 1024;
rd->inode_map = realloc(rd->inode_map, sizeof(__u32) * rd->inode_map_alloc);
}
rd->inode_map[rd->inode_map_size*2] = old;
rd->inode_map[rd->inode_map_size*2+1] = new;
rd->inode_map_size++;
}
int compare_inode_map(const void *a, const void *b)
{
return *((__u32*)a) - *((__u32*)b);
}
void sort_inode_map(realloc_data *rd)
{
if (!rd->inode_map)
{
return;
}
qsort(rd->inode_map, rd->inode_map_size, sizeof(__u32)*2, compare_inode_map);
}
__u32 search_inode_map(realloc_data *rd, __u32 old)
{
__u32 start = 0, end = rd->inode_map_size, cur, cur_old;
if (!rd->inode_map)
{
return 0;
}
while (end-start > 1)
{
cur = (start+end)>>1;
cur_old = rd->inode_map[cur<<1];
if (cur < old)
{
start = cur+1;
}
else if (cur > old)
{
end = cur;
}
else
{
return rd->inode_map[(cur<<1)+1];
}
}
return 0;
}
const char *program_name = "realloc-inodes";
int change_inode_numbers(ext2_ino_t dir, int entry,