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:
|
||||
* 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,
|
||||
|
|
Loading…
Reference in New Issue