forked from tytso/e2fsprogs-inline-patch-queue
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libext2fs-add-a-unit-test-for-inline-data
310 lines (305 loc) · 8.25 KB
/
libext2fs-add-a-unit-test-for-inline-data
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
libext2fs: add a unit test for inline data
From: Zheng Liu <[email protected]>
In this unit test, we will test the interface of inline data and make
sure it is fine.
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Zheng Liu <[email protected]>
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 4d011c9..3419778 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -391,6 +391,11 @@ tst_inline: $(srcdir)/inline.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
$(Q) $(CC) -o tst_inline $(srcdir)/inline.c $(ALL_CFLAGS) -DDEBUG \
$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+tst_inline_data: inline_data.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+ $(E) " LD $@"
+ $(Q) $(CC) -o tst_inline_data $(srcdir)/inline_data.c $(ALL_CFLAGS) \
+ -DDEBUG $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+
tst_csum: csum.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR) $(STATIC_LIBE2P) \
$(top_srcdir)/lib/e2p/e2p.h
$(E) " LD $@"
@@ -408,7 +413,7 @@ mkjournal: mkjournal.c $(STATIC_LIBEXT2FS) $(DEPLIBCOM_ERR)
check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount \
tst_super_size tst_types tst_inode_size tst_csum tst_crc32c tst_bitmaps \
- tst_inline
+ tst_inline tst_inline_data
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_bitops
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_badblocks
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_iscan
@@ -418,6 +423,7 @@ check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount \
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_inode_size
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_csum
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_inline
+ LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_inline_data
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_crc32c
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) \
./tst_bitmaps -f $(srcdir)/tst_bitmaps_cmds > tst_bitmaps_out
diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index 4a35209..199cdde 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -467,3 +467,263 @@ errcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino,
data.ea_data = buf + EXT4_MIN_INLINE_DATA_SIZE;
return ext2fs_inline_data_ea_set(&data);
}
+
+#ifdef DEBUG
+#include "e2p/e2p.h"
+
+/*
+ * The length of buffer is set to 64 because in inode's i_block member it only
+ * can save 60 bytes. Thus this value can let the data being saved in extra
+ * space.
+ */
+#define BUFF_SIZE (64)
+
+static errcode_t file_test(ext2_filsys fs)
+{
+ struct ext2_inode inode;
+ ext2_ino_t newfile;
+ errcode_t retval;
+ size_t size;
+ char *buf = 0, *cmpbuf = 0;
+ int i;
+
+ /* create a new file */
+ retval = ext2fs_new_inode(fs, 2, 010755, 0, &newfile);
+ if (retval) {
+ com_err("file_test", retval, "while allocaing a new inode");
+ return 1;
+ }
+
+ memset(&inode, 0, sizeof(inode));
+ inode.i_flags |= EXT4_INLINE_DATA_FL;
+ inode.i_size = EXT4_MIN_INLINE_DATA_SIZE;
+ inode.i_mode = LINUX_S_IFREG;
+ retval = ext2fs_write_new_inode(fs, newfile, &inode);
+ if (retval) {
+ com_err("file_test", retval, "while writting a new inode");
+ return 1;
+ }
+
+ retval = ext2fs_inline_data_init(fs, newfile);
+ if (retval) {
+ com_err("file_test", retval, "while init 'system.data'");
+ return 1;
+ }
+
+ retval = ext2fs_inline_data_size(fs, newfile, &size);
+ if (retval) {
+ com_err("file_test", retval, "while getting size");
+ return 1;
+ }
+
+ if (size != EXT4_MIN_INLINE_DATA_SIZE) {
+ fprintf(stderr,
+ "tst_inline_data: size of inline data is wrong\n");
+ return 1;
+ }
+
+ ext2fs_get_mem(BUFF_SIZE, &buf);
+ memset(buf, 'a', BUFF_SIZE);
+ retval = ext2fs_inline_data_set(fs, newfile, 0, buf, BUFF_SIZE);
+ if (retval) {
+ com_err("file_test", retval,
+ "while setting inline data %s", buf);
+ goto err;
+ }
+
+ ext2fs_get_mem(BUFF_SIZE, &cmpbuf);
+ retval = ext2fs_inline_data_get(fs, newfile, 0, cmpbuf, &size);
+ if (retval) {
+ com_err("file_test", retval, "while getting inline data");
+ goto err;
+ }
+
+ if (size != BUFF_SIZE) {
+ fprintf(stderr,
+ "tst_inline_data: size %lu != buflen %lu\n",
+ size, BUFF_SIZE);
+ retval = 1;
+ goto err;
+ }
+
+ if (memcmp(buf, cmpbuf, BUFF_SIZE)) {
+ fprintf(stderr, "tst_inline_data: buf != cmpbuf\n");
+ retval = 1;
+ goto err;
+ }
+
+ retval = ext2fs_punch(fs, newfile, 0, 0, 0, ~0ULL);
+ if (retval) {
+ com_err("file_test", retval, "while truncating inode");
+ goto err;
+ }
+
+ /* reload inode and check isize */
+ ext2fs_read_inode(fs, newfile, &inode);
+ if (inode.i_size != 0) {
+ fprintf(stderr, "tst_inline_data: i_size should be 0\n");
+ retval = 1;
+ }
+
+err:
+ if (cmpbuf)
+ ext2fs_free_mem(&cmpbuf);
+ if (buf)
+ ext2fs_free_mem(&buf);
+ return retval;
+}
+
+static errcode_t dir_test(ext2_filsys fs)
+{
+ const char *dot_name = ".";
+ const char *stub_name = "stub";
+ const char *parent_name = "test";
+ ext2_ino_t parent, dir, tmp;
+ errcode_t retval;
+ char dirname[PATH_MAX];
+ int i;
+
+ retval = ext2fs_mkdir(fs, 11, 11, stub_name);
+ if (retval) {
+ com_err("dir_test", retval, "while creating %s dir", stub_name);
+ return retval;
+ }
+
+ retval = ext2fs_mkdir(fs, 11, 0, parent_name);
+ if (retval) {
+ com_err("dir_test", retval,
+ "while creating %s dir", parent_name);
+ return retval;
+ }
+
+ retval = ext2fs_lookup(fs, 11, parent_name, strlen(parent_name),
+ 0, &parent);
+ if (retval) {
+ com_err("dir_test", retval,
+ "while looking up %s dir", parent_name);
+ return retval;
+ }
+
+ retval = ext2fs_lookup(fs, parent, dot_name, strlen(dot_name),
+ 0, &tmp);
+ if (retval) {
+ com_err("dir_test", retval,
+ "while looking up %s dir", parent_name);
+ return retval;
+ }
+
+ if (parent != tmp) {
+ fprintf(stderr, "tst_inline_data: parent (%lu) != tmp (%lu)\n",
+ parent, tmp);
+ return 1;
+ }
+
+ for (i = 0, dir = 13; i < 4; i++, dir++) {
+ tmp = 0;
+ snprintf(dirname, PATH_MAX, "%d", i);
+ retval = ext2fs_mkdir(fs, parent, 0, dirname);
+ if (retval) {
+ com_err("dir_test", retval,
+ "while creating %s dir", dirname);
+ return retval;
+ }
+
+ retval = ext2fs_lookup(fs, parent, dirname, strlen(dirname),
+ 0, &tmp);
+ if (retval) {
+ com_err("dir_test", retval,
+ "while looking up %s dir", parent_name);
+ return retval;
+ }
+
+ if (dir != tmp) {
+ fprintf(stderr, "tst_inline_data: dir (%lu) != tmp (%lu)\n",
+ dir, tmp);
+ return 1;
+ }
+ }
+
+ snprintf(dirname, PATH_MAX, "%d", i);
+ retval = ext2fs_mkdir(fs, parent, 0, dirname);
+ if (retval && retval != EXT2_ET_DIR_NO_SPACE) {
+ com_err("dir_test", retval, "while creating %s dir", dirname);
+ return retval;
+ }
+
+ retval = ext2fs_expand_dir(fs, parent);
+ if (retval) {
+ com_err("dir_test", retval, "while expanding %s dir", parent_name);
+ return retval;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ ext2_filsys fs;
+ struct ext2_super_block param;
+ errcode_t retval;
+ int i;
+
+ /* setup */
+ initialize_ext2_error_table();
+
+ memset(¶m, 0, sizeof(param));
+ ext2fs_blocks_count_set(¶m, 32768);
+ param.s_inodes_count = 100;
+
+ param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_INLINE_DATA;
+ param.s_rev_level = EXT2_DYNAMIC_REV;
+ param.s_inode_size = 256;
+
+ retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m,
+ test_io_manager, &fs);
+ if (retval) {
+ com_err("setup", retval,
+ "while initializing filesystem");
+ exit(1);
+ }
+
+ retval = ext2fs_allocate_tables(fs);
+ if (retval) {
+ com_err("setup", retval,
+ "while allocating tables for test filesysmte");
+ exit(1);
+ }
+
+ /* initialize inode cache */
+ if (!fs->icache) {
+ struct ext2_inode inode;
+ ext2_ino_t first_ino = EXT2_FIRST_INO(fs->super);
+ int i;
+
+ /* we just want to init inode cache. So ignore error */
+ ext2fs_create_inode_cache(fs, 16);
+ if (!fs->icache) {
+ fprintf(stderr,
+ "tst_inline_data: init inode cache failed\n");
+ exit(1);
+ }
+
+ /* setup inode cache */
+ for (i = 0; i < fs->icache->cache_size; i++)
+ fs->icache->cache[i].ino = first_ino++;
+ }
+
+ /* test */
+ if (file_test(fs)) {
+ fprintf(stderr, "tst_inline_data(FILE): FAILED\n");
+ return 1;
+ }
+ printf("tst_inline_data(FILE): OK\n");
+
+ if (dir_test(fs)) {
+ fprintf(stderr, "tst_inline_data(DIR): FAILED\n");
+ return 1;
+ }
+ printf("tst_inline_data(DIR): OK\n");
+
+ return 0;
+}
+#endif