1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#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;
}
|