adjust algorithm, add inode map impl based on reallocated "vector"
parent
0007290747
commit
6cb0239e7e
|
@ -3,16 +3,22 @@
|
||||||
*
|
*
|
||||||
* In theory it shouldn't be that hard:
|
* In theory it shouldn't be that hard:
|
||||||
* 1) If shrinking:
|
* 1) If shrinking:
|
||||||
* 1.1) move inodes so that the end of inode table is empty
|
* 1.1) mark the end of each inode table as reserved (to make sure the inode allocator won't allocate it)
|
||||||
* 1.2) mark some blocks that belonged to inode table as free
|
* 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) If growing:
|
||||||
* 2.1) move data blocks so there is enough space reserved for new inode table
|
* 2.1) check all extra blocks that will be occupied by the growing inode tables,
|
||||||
* 2.2) mark some blocks that should belong to inode table as occupied
|
* 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
|
* 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)
|
* 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
|
* 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),
|
* 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)
|
* 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
|
* 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
|
* we could first write a file containing all necessary changes, then backup all
|
||||||
|
@ -29,11 +35,73 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "ext2fs/ext2_fs.h"
|
#include <ext2fs/ext2_fs.h>
|
||||||
#include "ext2fs/ext2fs.h"
|
#include <ext2fs/ext2fs.h>
|
||||||
|
|
||||||
#define _(a) (a)
|
#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";
|
const char *program_name = "realloc-inodes";
|
||||||
|
|
||||||
int change_inode_numbers(ext2_ino_t dir, int entry,
|
int change_inode_numbers(ext2_ino_t dir, int entry,
|
||||||
|
|
Loading…
Reference in New Issue