4 * This file is part of BeRTOS.
6 * Bertos is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * As a special exception, you may use this file as part of a free software
21 * library without restriction. Specifically, if other files instantiate
22 * templates or use macros or inline functions from this file, or you compile
23 * this file and link it with other files to produce an executable, this
24 * file does not by itself cause the resulting executable to be covered by
25 * the GNU General Public License. This exception does not however
26 * invalidate any other reasons why the executable file might be covered by
27 * the GNU General Public License.
29 * Copyright 2007, 2008 Develer S.r.l. (http://www.develer.com/)
34 * \author Francesco Sacchi <batt@develer.com>
37 #include <fs/battfs.h>
38 #include <io/kblock_file.h>
40 #include <cfg/debug.h>
47 #define FILE_SIZE 32768
50 #define DATA_SIZE (PAGE_SIZE - BATTFS_HEADER_LEN)
51 #define PAGE_COUNT (FILE_SIZE / PAGE_SIZE)
55 const char test_filename[]="battfs_disk.bin";
57 static uint8_t page_buffer[PAGE_SIZE];
58 static pgcnt_t page_array[PAGE_COUNT];
60 static void testCheck(BattFsSuper *disk, pgcnt_t *reference)
62 ASSERT(battfs_fsck(disk));
64 for (unsigned i = 0; i < disk->dev->blk_cnt; i++)
66 if (disk->page_array[i] != reference[i])
68 kprintf("Error at addr %d: page_array read", i);
69 for (pgcnt_t i = 0; i < disk->dev->blk_cnt; i++)
73 kprintf("%04d ", disk->page_array[i]);
77 for (pgcnt_t i = 0; i < disk->dev->blk_cnt; i++)
81 kprintf("%04d ", reference[i]);
89 ASSERT(battfs_fsck(disk));
90 ASSERT(battfs_umount(disk));
93 static void diskNew(BattFsSuper *disk)
95 pgcnt_t ref[PAGE_COUNT];
97 TRACEMSG("1: disk new\n");
99 FILE *fpt = fopen(test_filename, "w+");
101 for (int i = 0; i < FILE_SIZE; i++)
104 for (int i = 0; i < PAGE_COUNT; i++)
108 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
109 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
111 testCheck(disk, ref);
112 TRACEMSG("1: passed\n");
115 static void disk1File(BattFsSuper *disk)
117 pgcnt_t ref[PAGE_COUNT];
118 TRACEMSG("2: disk full with 1 contiguos file\n");
120 FILE *fp = fopen(test_filename, "w+");
121 for (int i = 0; i < FILE_SIZE; i++)
125 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, PAGE_COUNT);
127 for (int i = 0; i < PAGE_COUNT; i++)
129 battfs_writeTestBlock(&f.b, i, 0, 0, DATA_SIZE, i);
133 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
135 testCheck(disk, ref);
136 TRACEMSG("2: passed\n");
140 static void diskHalfFile(BattFsSuper *disk)
142 pgcnt_t ref[PAGE_COUNT];
143 TRACEMSG("3: disk half full with 1 contiguos file, rest unformatted\n");
146 FILE *fp = fopen(test_filename, "w+");
147 for (int i = 0; i < FILE_SIZE; i++)
151 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, PAGE_COUNT);
153 for (int i = 0; i < PAGE_COUNT / 2; i++)
155 battfs_writeTestBlock(&f.b, i, 0, 0, DATA_SIZE, i);
158 fseek(fp, FILE_SIZE / 2, SEEK_SET);
159 for (int i = FILE_SIZE / 2; i < FILE_SIZE; i++)
162 for (int i = PAGE_COUNT / 2; i < PAGE_COUNT; i++)
167 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
169 testCheck(disk, ref);
170 TRACEMSG("3: passed\n");
174 static void oldSeq1(BattFsSuper *disk)
177 TRACEMSG("6: 1 file with 1 old seq num, 1 free block\n");
179 FILE *fp = fopen(test_filename, "w+");
180 for (int i = 0; i < PAGE_SIZE * 4; i++)
183 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4);
185 // page, inode, seq, fill, pgoff
186 battfs_writeTestBlock(&f.b, 0, 0, 0, DATA_SIZE, 0);
187 battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 1);
188 battfs_writeTestBlock(&f.b, 2, 0, 1, DATA_SIZE, 1);
189 battfs_eraseBlock(&f.b, 3);
196 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
198 testCheck(disk, ref);
199 TRACEMSG("6: passed\n");
202 static void oldSeq2(BattFsSuper *disk)
205 TRACEMSG("7: 1 file with 1 old seq num, 1 free block\n");
207 FILE *fp = fopen(test_filename, "w+");
208 for (int i = 0; i < PAGE_SIZE * 4; i++)
211 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4);
213 // page, inode, seq, fill, pgoff
214 battfs_writeTestBlock(&f.b, 0, 0, 0, DATA_SIZE, 0);
215 battfs_writeTestBlock(&f.b, 1, 0, 1, DATA_SIZE, 1);
216 battfs_writeTestBlock(&f.b, 2, 0, 0, DATA_SIZE, 1);
217 battfs_eraseBlock(&f.b, 3);
224 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
225 testCheck(disk, ref);
226 TRACEMSG("7: passed\n");
229 static void oldSeq3(BattFsSuper *disk)
232 TRACEMSG("8: 1 file with 1 old seq num, 1 free block\n");
235 FILE *fp = fopen(test_filename, "w+");
236 for (int i = 0; i < PAGE_SIZE * 4; i++)
239 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4);
241 // page, inode, seq, fill, pgoff
242 battfs_eraseBlock(&f.b, 0);
243 battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 0);
244 battfs_writeTestBlock(&f.b, 2, 0, 1, DATA_SIZE, 1);
245 battfs_writeTestBlock(&f.b, 3, 0, 0, DATA_SIZE, 1);
252 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
253 testCheck(disk, ref);
254 TRACEMSG("8: passed\n");
257 static void oldSeq2File(BattFsSuper *disk)
260 TRACEMSG("9: 2 file with old seq num, 2 free block\n");
263 FILE *fp = fopen(test_filename, "w+");
264 for (int i = 0; i < PAGE_SIZE * 8; i++)
267 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
269 // page, inode, seq, fill, pgoff
270 battfs_eraseBlock(&f.b, 0);
271 battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 0);
272 battfs_writeTestBlock(&f.b, 2, 0, 3, DATA_SIZE, 1);
273 battfs_writeTestBlock(&f.b, 3, 0, 0, DATA_SIZE, 1);
274 battfs_eraseBlock(&f.b, 4);
275 battfs_writeTestBlock(&f.b, 5, 4, 0, DATA_SIZE, 0);
276 battfs_writeTestBlock(&f.b, 6, 4, 1, DATA_SIZE, 1);
277 battfs_writeTestBlock(&f.b, 7, 4, 0, DATA_SIZE, 1);
289 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
290 testCheck(disk, ref);
291 TRACEMSG("9: passed\n");
294 static void openFile(BattFsSuper *disk)
298 TRACEMSG("10: open file test, inode 0 and inode 4\n");
300 FILE *fp = fopen(test_filename, "w+");
301 for (int i = 0; i < PAGE_SIZE * 8; i++)
304 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
307 int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
310 inode_t INEXISTENT_INODE = 123;
311 unsigned int MODE = 0;
313 // page, inode, seq, fill, pgoff
314 battfs_eraseBlock(&f.b, 0);
315 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
316 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
317 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
318 battfs_eraseBlock(&f.b, 4);
319 battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0);
320 battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1);
321 battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1);
323 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
324 ASSERT(battfs_fsck(disk));
325 ASSERT(!battfs_fileExists(disk, INEXISTENT_INODE));
327 ASSERT(battfs_fileExists(disk, INODE));
328 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
329 ASSERT(fd1.fd.size == PAGE_FILL * 2);
330 ASSERT(fd1.fd.seek_pos == 0);
331 ASSERT(fd1.mode == MODE);
332 ASSERT(fd1.inode == INODE);
333 ASSERT(fd1.start == &disk->page_array[0]);
334 ASSERT(fd1.disk == disk);
335 ASSERT(LIST_HEAD(&disk->file_opened_list) == &fd1.link);
337 ASSERT(kfile_reopen(&fd1.fd) == &fd1.fd);
338 ASSERT(fd1.fd.size == PAGE_FILL * 2);
339 ASSERT(fd1.fd.seek_pos == 0);
340 ASSERT(fd1.mode == MODE);
341 ASSERT(fd1.inode == INODE);
342 ASSERT(fd1.start == &disk->page_array[0]);
343 ASSERT(fd1.disk == disk);
344 ASSERT(LIST_HEAD(&disk->file_opened_list) == &fd1.link);
346 ASSERT(battfs_fileExists(disk, INODE2));
347 ASSERT(battfs_fileopen(disk, &fd2, INODE2, MODE));
348 ASSERT(fd2.fd.size == PAGE_FILL * 2);
349 ASSERT(fd2.fd.seek_pos == 0);
350 ASSERT(fd2.mode == MODE);
351 ASSERT(fd2.inode == INODE2);
352 ASSERT(fd2.start == &disk->page_array[2]);
353 ASSERT(fd2.disk == disk);
354 ASSERT(LIST_HEAD(&disk->file_opened_list)->succ == &fd2.link);
356 ASSERT(kfile_close(&fd1.fd) == 0);
357 ASSERT(kfile_error(&fd1.fd) == 0);
358 ASSERT(kfile_close(&fd2.fd) == 0);
359 ASSERT(kfile_error(&fd2.fd) == 0);
360 ASSERT(LIST_EMPTY(&disk->file_opened_list));
361 ASSERT(battfs_fsck(disk));
362 ASSERT(battfs_umount(disk));
364 TRACEMSG("10: passed\n");
367 static void readFile(BattFsSuper *disk)
372 TRACEMSG("11: read file test\n");
374 FILE *fp = fopen(test_filename, "w+");
375 for (int i = 0; i < PAGE_SIZE * 8; i++)
378 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
381 unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
384 unsigned int MODE = 0;
386 battfs_eraseBlock(&f.b, 0);
387 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
388 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
389 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
390 battfs_eraseBlock(&f.b, 4);
391 battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0);
392 battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1);
393 battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1);
395 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
396 ASSERT(battfs_fsck(disk));
397 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
398 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
399 ASSERT(fd1.fd.seek_pos == sizeof(buf));
400 for (size_t i = 0; i < sizeof(buf); i++)
401 ASSERT(buf[i] == 0xff);
403 ASSERT(kfile_close(&fd1.fd) == 0);
404 ASSERT(kfile_error(&fd1.fd) == 0);
405 ASSERT(battfs_fsck(disk));
406 ASSERT(battfs_umount(disk));
408 TRACEMSG("11: passed\n");
411 static void readAcross(BattFsSuper *disk)
415 TRACEMSG("12: read file test across page boundary and seek test\n");
417 FILE *fp = fopen(test_filename, "w+");
418 for (int i = 0; i < PAGE_SIZE * 8; i++)
421 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
423 const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
425 unsigned int MODE = 0;
426 uint8_t buf[PAGE_FILL + BATTFS_HEADER_LEN / 2];
428 battfs_eraseBlock(&f.b, 0);
429 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
430 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
431 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
432 battfs_eraseBlock(&f.b, 4);
433 battfs_writeTestBlock(&f.b, 5, INODE, 0, PAGE_FILL, 2);
434 battfs_writeTestBlock(&f.b, 6, INODE, 1, PAGE_FILL, 3);
435 battfs_writeTestBlock(&f.b, 7, INODE, 0, PAGE_FILL, 3);
437 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
438 ASSERT(battfs_fsck(disk));
439 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
441 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
442 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf));
443 for (size_t i = 0; i < sizeof(buf); i++)
444 ASSERT(buf[i] == 0xff);
446 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
447 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 2);
448 for (size_t i = 0; i < sizeof(buf); i++)
449 ASSERT(buf[i] == 0xff);
451 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
452 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
453 for (size_t i = 0; i < sizeof(buf); i++)
454 ASSERT(buf[i] == 0xff);
456 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == PAGE_FILL * 4 - sizeof(buf) * 3);
457 ASSERT(fd1.fd.seek_pos == (kfile_off_t)fd1.fd.size);
458 for (size_t i = 0; i < PAGE_FILL * 4 - sizeof(buf) * 3; i++)
459 ASSERT(buf[i] == 0xff);
461 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
462 ASSERT(fd1.fd.seek_pos == 0);
464 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_END) == (kfile_off_t)fd1.fd.size);
465 ASSERT(fd1.fd.seek_pos = (kfile_off_t)fd1.fd.size);
467 ASSERT(kfile_close(&fd1.fd) == 0);
468 ASSERT(kfile_error(&fd1.fd) == 0);
469 ASSERT(battfs_fsck(disk));
470 ASSERT(battfs_umount(disk));
472 TRACEMSG("12: passed\n");
476 static void writeFile(BattFsSuper *disk)
479 uint8_t buf[PAGE_SIZE - BATTFS_HEADER_LEN];
481 TRACEMSG("13: write file test\n");
483 FILE *fp = fopen(test_filename, "w+");
484 for (int i = 0; i < PAGE_SIZE * 8; i++)
487 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
490 unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
493 unsigned int MODE = 0;
495 battfs_eraseBlock(&f.b, 0);
496 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
497 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
498 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
499 battfs_eraseBlock(&f.b, 4);
500 battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0);
501 battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1);
502 battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1);
504 for (size_t i = 0; i < sizeof(buf); i++)
507 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
508 ASSERT(battfs_fsck(disk));
509 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
510 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
511 ASSERT(fd1.fd.seek_pos == sizeof(buf));
512 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
513 ASSERT(fd1.fd.seek_pos == 0);
515 memset(buf, 0, sizeof(buf));
516 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
517 for (size_t i = 0; i < sizeof(buf); i++)
520 ASSERT(kfile_close(&fd1.fd) == 0);
521 ASSERT(kfile_error(&fd1.fd) == 0);
522 ASSERT(battfs_fsck(disk));
523 ASSERT(battfs_umount(disk));
525 TRACEMSG("13: passed\n");
528 static void writeAcross(BattFsSuper *disk)
532 TRACEMSG("14: write file test across page boundary and seek test\n");
534 FILE *fp = fopen(test_filename, "w+");
535 for (int i = 0; i < PAGE_SIZE * 8; i++)
538 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
540 const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
542 unsigned int MODE = 0;
543 uint8_t buf[PAGE_FILL + BATTFS_HEADER_LEN / 2];
545 battfs_eraseBlock(&f.b, 0);
546 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
547 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
548 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
549 battfs_eraseBlock(&f.b, 4);
550 battfs_writeTestBlock(&f.b, 5, INODE, 0, PAGE_FILL, 2);
551 battfs_writeTestBlock(&f.b, 6, INODE, 1, PAGE_FILL, 3);
552 battfs_writeTestBlock(&f.b, 7, INODE, 0, PAGE_FILL, 3);
554 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
555 ASSERT(battfs_fsck(disk));
556 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
559 for (size_t i = 0; i < sizeof(buf); i++)
561 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
562 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf));
564 for (size_t i = 0; i < sizeof(buf); i++)
566 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
567 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 2);
569 for (size_t i = 0; i < sizeof(buf); i++)
571 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
572 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
574 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
575 ASSERT(fd1.fd.seek_pos == 0);
578 memset(buf, 0, sizeof(buf));
579 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
580 for (size_t i = 0; i < sizeof(buf); i++)
581 ASSERT(buf[i] == val++);
583 memset(buf, 0, sizeof(buf));
584 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
585 for (size_t i = 0; i < sizeof(buf); i++)
586 ASSERT(buf[i] == val++);
588 memset(buf, 0, sizeof(buf));
589 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
590 for (size_t i = 0; i < sizeof(buf); i++)
591 ASSERT(buf[i] == val++);
593 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
595 ASSERT(kfile_close(&fd1.fd) == 0);
596 ASSERT(kfile_error(&fd1.fd) == 0);
597 ASSERT(battfs_fsck(disk));
598 ASSERT(battfs_umount(disk));
600 TRACEMSG("14: passed\n");
603 static void createFile(BattFsSuper *disk)
605 TRACEMSG("15: file creation on new disk\n");
607 FILE *fpt = fopen(test_filename, "w+");
608 for (int i = 0; i < FILE_SIZE; i++)
611 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
615 unsigned int MODE = BATTFS_CREATE;
617 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
618 ASSERT(battfs_fsck(disk));
619 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
620 for (int i = 0; i < FILE_SIZE / 2; i++)
621 ASSERT(kfile_putc(i, &fd1.fd) != EOF);
623 ASSERT(fd1.fd.seek_pos == FILE_SIZE / 2);
624 ASSERT(fd1.fd.size == FILE_SIZE / 2);
625 ASSERT(kfile_close(&fd1.fd) == 0);
626 ASSERT(kfile_error(&fd1.fd) == 0);
627 ASSERT(battfs_fsck(disk));
628 ASSERT(battfs_umount(disk));
630 fpt = fopen(test_filename, "r+");
631 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
633 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
634 ASSERT(battfs_fsck(disk));
635 ASSERT(battfs_fileopen(disk, &fd1, INODE, 0));
636 ASSERT(fd1.fd.size == FILE_SIZE / 2);
637 ASSERT(fd1.fd.seek_pos == 0);
639 uint8_t buf[FILE_SIZE / 2];
640 memset(buf, 0, sizeof(buf));
641 ASSERT(kfile_read(&fd1.fd, buf, FILE_SIZE / 2) == FILE_SIZE / 2);
643 for (int i = 0; i < FILE_SIZE / 2; i++)
644 ASSERT(buf[i] == (i & 0xff));
646 ASSERT(fd1.fd.seek_pos == FILE_SIZE / 2);
647 ASSERT(kfile_close(&fd1.fd) == 0);
648 ASSERT(kfile_error(&fd1.fd) == 0);
649 ASSERT(battfs_fsck(disk));
650 ASSERT(battfs_umount(disk));
653 TRACEMSG("15: passed\n");
656 static void multipleWrite(BattFsSuper *disk)
658 TRACEMSG("16: multiple write on file\n");
660 FILE *fpt = fopen(test_filename, "w+");
661 for (int i = 0; i < FILE_SIZE; i++)
664 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
669 unsigned int MODE = BATTFS_CREATE;
672 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
673 ASSERT(battfs_fsck(disk));
674 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
677 for (j = 1; j < 1013; j++)
679 for (unsigned i = 0; i < sizeof(buf); i++)
682 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
683 ASSERT(fd1.fd.seek_pos == sizeof(buf));
684 ASSERT(fd1.fd.size == sizeof(buf));
685 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
686 memset(buf, 0, sizeof(buf));
687 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
688 ASSERT(fd1.fd.seek_pos == sizeof(buf));
689 for (unsigned i = 0; i < sizeof(buf); i++)
690 ASSERT(buf[i] == ((j+i) & 0xff));
691 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
692 ASSERT(disk->free_bytes == disk->disk_size - sizeof(buf));
694 ASSERT(kfile_close(&fd1.fd) == 0);
695 ASSERT(kfile_error(&fd1.fd) == 0);
696 ASSERT(battfs_fsck(disk));
697 ASSERT(battfs_umount(disk));
699 fpt = fopen(test_filename, "r+");
700 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
702 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
703 ASSERT(battfs_fsck(disk));
704 ASSERT(disk->free_bytes == disk->disk_size - sizeof(buf));
705 ASSERT(battfs_fileopen(disk, &fd1, INODE, 0));
706 ASSERT(fd1.fd.size == sizeof(buf));
707 memset(buf, 0, sizeof(buf));
708 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
709 for (unsigned i = 0; i < sizeof(buf); i++)
710 ASSERT(buf[i] == ((j-1+i) & 0xff));
711 ASSERT(kfile_close(&fd1.fd) == 0);
712 ASSERT(kfile_error(&fd1.fd) == 0);
713 ASSERT(battfs_fsck(disk));
714 ASSERT(battfs_umount(disk));
717 TRACEMSG("16: passed\n");
720 static void increaseFile(BattFsSuper *disk)
722 TRACEMSG("17: increasing dimension of a file with multiple open files.\n");
724 FILE *fpt = fopen(test_filename, "w+");
725 for (int i = 0; i < FILE_SIZE / 10; i++)
729 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT / 10);
733 inode_t INODE1 = 1, INODE2 = 2;
734 unsigned int MODE = BATTFS_CREATE;
737 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
738 ASSERT(battfs_fsck(disk));
739 ASSERT(battfs_fileopen(disk, &fd1, INODE1, MODE));
740 ASSERT(battfs_fileopen(disk, &fd2, INODE2, MODE));
741 for (unsigned i = 0; i < sizeof(buf); i++)
742 ASSERT(kfile_putc(i, &fd2.fd) != EOF);
743 ASSERT(kfile_seek(&fd2.fd, 0, KSM_SEEK_SET) == 0);
744 memset(buf, 0, sizeof(buf));
745 ASSERT(kfile_read(&fd2.fd, buf, sizeof(buf)) == sizeof(buf));
747 for (unsigned i = 0; i < sizeof(buf); i++)
748 ASSERT(buf[i] == (i & 0xff));
749 ASSERT(kfile_seek(&fd2.fd, 0, KSM_SEEK_SET) == 0);
751 for (unsigned i = 0; i < sizeof(buf); i++)
752 ASSERT(kfile_putc(i, &fd1.fd) != EOF);
754 memset(buf, 0, sizeof(buf));
755 ASSERT(kfile_read(&fd2.fd, buf, sizeof(buf)) == sizeof(buf));
757 for (unsigned i = 0; i < sizeof(buf); i++)
758 ASSERT(buf[i] == (i & 0xff));
760 ASSERT(kfile_close(&fd1.fd) == 0);
761 ASSERT(kfile_error(&fd1.fd) == 0);
762 ASSERT(kfile_close(&fd2.fd) == 0);
763 ASSERT(kfile_error(&fd2.fd) == 0);
764 ASSERT(battfs_fsck(disk));
765 ASSERT(battfs_umount(disk));
767 TRACEMSG("17: passed\n");
770 static void readEOF(BattFsSuper *disk)
775 TRACEMSG("18: reading over EOF test\n");
777 FILE *fp = fopen(test_filename, "w+");
778 for (int i = 0; i < PAGE_SIZE * 8; i++)
781 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
784 unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
787 unsigned int MODE = 0;
789 battfs_eraseBlock(&f.b, 0);
790 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
791 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
792 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
793 battfs_eraseBlock(&f.b, 4);
794 battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0);
795 battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1);
796 battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1);
798 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
799 ASSERT(battfs_fsck(disk));
800 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
801 ASSERT(kfile_seek(&fd1.fd, fd1.fd.size + 10, SEEK_SET) == fd1.fd.size + 10);
802 ASSERT(fd1.fd.seek_pos == fd1.fd.size + 10);
803 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == 0);
805 ASSERT(kfile_close(&fd1.fd) == 0);
806 ASSERT(kfile_error(&fd1.fd) == 0);
807 ASSERT(battfs_fsck(disk));
808 ASSERT(battfs_umount(disk));
810 TRACEMSG("18: passed\n");
813 static void writeEOF(BattFsSuper *disk)
815 TRACEMSG("19: writing over EOF test\n");
817 FILE *fpt = fopen(test_filename, "w+");
818 for (int i = 0; i < FILE_SIZE / 5; i++)
821 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT / 5);
825 unsigned int MODE = BATTFS_CREATE;
826 uint8_t buf[FILE_SIZE / 13];
828 for (int i = 0; i < 2; i++)
831 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
832 ASSERT(battfs_fsck(disk));
833 disk_size_t prev_free = disk->free_bytes;
834 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
835 ASSERT(fd1.fd.size == 0);
837 ASSERT(kfile_seek(&fd1.fd, 2, KSM_SEEK_END) == 2);
838 ASSERT(kfile_write(&fd1.fd, buf, 2));
839 ASSERT(fd1.fd.seek_pos == 4);
840 ASSERT(fd1.fd.size == 4);
841 ASSERT(disk->free_bytes == prev_free - 4);
842 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
844 ASSERT(kfile_read(&fd1.fd, buf, 2) == 2);
845 for (int i = 0; i < 2; i++)
849 ASSERT(kfile_read(&fd1.fd, buf, 2) == 2);
850 for (int i = 0; i < 2; i++)
851 ASSERT(buf[i] == (i & 0xff));
853 ASSERT(kfile_seek(&fd1.fd, sizeof(buf), KSM_SEEK_END) == sizeof(buf) + 4);
854 for (unsigned i = 0; i < sizeof(buf); i++)
856 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)));
857 ASSERT(fd1.fd.seek_pos == sizeof(buf) * 2 + 4);
858 ASSERT(fd1.fd.size == sizeof(buf) * 2 + 4);
859 ASSERT(disk->free_bytes == prev_free - sizeof(buf) * 2 - 4);
861 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
864 ASSERT(kfile_read(&fd1.fd, buf, 2) == 2);
865 ASSERT(fd1.fd.seek_pos == 2);
866 for (int i = 0; i < 2; i++)
870 ASSERT(kfile_read(&fd1.fd, buf, 2) == 2);
871 ASSERT(fd1.fd.seek_pos == 4);
872 for (int i = 0; i < 2; i++)
873 ASSERT(buf[i] == (i & 0xff));
876 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
877 ASSERT(fd1.fd.seek_pos == sizeof(buf) + 4);
878 for (unsigned i = 0; i < sizeof(buf); i++)
881 memset(buf, 0, sizeof(buf));
882 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
883 for (unsigned i = 0; i < sizeof(buf); i++)
884 ASSERT(buf[i] == (i & 0xff));
886 ASSERT(kfile_close(&fd1.fd) == 0);
887 ASSERT(kfile_error(&fd1.fd) == 0);
888 ASSERT(battfs_fsck(disk));
889 ASSERT(battfs_umount(disk));
891 TRACEMSG("19: passed\n");
895 static void endOfSpace(BattFsSuper *disk)
897 TRACEMSG("20: what happens when disk space is over?\n");
899 uint8_t buf[(PAGE_SIZE - BATTFS_HEADER_LEN) * 5];
901 FILE *fp = fopen(test_filename, "w+");
902 for (int i = 0; i < PAGE_SIZE * 4; i++)
905 kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4);
907 unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
909 unsigned int MODE = BATTFS_CREATE;
911 battfs_eraseBlock(&f.b, 0);
912 battfs_eraseBlock(&f.b, 1);
913 battfs_eraseBlock(&f.b, 2);
914 battfs_eraseBlock(&f.b, 3);
916 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
917 ASSERT(battfs_fsck(disk));
918 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
919 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == PAGE_FILL * 4);
920 ASSERT(fd1.fd.size == (kfile_off_t)(PAGE_FILL * 4));
921 ASSERT(fd1.fd.seek_pos == (kfile_off_t)(PAGE_FILL * 4));
922 ASSERT(disk->free_bytes == 0);
924 ASSERT(kfile_close(&fd1.fd) == 0);
925 ASSERT(kfile_error(&fd1.fd) == BATTFS_DISK_SPACEOVER_ERR);
926 ASSERT(battfs_fsck(disk));
927 ASSERT(battfs_umount(disk));
929 TRACEMSG("20: passed\n");
933 static void multipleFilesRW(BattFsSuper *disk)
935 TRACEMSG("21: multiple files read/write test\n");
937 FILE *fpt = fopen(test_filename, "w+");
938 for (int i = 0; i < FILE_SIZE; i++)
941 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
945 unsigned int MODE = BATTFS_CREATE;
946 uint32_t buf[FILE_SIZE / (4 * N_FILES * sizeof(uint32_t))];
948 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
949 ASSERT(battfs_fsck(disk));
950 for (inode_t i = 0; i < N_FILES; i++)
951 ASSERT(battfs_fileopen(disk, &fd[i], i, MODE));
953 for (int i = N_FILES - 1; i >= 0; i--)
955 for (uint32_t j = 0; j < countof(buf); j++)
958 ASSERT(kfile_write(&fd[i].fd, buf, sizeof(buf)) == sizeof(buf));
959 ASSERT(fd[i].fd.size == sizeof(buf));
960 ASSERT(fd[i].fd.seek_pos == sizeof(buf));
961 ASSERT(kfile_seek(&fd[i].fd, 0, SEEK_SET) == 0);
964 for (inode_t i = 0; i < N_FILES; i++)
966 memset(buf, 0, sizeof(buf));
967 ASSERT(kfile_read(&fd[i].fd, buf, sizeof(buf)) == sizeof(buf));
969 for (uint32_t j = 0; j < countof(buf); j++)
970 ASSERT(buf[j] == j+i);
972 ASSERT(fd[i].fd.size == sizeof(buf));
973 ASSERT(fd[i].fd.seek_pos == sizeof(buf));
974 ASSERT(kfile_seek(&fd[i].fd, 0, SEEK_SET) == 0);
977 for (inode_t i = 0; i < N_FILES; i++)
979 ASSERT(kfile_close(&fd[i].fd) == 0);
980 ASSERT(kfile_error(&fd[i].fd) == 0);
983 ASSERT(battfs_fsck(disk));
984 ASSERT(battfs_umount(disk));
986 fpt = fopen(test_filename, "r+");
987 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
989 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
990 ASSERT(battfs_fsck(disk));
992 for (inode_t i = 0; i < N_FILES; i++)
993 ASSERT(battfs_fileopen(disk, &fd[i], i, 0));
995 for (inode_t i = 0; i < N_FILES; i++)
997 memset(buf, 0, sizeof(buf));
998 ASSERT(kfile_read(&fd[i].fd, buf, sizeof(buf)) == sizeof(buf));
1000 for (uint32_t j = 0; j < countof(buf); j++)
1001 ASSERT(buf[j] == j+i);
1003 ASSERT(fd[i].fd.size == sizeof(buf));
1004 ASSERT(fd[i].fd.seek_pos == sizeof(buf));
1005 ASSERT(kfile_seek(&fd[i].fd, 0, SEEK_SET) == 0);
1008 for (inode_t i = 0; i < N_FILES; i++)
1010 ASSERT(kfile_close(&fd[i].fd) == 0);
1011 ASSERT(kfile_error(&fd[i].fd) == 0);
1014 ASSERT(battfs_umount(disk));
1015 TRACEMSG("21: passed\n");
1019 static void openAllFiles(BattFsSuper *disk)
1021 TRACEMSG("22: try to open a lot of files\n");
1023 FILE *fpt = fopen(test_filename, "w+");
1024 for (int i = 0; i < FILE_SIZE; i++)
1027 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
1029 BattFs fd[BATTFS_MAX_FILES];
1030 unsigned int MODE = BATTFS_CREATE;
1032 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
1033 ASSERT(battfs_fsck(disk));
1034 for (unsigned i = 0; i < countof(fd); i++)
1035 ASSERT(battfs_fileopen(disk, &fd[i], i, MODE));
1037 ASSERT(battfs_fsck(disk));
1039 for (unsigned i = 0; i < countof(fd); i++)
1041 ASSERT(kfile_close(&fd[i].fd) == 0);
1042 ASSERT(kfile_error(&fd[i].fd) == 0);
1045 ASSERT(battfs_fsck(disk));
1046 ASSERT(battfs_umount(disk));
1049 fpt = fopen(test_filename, "r+");
1050 kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
1052 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
1053 ASSERT(battfs_fsck(disk));
1056 for (unsigned i = 0; i < countof(fd); i++)
1057 ASSERT(battfs_fileopen(disk, &fd[i], i, MODE));
1059 ASSERT(battfs_fsck(disk));
1061 for (unsigned i = 0; i < countof(fd); i++)
1063 ASSERT(kfile_close(&fd[i].fd) == 0);
1064 ASSERT(kfile_error(&fd[i].fd) == 0);
1067 ASSERT(battfs_fsck(disk));
1068 ASSERT(battfs_umount(disk));
1069 TRACEMSG("22: passed\n");
1073 int battfs_testRun(void)
1079 diskHalfFile(&disk);
1090 multipleWrite(&disk);
1091 increaseFile(&disk);
1095 multipleFilesRW(&disk);
1096 openAllFiles(&disk);
1098 kprintf("All tests passed!\n");
1103 int battfs_testSetup(void)
1108 int battfs_testTearDown(void)