aboutsummaryrefslogtreecommitdiffstats
path: root/src/clone_ea.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/clone_ea.c')
-rw-r--r--src/clone_ea.c70
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;
+}
+
+