diff options
author | fishsoupisgood <github@madingley.org> | 2018-05-12 17:10:22 +0100 |
---|---|---|
committer | fishsoupisgood <github@madingley.org> | 2018-05-12 17:10:22 +0100 |
commit | b6afefb5d12dbed4801272dae3048588dfc1cb9a (patch) | |
tree | 0dc99b5b05d54cd5496b26fa37e19cc79f0b4b5e /src/clone_ea.c | |
download | ext_clone-b6afefb5d12dbed4801272dae3048588dfc1cb9a.tar.gz ext_clone-b6afefb5d12dbed4801272dae3048588dfc1cb9a.tar.bz2 ext_clone-b6afefb5d12dbed4801272dae3048588dfc1cb9a.zip |
first working version
Diffstat (limited to 'src/clone_ea.c')
-rw-r--r-- | src/clone_ea.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/clone_ea.c b/src/clone_ea.c new file mode 100644 index 0000000..d8287b7 --- /dev/null +++ b/src/clone_ea.c @@ -0,0 +1,70 @@ +#include "project.h" + +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 ret; + blk64_t src_blk = src_i->i_file_acl; + blk64_t goal, dst_blk, len; + dgrp_t group; + + struct ext2_ext_attr_header *h; + + if (!src_blk) return 0; + + if (!ea_map_lookup (src_blk, &dst_blk, &len)) { + /* Easy case */ + + EXT2_MOAN_FAIL (ret, ext2fs_adjust_ea_refcount2 (dst_fs, dst_blk, buf, +1, NULL)); + + if (ret) return ret; + + dst_i->i_file_acl = dst_blk; + dst_i->i_blocks += len * (dst_fs->blocksize / 512); + return 0; + } + + EXT2_MOAN_FAIL (ret, io_channel_read_blk64 (src_fs->io, src_blk, 1, buf)); + + if (ret) return ret; + + h = (struct ext2_ext_attr_header *) buf; + len = h->h_blocks; + + if (len > 1) { + EXT2_MOAN_FAIL (ret, io_channel_read_blk64 (src_fs->io, src_blk + 1, len - 1, buf + src_fs->blocksize)); + + if (ret) return ret; + } + + h->h_refcount = 0; + + group = ext2fs_group_of_ino (dst_fs, i_num); + goal = ext2fs_group_first_block2 (dst_fs, group); + + EXT2_MOAN_FAIL (ret, ext2fs_alloc_range (dst_fs, 0, goal, len, &dst_blk)); + + if (ret) return ret; + + //printf ("EA block %d mapped to block %d len %d\n", (int)src_blk, (int) dst_blk, (int)len); + stats_ea_blocks++; + + if (ea_map_set (src_blk, dst_blk, len)) + return -1; + + + EXT2_MOAN_FAIL (ret, io_channel_write_blk64 (dst_fs->io, dst_blk, len, buf)); + + 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->i_blocks += len * (dst_fs->blocksize / 512); + EXT2_MOAN_FAIL (ret, ext2fs_adjust_ea_refcount2 (dst_fs, dst_blk, buf, +1, NULL)); + + if (ret) return ret; + + + return 0; +} + + |