#include "project.h" 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 ret; __u64 file_len; unsigned got, written, fetch; ext2_file_t src_f = NULL, dst_f = NULL; do { EXT2_MOAN_FAIL (ret, ext2fs_file_open2 (src_fs, i_num, src_i, 0, &src_f)); if (ret) return -1; EXT2_MOAN_FAIL (ret, ext2fs_file_open2 (dst_fs, i_num, dst_i, EXT2_FILE_WRITE, &dst_f)); if (ret) return -1; if (offset) { EXT2_MOAN_FAIL (ret, ext2fs_file_lseek (src_f, offset, SEEK_SET, NULL)); if (ret) return -1; EXT2_MOAN_FAIL (ret, ext2fs_file_lseek (dst_f, offset, SEEK_SET, NULL)); if (ret) return -1; } EXT2_MOAN_FAIL (ret, ext2fs_file_get_lsize (src_f, &file_len)); if (ret) break; file_len -= offset; if (len > file_len) len = file_len; while (len) { fetch = len > BUF_SZ ? BUF_SZ : len; EXT2_MOAN_FAIL (ret, ext2fs_file_read (src_f, buf, fetch, &got)); if (ret) break; if (got) { EXT2_MOAN_FAIL (ret, ext2fs_file_write (dst_f, buf, got, &written)); if (ret) break; if (written != got) { fprintf (stderr, "Not all bytes written in inode %d\n", (int) i_num); ret = 1; break; } } stats_bytes += written; len -= written; } } while (0); ext2fs_file_flush (dst_f); ext2fs_file_close (dst_f); ext2fs_file_close (src_f); return ret; }