From ec9eb54d2f36f9c98607b5fc8745f978cfebd63e Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 14 May 2018 02:40:06 +0100 Subject: support non extents and fast symlinks --- src/Makefile.am | 28 +++++++++++++++++++++------- src/clone_data.c | 3 ++- src/clone_ea.c | 2 +- src/clone_extents.c | 22 ++++++++++++---------- src/clone_fs.c | 15 +++++++++++++-- src/clone_inode.c | 23 ++++++++++++++++++----- src/prototypes.h | 27 +++++++++++++++------------ src/zap_inode.c | 6 +++--- 8 files changed, 85 insertions(+), 41 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index da2463f..dafcc87 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,7 +7,7 @@ HSRCS=project.h prototypes.h noinst_HEADERS=${HSRCS} bin_PROGRAMS = ext_clone -CSRCS= clone_data.c clone_ea.c clone_extents.c clone_inode.c ea_map.c ext_clone.c stats.c clone_fs.c zap_fs.c zap_inode.c +CSRCS= clone_data.c clone_ea.c clone_extents.c clone_inode.c ea_map.c ext_clone.c stats.c clone_fs.c zap_fs.c zap_inode.c clone_blocks.c ext_clone_SOURCES = ${CSRCS} ext_clone_LDADD = ${LIBE2P_LIB} ${LIBEXT2FS_LIB} ${LIBCOM_ERR_LIB} ${LIBDB_LIB} -lm @@ -23,12 +23,26 @@ src.img: mkdir -p src rm -f src.img truncate -s 128M src.img - mkfs.ext4 -b 4096 -O 64bit -E stride=16,stripe-width=112 src.img + mkfs.ext3 -b 4096 -E stride=16,stripe-width=112 src.img + mount src.img src + mkdir src/ext3 + (cd src/ext3 && git clone git://git.panaceas.org/tools/sympathy ) + (cd src/ext3 && truncate -s 256m holey && dd if=/dev/urandom of=holey conv=notrunc,nocreat bs=1024k seek=37 count=1 ) + (cd src/ext3 && ln holey linky) + (cd src/ext3 && touch empty) + (cd src/ext3 && ln -s holey slinky) + umount src + tune2fs -O extents,uninit_bg,dir_index,has_journal src.img + mount src.img src + mkdir src/ext4 + (cd src/ext4 && git clone git://git.panaceas.org/tools/sympathy ) + (cd src/ext4 && truncate -s 256m holey && dd if=/dev/urandom of=holey conv=notrunc,nocreat bs=1024k seek=37 count=1 ) + (cd src/ext4 && ln holey linky) + (cd src/ext4 && touch empty) + (cd src/ext4 && ln -s holey slinky) + umount src + e2fsck -f -y src.img mount src.img src - (cd src && git clone git://git.panaceas.org/tools/sympathy ) - (cd src && truncate -s 8g holey && dd if=/dev/zero of=holey conv=notrunc,nocreat bs=1024k seek=4000 count=1 ) - (cd src && ln holey linky) - (cd src && touch empty) ls -lZR src ls -lR src umount src @@ -56,7 +70,7 @@ test: ext_clone src.img mkdir -p dst mount -o ro src.img src mount -o ro dst.img dst - rsync -varX -n src/ dst/ + rsync -vScarX -n src/ dst/ umount dst umount src rmdir src diff --git a/src/clone_data.c b/src/clone_data.c index 3083914..24aaf62 100644 --- a/src/clone_data.c +++ b/src/clone_data.c @@ -44,9 +44,10 @@ int clone_data (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct file_len -= offset; - if (len > file_len) + if ((len > file_len) || (!len)) len = file_len; + while (len) { fetch = len > BUF_SZ ? BUF_SZ : len; diff --git a/src/clone_ea.c b/src/clone_ea.c index d8287b7..3dce3cc 100644 --- a/src/clone_ea.c +++ b/src/clone_ea.c @@ -57,7 +57,7 @@ int clone_ea (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct e if (ret) return ret; dst_i->i_file_acl = dst_blk & 0xffffffff; - dst_i->osd2.linux2.l_i_file_acl_high= dst_blk >> 32; + dst_i->osd2.linux2.l_i_file_acl_high = dst_blk >> 32; dst_i->i_blocks += len * (dst_fs->blocksize / 512); EXT2_MOAN_FAIL (ret, ext2fs_adjust_ea_refcount2 (dst_fs, dst_blk, buf, +1, NULL)); diff --git a/src/clone_extents.c b/src/clone_extents.c index 09c639b..4c13185 100644 --- a/src/clone_extents.c +++ b/src/clone_extents.c @@ -1,9 +1,9 @@ #include "project.h" -static int allocate_extent (ext2_filsys fs, ext2_ino_t i_num, ext2_extent_handle_t eh, blk64_t l_start, blk64_t len, __u32 flags) +int allocate_extent (ext2_filsys fs, ext2_ino_t i_num, ext2_extent_handle_t eh, blk64_t l_start, blk64_t len, __u32 flags) { - blk64_t goal, start, size, want,max; + blk64_t goal, start, size, want, max; dgrp_t group; int ret; struct ext2fs_extent e; @@ -12,7 +12,7 @@ static int allocate_extent (ext2_filsys fs, ext2_ino_t i_num, ext2_extent_handle goal = ext2fs_group_first_block2 (fs, group); - max = (flags & EXT2_EXTENT_FLAGS_UNINIT) ? EXT_UNINIT_MAX_LEN:EXT_INIT_MAX_LEN; + max = (flags & EXT2_EXTENT_FLAGS_UNINIT) ? EXT_UNINIT_MAX_LEN : EXT_INIT_MAX_LEN; ret = 0; @@ -41,11 +41,11 @@ static int allocate_extent (ext2_filsys fs, ext2_ino_t i_num, ext2_extent_handle if (ret) { - fprintf(stderr,"Failed extent was:\n"); - fprintf(stderr," e.e_pblk = %lld\n",(long long int) e.e_pblk); - fprintf(stderr," e.e_lblk = %lld\n",(long long int) e.e_lblk); - fprintf(stderr," e.e_len = %lld\n",(long long int) e.e_len); - fprintf(stderr," e.e_flags = 0x%llx\n",(long long int) e.e_flags); + fprintf (stderr, "Failed extent was:\n"); + fprintf (stderr, " e.e_pblk = %lld\n", (long long int) e.e_pblk); + fprintf (stderr, " e.e_lblk = %lld\n", (long long int) e.e_lblk); + fprintf (stderr, " e.e_len = %lld\n", (long long int) e.e_len); + fprintf (stderr, " e.e_flags = 0x%llx\n", (long long int) e.e_flags); break; } @@ -99,10 +99,12 @@ int clone_extents (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, str if (e.e_flags & EXT2_EXTENT_FLAGS_LEAF) { - if (!l_len) + if (!l_len) { + l_start = e.e_lblk; flags = e.e_flags; + } - if (((l_start + l_len) != e.e_lblk) || (flags != e.e_flags) ) { + if (((l_start + l_len) != e.e_lblk) || (flags != e.e_flags)) { ret = allocate_extent (dst_fs, i_num, dst_e, l_start, l_len, flags); if (ret) break; diff --git a/src/clone_fs.c b/src/clone_fs.c index 1269b30..332a09b 100644 --- a/src/clone_fs.c +++ b/src/clone_fs.c @@ -13,6 +13,13 @@ int clone_fs (ext2_filsys src_fs, ext2_filsys dst_fs) if (ret) return -1; +#if 0 + EXT2_MOAN_FAIL (ret, ext2fs_inode_scan_flags (scan, EXT2_SF_SKIP_MISSING_ITABLE, 0)); + + if (ret) return -1; + +#endif + for (;;) { EXT2_MOAN_FAIL (ret, ext2fs_get_next_inode (scan, &i_num, &src_i)); @@ -36,16 +43,20 @@ int clone_fs (ext2_filsys src_fs, ext2_filsys dst_fs) if (i_num == src_fs->super->s_journal_inum) skip = 1; + // if (ext2fs_test_inode_bitmap2(src_fs->inode_map,i_num)) skip=1; + if (skip) continue; - if (clone_inode (src_fs, dst_fs, i_num, &src_i)) { + ret = clone_inode (src_fs, dst_fs, i_num, &src_i); + + if (ret) { fprintf (stderr, "clone_inode(%d) failed\n", (int) i_num); break; } } ext2fs_close_inode_scan (scan); - return 0; + return ret; } diff --git a/src/clone_inode.c b/src/clone_inode.c index 33d4647..3f7a94b 100644 --- a/src/clone_inode.c +++ b/src/clone_inode.c @@ -5,7 +5,7 @@ int clone_inode (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struc struct ext2_inode dst_i; int ret; - // printf ("cloning inode %d\n", (int) i_num); + //printf ("cloning inode %d %d\n", (int) i_num, ext2fs_test_inode_bitmap2(src_fs->inode_map, i_num)); EXT2_MOAN_FAIL (ret, ext2fs_read_inode (dst_fs, i_num, &dst_i)); @@ -30,18 +30,31 @@ int clone_inode (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struc } } else { + /* Two possibilities here - fast links or old style block lists */ - EXT2_MOAN_FAIL (ret, ext2fs_write_inode (dst_fs, i_num, &dst_i)); + if (!ext2fs_inode_has_valid_blocks2 (src_fs, src_i)) { + /*inline -symlink*/ + memcpy (&dst_i.i_block, src_i->i_block, sizeof (dst_i.i_block)); - if (clone_data (src_fs, dst_fs, i_num, src_i, &dst_i, 0, 0)) { - fprintf (stderr, "Cloning data for inode %d failed\n", (int) i_num); - return -1; + EXT2_MOAN_FAIL (ret, ext2fs_write_inode (dst_fs, i_num, &dst_i)); + + if (ret) + return -1; + + + } else { + /*Block list*/ + if (clone_blocks (src_fs, dst_fs, i_num, src_i, &dst_i)) { + fprintf (stderr, "Cloning blocks for inode %d failed\n", (int) i_num); + return -1; + } } } if (ret) return -1; + if (dst_i.i_mode & LINUX_S_IFDIR) ext2fs_inode_alloc_stats2 (dst_fs, i_num, +1, +1); else diff --git a/src/prototypes.h b/src/prototypes.h index 3ac93b7..f4e88c1 100644 --- a/src/prototypes.h +++ b/src/prototypes.h @@ -1,27 +1,30 @@ /* clone_data.c */ -int clone_data(ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i, struct ext2_inode *dst_i, uint64_t offset, uint64_t len); +int clone_data (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i, struct ext2_inode *dst_i, uint64_t offset, uint64_t len); /* clone_ea.c */ -int clone_ea(ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i, struct ext2_inode *dst_i); +int clone_ea (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i, struct ext2_inode *dst_i); /* clone_extents.c */ -int clone_extents(ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i, struct ext2_inode *dst_i); +int allocate_extent (ext2_filsys fs, ext2_ino_t i_num, ext2_extent_handle_t eh, blk64_t l_start, blk64_t len, __u32 flags); +int clone_extents (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i, struct ext2_inode *dst_i); /* clone_inode.c */ -int clone_inode(ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i); +int clone_inode (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i); /* ea_map.c */ -int ea_map_lookup(blk64_t src_blk, blk64_t *dst_blk, blk64_t *len); -int ea_map_set(blk64_t src_blk, blk64_t dst_blk, blk64_t len); +int ea_map_lookup (blk64_t src_blk, blk64_t *dst_blk, blk64_t *len); +int ea_map_set (blk64_t src_blk, blk64_t dst_blk, blk64_t len); /* ext_clone.c */ -char buf[(16*1024*1024)]; -int main(int argc, char *argv[]); +char buf[ (16 * 1024 * 1024)]; +int main (int argc, char *argv[]); /* stats.c */ uint64_t stats_inodes; uint64_t stats_ea_blocks; uint64_t stats_bytes; struct timeval start_time; struct timeval last_time; -void stats(int force); +void stats (int force); /* clone_fs.c */ -int clone_fs(ext2_filsys src_fs, ext2_filsys dst_fs); +int clone_fs (ext2_filsys src_fs, ext2_filsys dst_fs); /* zap_fs.c */ -int zap_fs(ext2_filsys fs); +int zap_fs (ext2_filsys fs); /* zap_inode.c */ -int zap_inode(ext2_filsys fs, ext2_ino_t i_num, struct ext2_inode *i); +int zap_inode (ext2_filsys fs, ext2_ino_t i_num, struct ext2_inode *i); +/* clone_blocks.c */ +int clone_blocks (ext2_filsys src_fs, ext2_filsys dst_fs, ext2_ino_t i_num, struct ext2_inode *src_i, struct ext2_inode *dst_i); diff --git a/src/zap_inode.c b/src/zap_inode.c index f40a16b..f31af19 100644 --- a/src/zap_inode.c +++ b/src/zap_inode.c @@ -1,8 +1,8 @@ #include "project.h" -static int clear_blocks (ext2_filsys fs, blk_t *b_num, +static int clear_blocks (ext2_filsys fs, blk64_t *b_num, e2_blkcnt_t blockcnt, - blk_t ref_block, + blk64_t ref_block, int ref_offset, void *priv_data) { @@ -21,7 +21,7 @@ int zap_inode (ext2_filsys fs, ext2_ino_t i_num, struct ext2_inode *i) printf ("clearing already used inode %d\n", (int) i_num); - EXT2_MOAN_FAIL (ret, ext2fs_block_iterate2 (fs, i_num, BLOCK_FLAG_DEPTH_TRAVERSE, 0, clear_blocks, NULL)); + EXT2_MOAN_FAIL (ret, ext2fs_block_iterate3 (fs, i_num, BLOCK_FLAG_DEPTH_TRAVERSE, 0, clear_blocks, NULL)); if (ret) return -1; -- cgit v1.2.3