aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfishsoupisgood <github@madingley.org>2018-05-14 02:40:06 +0100
committerfishsoupisgood <github@madingley.org>2018-05-14 02:40:06 +0100
commitec9eb54d2f36f9c98607b5fc8745f978cfebd63e (patch)
treee8570d2f581d844ce24d02eb9d89bdd156d3cd2c
parentb8e2bb419265d10c11fc5840aabce81379bb242d (diff)
downloadext_clone-ec9eb54d2f36f9c98607b5fc8745f978cfebd63e.tar.gz
ext_clone-ec9eb54d2f36f9c98607b5fc8745f978cfebd63e.tar.bz2
ext_clone-ec9eb54d2f36f9c98607b5fc8745f978cfebd63e.zip
support non extents and fast symlinks
-rw-r--r--src/Makefile.am28
-rw-r--r--src/clone_data.c3
-rw-r--r--src/clone_ea.c2
-rw-r--r--src/clone_extents.c22
-rw-r--r--src/clone_fs.c15
-rw-r--r--src/clone_inode.c23
-rw-r--r--src/prototypes.h27
-rw-r--r--src/zap_inode.c6
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;