#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; }