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_posix.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)
53 #define HW_PAGEBUF true
56 const char test_filename[]="battfs_disk.bin";
58 static uint8_t page_buffer[PAGE_SIZE];
59 static pgcnt_t page_array[PAGE_COUNT];
61 static void testCheck(BattFsSuper *disk, pgcnt_t *reference)
63 ASSERT(battfs_fsck(disk));
65 for (unsigned i = 0; i < disk->dev->blk_cnt; i++)
67 if (disk->page_array[i] != reference[i])
69 kprintf("Error at addr %d: page_array read", i);
70 for (pgcnt_t i = 0; i < disk->dev->blk_cnt; i++)
74 kprintf("%04d ", disk->page_array[i]);
78 for (pgcnt_t i = 0; i < disk->dev->blk_cnt; i++)
82 kprintf("%04d ", reference[i]);
90 ASSERT(battfs_fsck(disk));
91 ASSERT(battfs_umount(disk));
94 static void diskNew(BattFsSuper *disk)
96 pgcnt_t ref[PAGE_COUNT];
98 TRACEMSG("1: disk new\n");
100 FILE *fpt = fopen(test_filename, "w+");
102 for (int i = 0; i < FILE_SIZE; i++)
105 for (int i = 0; i < PAGE_COUNT; i++)
109 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
110 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
112 testCheck(disk, ref);
113 TRACEMSG("1: passed\n");
116 static void disk1File(BattFsSuper *disk)
118 pgcnt_t ref[PAGE_COUNT];
119 TRACEMSG("2: disk full with 1 contiguos file\n");
121 FILE *fp = fopen(test_filename, "w+");
122 for (int i = 0; i < FILE_SIZE; i++)
126 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
128 for (int i = 0; i < PAGE_COUNT; i++)
130 battfs_writeTestBlock(&f.b, i, 0, 0, DATA_SIZE, i);
134 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
136 testCheck(disk, ref);
137 TRACEMSG("2: passed\n");
141 static void diskHalfFile(BattFsSuper *disk)
143 pgcnt_t ref[PAGE_COUNT];
144 TRACEMSG("3: disk half full with 1 contiguos file, rest unformatted\n");
147 FILE *fp = fopen(test_filename, "w+");
148 for (int i = 0; i < FILE_SIZE; i++)
152 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
154 for (int i = 0; i < PAGE_COUNT / 2; i++)
156 battfs_writeTestBlock(&f.b, i, 0, 0, DATA_SIZE, i);
159 fseek(fp, FILE_SIZE / 2, SEEK_SET);
160 for (int i = FILE_SIZE / 2; i < FILE_SIZE; i++)
163 for (int i = PAGE_COUNT / 2; i < PAGE_COUNT; i++)
168 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
170 testCheck(disk, ref);
171 TRACEMSG("3: passed\n");
175 static void oldSeq1(BattFsSuper *disk)
178 TRACEMSG("6: 1 file with 1 old seq num, 1 free block\n");
180 FILE *fp = fopen(test_filename, "w+");
181 for (int i = 0; i < PAGE_SIZE * 4; i++)
184 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 4);
186 // page, inode, seq, fill, pgoff
187 battfs_writeTestBlock(&f.b, 0, 0, 0, DATA_SIZE, 0);
188 battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 1);
189 battfs_writeTestBlock(&f.b, 2, 0, 1, DATA_SIZE, 1);
190 battfs_eraseBlock(&f.b, 3);
197 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
199 testCheck(disk, ref);
200 TRACEMSG("6: passed\n");
203 static void oldSeq2(BattFsSuper *disk)
206 TRACEMSG("7: 1 file with 1 old seq num, 1 free block\n");
208 FILE *fp = fopen(test_filename, "w+");
209 for (int i = 0; i < PAGE_SIZE * 4; i++)
212 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 4);
214 // page, inode, seq, fill, pgoff
215 battfs_writeTestBlock(&f.b, 0, 0, 0, DATA_SIZE, 0);
216 battfs_writeTestBlock(&f.b, 1, 0, 1, DATA_SIZE, 1);
217 battfs_writeTestBlock(&f.b, 2, 0, 0, DATA_SIZE, 1);
218 battfs_eraseBlock(&f.b, 3);
225 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
226 testCheck(disk, ref);
227 TRACEMSG("7: passed\n");
230 static void oldSeq3(BattFsSuper *disk)
233 TRACEMSG("8: 1 file with 1 old seq num, 1 free block\n");
236 FILE *fp = fopen(test_filename, "w+");
237 for (int i = 0; i < PAGE_SIZE * 4; i++)
240 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 4);
242 // page, inode, seq, fill, pgoff
243 battfs_eraseBlock(&f.b, 0);
244 battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 0);
245 battfs_writeTestBlock(&f.b, 2, 0, 1, DATA_SIZE, 1);
246 battfs_writeTestBlock(&f.b, 3, 0, 0, DATA_SIZE, 1);
253 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
254 testCheck(disk, ref);
255 TRACEMSG("8: passed\n");
258 static void oldSeq2File(BattFsSuper *disk)
261 TRACEMSG("9: 2 file with old seq num, 2 free block\n");
264 FILE *fp = fopen(test_filename, "w+");
265 for (int i = 0; i < PAGE_SIZE * 8; i++)
268 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
270 // page, inode, seq, fill, pgoff
271 battfs_eraseBlock(&f.b, 0);
272 battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 0);
273 battfs_writeTestBlock(&f.b, 2, 0, 3, DATA_SIZE, 1);
274 battfs_writeTestBlock(&f.b, 3, 0, 0, DATA_SIZE, 1);
275 battfs_eraseBlock(&f.b, 4);
276 battfs_writeTestBlock(&f.b, 5, 4, 0, DATA_SIZE, 0);
277 battfs_writeTestBlock(&f.b, 6, 4, 1, DATA_SIZE, 1);
278 battfs_writeTestBlock(&f.b, 7, 4, 0, DATA_SIZE, 1);
290 battfs_mount(disk, &f.b, page_array, sizeof(page_array));
291 testCheck(disk, ref);
292 TRACEMSG("9: passed\n");
295 static void openFile(BattFsSuper *disk)
299 TRACEMSG("10: open file test, inode 0 and inode 4\n");
301 FILE *fp = fopen(test_filename, "w+");
302 for (int i = 0; i < PAGE_SIZE * 8; i++)
305 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
308 int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
311 inode_t INEXISTENT_INODE = 123;
312 unsigned int MODE = 0;
314 // page, inode, seq, fill, pgoff
315 battfs_eraseBlock(&f.b, 0);
316 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
317 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
318 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
319 battfs_eraseBlock(&f.b, 4);
320 battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0);
321 battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1);
322 battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1);
324 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
325 ASSERT(battfs_fsck(disk));
326 ASSERT(!battfs_fileExists(disk, INEXISTENT_INODE));
328 ASSERT(battfs_fileExists(disk, INODE));
329 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
330 ASSERT(fd1.fd.size == PAGE_FILL * 2);
331 ASSERT(fd1.fd.seek_pos == 0);
332 ASSERT(fd1.mode == MODE);
333 ASSERT(fd1.inode == INODE);
334 ASSERT(fd1.start == &disk->page_array[0]);
335 ASSERT(fd1.disk == disk);
336 ASSERT(LIST_HEAD(&disk->file_opened_list) == &fd1.link);
338 ASSERT(kfile_reopen(&fd1.fd) == &fd1.fd);
339 ASSERT(fd1.fd.size == PAGE_FILL * 2);
340 ASSERT(fd1.fd.seek_pos == 0);
341 ASSERT(fd1.mode == MODE);
342 ASSERT(fd1.inode == INODE);
343 ASSERT(fd1.start == &disk->page_array[0]);
344 ASSERT(fd1.disk == disk);
345 ASSERT(LIST_HEAD(&disk->file_opened_list) == &fd1.link);
347 ASSERT(battfs_fileExists(disk, INODE2));
348 ASSERT(battfs_fileopen(disk, &fd2, INODE2, MODE));
349 ASSERT(fd2.fd.size == PAGE_FILL * 2);
350 ASSERT(fd2.fd.seek_pos == 0);
351 ASSERT(fd2.mode == MODE);
352 ASSERT(fd2.inode == INODE2);
353 ASSERT(fd2.start == &disk->page_array[2]);
354 ASSERT(fd2.disk == disk);
355 ASSERT(LIST_HEAD(&disk->file_opened_list)->succ == &fd2.link);
357 ASSERT(kfile_close(&fd1.fd) == 0);
358 ASSERT(kfile_error(&fd1.fd) == 0);
359 ASSERT(kfile_close(&fd2.fd) == 0);
360 ASSERT(kfile_error(&fd2.fd) == 0);
361 ASSERT(LIST_EMPTY(&disk->file_opened_list));
362 ASSERT(battfs_fsck(disk));
363 ASSERT(battfs_umount(disk));
365 TRACEMSG("10: passed\n");
368 static void readFile(BattFsSuper *disk)
373 TRACEMSG("11: read file test\n");
375 FILE *fp = fopen(test_filename, "w+");
376 for (int i = 0; i < PAGE_SIZE * 8; i++)
379 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
382 unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
385 unsigned int MODE = 0;
387 battfs_eraseBlock(&f.b, 0);
388 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
389 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
390 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
391 battfs_eraseBlock(&f.b, 4);
392 battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0);
393 battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1);
394 battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1);
396 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
397 ASSERT(battfs_fsck(disk));
398 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
399 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
400 ASSERT(fd1.fd.seek_pos == sizeof(buf));
401 for (size_t i = 0; i < sizeof(buf); i++)
402 ASSERT(buf[i] == 0xff);
404 ASSERT(kfile_close(&fd1.fd) == 0);
405 ASSERT(kfile_error(&fd1.fd) == 0);
406 ASSERT(battfs_fsck(disk));
407 ASSERT(battfs_umount(disk));
409 TRACEMSG("11: passed\n");
412 static void readAcross(BattFsSuper *disk)
416 TRACEMSG("12: read file test across page boundary and seek test\n");
418 FILE *fp = fopen(test_filename, "w+");
419 for (int i = 0; i < PAGE_SIZE * 8; i++)
422 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
424 const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
426 unsigned int MODE = 0;
427 uint8_t buf[PAGE_FILL + BATTFS_HEADER_LEN / 2];
429 battfs_eraseBlock(&f.b, 0);
430 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
431 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
432 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
433 battfs_eraseBlock(&f.b, 4);
434 battfs_writeTestBlock(&f.b, 5, INODE, 0, PAGE_FILL, 2);
435 battfs_writeTestBlock(&f.b, 6, INODE, 1, PAGE_FILL, 3);
436 battfs_writeTestBlock(&f.b, 7, INODE, 0, PAGE_FILL, 3);
438 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
439 ASSERT(battfs_fsck(disk));
440 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
442 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
443 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf));
444 for (size_t i = 0; i < sizeof(buf); i++)
445 ASSERT(buf[i] == 0xff);
447 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
448 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 2);
449 for (size_t i = 0; i < sizeof(buf); i++)
450 ASSERT(buf[i] == 0xff);
452 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
453 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
454 for (size_t i = 0; i < sizeof(buf); i++)
455 ASSERT(buf[i] == 0xff);
457 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == PAGE_FILL * 4 - sizeof(buf) * 3);
458 ASSERT(fd1.fd.seek_pos == (kfile_off_t)fd1.fd.size);
459 for (size_t i = 0; i < PAGE_FILL * 4 - sizeof(buf) * 3; i++)
460 ASSERT(buf[i] == 0xff);
462 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
463 ASSERT(fd1.fd.seek_pos == 0);
465 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_END) == (kfile_off_t)fd1.fd.size);
466 ASSERT(fd1.fd.seek_pos = (kfile_off_t)fd1.fd.size);
468 ASSERT(kfile_close(&fd1.fd) == 0);
469 ASSERT(kfile_error(&fd1.fd) == 0);
470 ASSERT(battfs_fsck(disk));
471 ASSERT(battfs_umount(disk));
473 TRACEMSG("12: passed\n");
477 static void writeFile(BattFsSuper *disk)
480 uint8_t buf[PAGE_SIZE - BATTFS_HEADER_LEN];
482 TRACEMSG("13: write file test\n");
484 FILE *fp = fopen(test_filename, "w+");
485 for (int i = 0; i < PAGE_SIZE * 8; i++)
488 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
491 unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
494 unsigned int MODE = 0;
496 battfs_eraseBlock(&f.b, 0);
497 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
498 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
499 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
500 battfs_eraseBlock(&f.b, 4);
501 battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0);
502 battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1);
503 battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1);
505 for (size_t i = 0; i < sizeof(buf); i++)
508 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
509 ASSERT(battfs_fsck(disk));
510 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
511 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
512 ASSERT(fd1.fd.seek_pos == sizeof(buf));
513 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
514 ASSERT(fd1.fd.seek_pos == 0);
516 memset(buf, 0, sizeof(buf));
517 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
518 for (size_t i = 0; i < sizeof(buf); i++)
521 ASSERT(kfile_close(&fd1.fd) == 0);
522 ASSERT(kfile_error(&fd1.fd) == 0);
523 ASSERT(battfs_fsck(disk));
524 ASSERT(battfs_umount(disk));
526 TRACEMSG("13: passed\n");
529 static void writeAcross(BattFsSuper *disk)
533 TRACEMSG("14: write file test across page boundary and seek test\n");
535 FILE *fp = fopen(test_filename, "w+");
536 for (int i = 0; i < PAGE_SIZE * 8; i++)
539 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
541 const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
543 unsigned int MODE = 0;
544 uint8_t buf[PAGE_FILL + BATTFS_HEADER_LEN / 2];
546 battfs_eraseBlock(&f.b, 0);
547 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
548 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
549 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
550 battfs_eraseBlock(&f.b, 4);
551 battfs_writeTestBlock(&f.b, 5, INODE, 0, PAGE_FILL, 2);
552 battfs_writeTestBlock(&f.b, 6, INODE, 1, PAGE_FILL, 3);
553 battfs_writeTestBlock(&f.b, 7, INODE, 0, PAGE_FILL, 3);
555 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
556 ASSERT(battfs_fsck(disk));
557 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
560 for (size_t i = 0; i < sizeof(buf); i++)
562 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
563 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf));
565 for (size_t i = 0; i < sizeof(buf); i++)
567 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
568 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 2);
570 for (size_t i = 0; i < sizeof(buf); i++)
572 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
573 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
575 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
576 ASSERT(fd1.fd.seek_pos == 0);
579 memset(buf, 0, sizeof(buf));
580 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
581 for (size_t i = 0; i < sizeof(buf); i++)
582 ASSERT(buf[i] == val++);
584 memset(buf, 0, sizeof(buf));
585 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
586 for (size_t i = 0; i < sizeof(buf); i++)
587 ASSERT(buf[i] == val++);
589 memset(buf, 0, sizeof(buf));
590 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
591 for (size_t i = 0; i < sizeof(buf); i++)
592 ASSERT(buf[i] == val++);
594 ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
596 ASSERT(kfile_close(&fd1.fd) == 0);
597 ASSERT(kfile_error(&fd1.fd) == 0);
598 ASSERT(battfs_fsck(disk));
599 ASSERT(battfs_umount(disk));
601 TRACEMSG("14: passed\n");
604 static void createFile(BattFsSuper *disk)
606 TRACEMSG("15: file creation on new disk\n");
608 FILE *fpt = fopen(test_filename, "w+");
609 for (int i = 0; i < FILE_SIZE; i++)
612 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
616 unsigned int MODE = BATTFS_CREATE;
618 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
619 ASSERT(battfs_fsck(disk));
620 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
621 for (int i = 0; i < FILE_SIZE / 2; i++)
622 ASSERT(kfile_putc(i, &fd1.fd) != EOF);
624 ASSERT(fd1.fd.seek_pos == FILE_SIZE / 2);
625 ASSERT(fd1.fd.size == FILE_SIZE / 2);
626 ASSERT(kfile_close(&fd1.fd) == 0);
627 ASSERT(kfile_error(&fd1.fd) == 0);
628 ASSERT(battfs_fsck(disk));
629 ASSERT(battfs_umount(disk));
631 fpt = fopen(test_filename, "r+");
632 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
634 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
635 ASSERT(battfs_fsck(disk));
636 ASSERT(battfs_fileopen(disk, &fd1, INODE, 0));
637 ASSERT(fd1.fd.size == FILE_SIZE / 2);
638 ASSERT(fd1.fd.seek_pos == 0);
640 uint8_t buf[FILE_SIZE / 2];
641 memset(buf, 0, sizeof(buf));
642 ASSERT(kfile_read(&fd1.fd, buf, FILE_SIZE / 2) == FILE_SIZE / 2);
644 for (int i = 0; i < FILE_SIZE / 2; i++)
645 ASSERT(buf[i] == (i & 0xff));
647 ASSERT(fd1.fd.seek_pos == FILE_SIZE / 2);
648 ASSERT(kfile_close(&fd1.fd) == 0);
649 ASSERT(kfile_error(&fd1.fd) == 0);
650 ASSERT(battfs_fsck(disk));
651 ASSERT(battfs_umount(disk));
654 TRACEMSG("15: passed\n");
657 static void multipleWrite(BattFsSuper *disk)
659 TRACEMSG("16: multiple write on file\n");
661 FILE *fpt = fopen(test_filename, "w+");
662 for (int i = 0; i < FILE_SIZE; i++)
665 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
670 unsigned int MODE = BATTFS_CREATE;
673 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
674 ASSERT(battfs_fsck(disk));
675 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
678 for (j = 1; j < 1013; j++)
680 for (unsigned i = 0; i < sizeof(buf); i++)
683 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
684 ASSERT(fd1.fd.seek_pos == sizeof(buf));
685 ASSERT(fd1.fd.size == sizeof(buf));
686 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
687 memset(buf, 0, sizeof(buf));
688 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
689 ASSERT(fd1.fd.seek_pos == sizeof(buf));
690 for (unsigned i = 0; i < sizeof(buf); i++)
691 ASSERT(buf[i] == ((j+i) & 0xff));
692 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
693 ASSERT(disk->free_bytes == disk->disk_size - sizeof(buf));
695 ASSERT(kfile_close(&fd1.fd) == 0);
696 ASSERT(kfile_error(&fd1.fd) == 0);
697 ASSERT(battfs_fsck(disk));
698 ASSERT(battfs_umount(disk));
700 fpt = fopen(test_filename, "r+");
701 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
703 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
704 ASSERT(battfs_fsck(disk));
705 ASSERT(disk->free_bytes == disk->disk_size - sizeof(buf));
706 ASSERT(battfs_fileopen(disk, &fd1, INODE, 0));
707 ASSERT(fd1.fd.size == sizeof(buf));
708 memset(buf, 0, sizeof(buf));
709 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
710 for (unsigned i = 0; i < sizeof(buf); i++)
711 ASSERT(buf[i] == ((j-1+i) & 0xff));
712 ASSERT(kfile_close(&fd1.fd) == 0);
713 ASSERT(kfile_error(&fd1.fd) == 0);
714 ASSERT(battfs_fsck(disk));
715 ASSERT(battfs_umount(disk));
718 TRACEMSG("16: passed\n");
721 static void increaseFile(BattFsSuper *disk)
723 TRACEMSG("17: increasing dimension of a file with multiple open files.\n");
725 FILE *fpt = fopen(test_filename, "w+");
726 for (int i = 0; i < FILE_SIZE / 10; i++)
730 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT / 10);
734 inode_t INODE1 = 1, INODE2 = 2;
735 unsigned int MODE = BATTFS_CREATE;
738 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
739 ASSERT(battfs_fsck(disk));
740 ASSERT(battfs_fileopen(disk, &fd1, INODE1, MODE));
741 ASSERT(battfs_fileopen(disk, &fd2, INODE2, MODE));
742 for (unsigned i = 0; i < sizeof(buf); i++)
743 ASSERT(kfile_putc(i, &fd2.fd) != EOF);
744 ASSERT(kfile_seek(&fd2.fd, 0, KSM_SEEK_SET) == 0);
745 memset(buf, 0, sizeof(buf));
746 ASSERT(kfile_read(&fd2.fd, buf, sizeof(buf)) == sizeof(buf));
748 for (unsigned i = 0; i < sizeof(buf); i++)
749 ASSERT(buf[i] == (i & 0xff));
750 ASSERT(kfile_seek(&fd2.fd, 0, KSM_SEEK_SET) == 0);
752 for (unsigned i = 0; i < sizeof(buf); i++)
753 ASSERT(kfile_putc(i, &fd1.fd) != EOF);
755 memset(buf, 0, sizeof(buf));
756 ASSERT(kfile_read(&fd2.fd, buf, sizeof(buf)) == sizeof(buf));
758 for (unsigned i = 0; i < sizeof(buf); i++)
759 ASSERT(buf[i] == (i & 0xff));
761 ASSERT(kfile_close(&fd1.fd) == 0);
762 ASSERT(kfile_error(&fd1.fd) == 0);
763 ASSERT(kfile_close(&fd2.fd) == 0);
764 ASSERT(kfile_error(&fd2.fd) == 0);
765 ASSERT(battfs_fsck(disk));
766 ASSERT(battfs_umount(disk));
768 TRACEMSG("17: passed\n");
771 static void readEOF(BattFsSuper *disk)
776 TRACEMSG("18: reading over EOF test\n");
778 FILE *fp = fopen(test_filename, "w+");
779 for (int i = 0; i < PAGE_SIZE * 8; i++)
782 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
785 unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
788 unsigned int MODE = 0;
790 battfs_eraseBlock(&f.b, 0);
791 battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0);
792 battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1);
793 battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1);
794 battfs_eraseBlock(&f.b, 4);
795 battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0);
796 battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1);
797 battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1);
799 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
800 ASSERT(battfs_fsck(disk));
801 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
802 ASSERT(kfile_seek(&fd1.fd, fd1.fd.size + 10, SEEK_SET) == fd1.fd.size + 10);
803 ASSERT(fd1.fd.seek_pos == fd1.fd.size + 10);
804 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == 0);
806 ASSERT(kfile_close(&fd1.fd) == 0);
807 ASSERT(kfile_error(&fd1.fd) == 0);
808 ASSERT(battfs_fsck(disk));
809 ASSERT(battfs_umount(disk));
811 TRACEMSG("18: passed\n");
814 static void writeEOF(BattFsSuper *disk)
816 TRACEMSG("19: writing over EOF test\n");
818 FILE *fpt = fopen(test_filename, "w+");
819 for (int i = 0; i < FILE_SIZE / 5; i++)
822 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT / 5);
826 unsigned int MODE = BATTFS_CREATE;
827 uint8_t buf[FILE_SIZE / 13];
829 for (int i = 0; i < 2; i++)
832 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
833 ASSERT(battfs_fsck(disk));
834 disk_size_t prev_free = disk->free_bytes;
835 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
836 ASSERT(fd1.fd.size == 0);
838 ASSERT(kfile_seek(&fd1.fd, 2, KSM_SEEK_END) == 2);
839 ASSERT(kfile_write(&fd1.fd, buf, 2));
840 ASSERT(fd1.fd.seek_pos == 4);
841 ASSERT(fd1.fd.size == 4);
842 ASSERT(disk->free_bytes == prev_free - 4);
843 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
845 ASSERT(kfile_read(&fd1.fd, buf, 2) == 2);
846 for (int i = 0; i < 2; i++)
850 ASSERT(kfile_read(&fd1.fd, buf, 2) == 2);
851 for (int i = 0; i < 2; i++)
852 ASSERT(buf[i] == (i & 0xff));
854 ASSERT(kfile_seek(&fd1.fd, sizeof(buf), KSM_SEEK_END) == sizeof(buf) + 4);
855 for (unsigned i = 0; i < sizeof(buf); i++)
857 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)));
858 ASSERT(fd1.fd.seek_pos == sizeof(buf) * 2 + 4);
859 ASSERT(fd1.fd.size == sizeof(buf) * 2 + 4);
860 ASSERT(disk->free_bytes == prev_free - sizeof(buf) * 2 - 4);
862 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
865 ASSERT(kfile_read(&fd1.fd, buf, 2) == 2);
866 ASSERT(fd1.fd.seek_pos == 2);
867 for (int i = 0; i < 2; i++)
871 ASSERT(kfile_read(&fd1.fd, buf, 2) == 2);
872 ASSERT(fd1.fd.seek_pos == 4);
873 for (int i = 0; i < 2; i++)
874 ASSERT(buf[i] == (i & 0xff));
877 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
878 ASSERT(fd1.fd.seek_pos == sizeof(buf) + 4);
879 for (unsigned i = 0; i < sizeof(buf); i++)
882 memset(buf, 0, sizeof(buf));
883 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
884 for (unsigned i = 0; i < sizeof(buf); i++)
885 ASSERT(buf[i] == (i & 0xff));
887 ASSERT(kfile_close(&fd1.fd) == 0);
888 ASSERT(kfile_error(&fd1.fd) == 0);
889 ASSERT(battfs_fsck(disk));
890 ASSERT(battfs_umount(disk));
892 TRACEMSG("19: passed\n");
896 static void endOfSpace(BattFsSuper *disk)
898 TRACEMSG("20: what happens when disk space is over?\n");
900 uint8_t buf[(PAGE_SIZE - BATTFS_HEADER_LEN) * 5];
902 FILE *fp = fopen(test_filename, "w+");
903 for (int i = 0; i < PAGE_SIZE * 4; i++)
906 kblockposix_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 4);
908 unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
910 unsigned int MODE = BATTFS_CREATE;
912 battfs_eraseBlock(&f.b, 0);
913 battfs_eraseBlock(&f.b, 1);
914 battfs_eraseBlock(&f.b, 2);
915 battfs_eraseBlock(&f.b, 3);
917 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
918 ASSERT(battfs_fsck(disk));
919 ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
920 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == PAGE_FILL * 4);
921 ASSERT(fd1.fd.size == (kfile_off_t)(PAGE_FILL * 4));
922 ASSERT(fd1.fd.seek_pos == (kfile_off_t)(PAGE_FILL * 4));
923 ASSERT(disk->free_bytes == 0);
925 ASSERT(kfile_close(&fd1.fd) == 0);
926 ASSERT(kfile_error(&fd1.fd) == BATTFS_DISK_SPACEOVER_ERR);
927 ASSERT(battfs_fsck(disk));
928 ASSERT(battfs_umount(disk));
930 TRACEMSG("20: passed\n");
934 static void multipleFilesRW(BattFsSuper *disk)
936 TRACEMSG("21: multiple files read/write test\n");
938 FILE *fpt = fopen(test_filename, "w+");
939 for (int i = 0; i < FILE_SIZE; i++)
942 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
946 unsigned int MODE = BATTFS_CREATE;
947 uint32_t buf[FILE_SIZE / (4 * N_FILES * sizeof(uint32_t))];
949 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
950 ASSERT(battfs_fsck(disk));
951 for (inode_t i = 0; i < N_FILES; i++)
952 ASSERT(battfs_fileopen(disk, &fd[i], i, MODE));
954 for (int i = N_FILES - 1; i >= 0; i--)
956 for (uint32_t j = 0; j < countof(buf); j++)
959 ASSERT(kfile_write(&fd[i].fd, buf, sizeof(buf)) == sizeof(buf));
960 ASSERT(fd[i].fd.size == sizeof(buf));
961 ASSERT(fd[i].fd.seek_pos == sizeof(buf));
962 ASSERT(kfile_seek(&fd[i].fd, 0, SEEK_SET) == 0);
965 for (inode_t i = 0; i < N_FILES; i++)
967 memset(buf, 0, sizeof(buf));
968 ASSERT(kfile_read(&fd[i].fd, buf, sizeof(buf)) == sizeof(buf));
970 for (uint32_t j = 0; j < countof(buf); j++)
971 ASSERT(buf[j] == j+i);
973 ASSERT(fd[i].fd.size == sizeof(buf));
974 ASSERT(fd[i].fd.seek_pos == sizeof(buf));
975 ASSERT(kfile_seek(&fd[i].fd, 0, SEEK_SET) == 0);
978 for (inode_t i = 0; i < N_FILES; i++)
980 ASSERT(kfile_close(&fd[i].fd) == 0);
981 ASSERT(kfile_error(&fd[i].fd) == 0);
984 ASSERT(battfs_fsck(disk));
985 ASSERT(battfs_umount(disk));
987 fpt = fopen(test_filename, "r+");
988 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
990 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
991 ASSERT(battfs_fsck(disk));
993 for (inode_t i = 0; i < N_FILES; i++)
994 ASSERT(battfs_fileopen(disk, &fd[i], i, 0));
996 for (inode_t i = 0; i < N_FILES; i++)
998 memset(buf, 0, sizeof(buf));
999 ASSERT(kfile_read(&fd[i].fd, buf, sizeof(buf)) == sizeof(buf));
1001 for (uint32_t j = 0; j < countof(buf); j++)
1002 ASSERT(buf[j] == j+i);
1004 ASSERT(fd[i].fd.size == sizeof(buf));
1005 ASSERT(fd[i].fd.seek_pos == sizeof(buf));
1006 ASSERT(kfile_seek(&fd[i].fd, 0, SEEK_SET) == 0);
1009 for (inode_t i = 0; i < N_FILES; i++)
1011 ASSERT(kfile_close(&fd[i].fd) == 0);
1012 ASSERT(kfile_error(&fd[i].fd) == 0);
1015 ASSERT(battfs_umount(disk));
1016 TRACEMSG("21: passed\n");
1020 static void openAllFiles(BattFsSuper *disk)
1022 TRACEMSG("22: try to open a lot of files\n");
1024 FILE *fpt = fopen(test_filename, "w+");
1025 for (int i = 0; i < FILE_SIZE; i++)
1028 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
1030 BattFs fd[BATTFS_MAX_FILES];
1031 unsigned int MODE = BATTFS_CREATE;
1033 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
1034 ASSERT(battfs_fsck(disk));
1035 for (unsigned i = 0; i < countof(fd); i++)
1036 ASSERT(battfs_fileopen(disk, &fd[i], i, MODE));
1038 ASSERT(battfs_fsck(disk));
1040 for (unsigned i = 0; i < countof(fd); i++)
1042 ASSERT(kfile_close(&fd[i].fd) == 0);
1043 ASSERT(kfile_error(&fd[i].fd) == 0);
1046 ASSERT(battfs_fsck(disk));
1047 ASSERT(battfs_umount(disk));
1050 fpt = fopen(test_filename, "r+");
1051 kblockposix_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
1053 ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
1054 ASSERT(battfs_fsck(disk));
1057 for (unsigned i = 0; i < countof(fd); i++)
1058 ASSERT(battfs_fileopen(disk, &fd[i], i, MODE));
1060 ASSERT(battfs_fsck(disk));
1062 for (unsigned i = 0; i < countof(fd); i++)
1064 ASSERT(kfile_close(&fd[i].fd) == 0);
1065 ASSERT(kfile_error(&fd[i].fd) == 0);
1068 ASSERT(battfs_fsck(disk));
1069 ASSERT(battfs_umount(disk));
1070 TRACEMSG("22: passed\n");
1074 int battfs_testRun(void)
1080 diskHalfFile(&disk);
1091 multipleWrite(&disk);
1092 increaseFile(&disk);
1096 multipleFilesRW(&disk);
1097 openAllFiles(&disk);
1099 kprintf("All tests passed!\n");
1104 int battfs_testSetup(void)
1109 int battfs_testTearDown(void)