d->page_size = PAGE_SIZE;
d->page_count = ftell(fp) / d->page_size;
d->page_array = malloc(d->page_count * sizeof(pgcnt_t));
- TRACEMSG("page_size:%d, page_count:%d, disk_size:%d\n", d->page_size, d->page_count, d->disk_size);
+ TRACEMSG("page_size:%d, page_count:%d\n", d->page_size, d->page_count);
return (fp && d->page_array);
}
return fread(buf, 1, size, fp);
}
-static size_t disk_page_write(struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, void *buf, size_t size)
+static size_t disk_page_write(struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, const void *buf, size_t size)
{
TRACEMSG("page:%d, addr:%d, size:%d\n", page, addr, size);
fseek(fp, page * d->page_size + addr, SEEK_SET);
{
if (argc < 2)
{
- FILE *fpt = fopen(test_filename, "w+");
- for (int i = 0; i < 32768; i++)
- fputc(0xff, fpt);
- fclose(fpt);
+/* FILE *fpt = fopen(test_filename, "w+");
+ for (int i = 0; i < 32768; i++)
+ fputc(0xff, fpt);
+ fclose(fpt);*/
filename = test_filename;
}
else
kprintf("%04d ", disk.page_array[i]);
}
kputchar('\n');
+
+ for (pgcnt_t i = 0; i < disk.page_count; i++)
+ {
+ if (i < disk.page_count / 2)
+ {
+ if (!battfs_writeTestBlock(&disk, i, i, i, i/3, 0, MARK_PAGE_VALID))
+ {
+ TRACEMSG("error writing:%d\n", i);
+ return 2;
+ }
+ }
+ else
+ {
+ if (!battfs_writeTestBlock(&disk, i, i, i, i/3, 0, i))
+ {
+ TRACEMSG("error writing:%d\n", i);
+ return 2;
+ }
+ }
+
+ }
return 0;
}
else
* Header is actually a footer, and so
* resides at page end.
*/
- if (disk->read(disk, page, disk->page_size - BATTFS_HEADER_LEN - 1, buf, BATTFS_HEADER_LEN)
+ if (disk->read(disk, page, disk->page_size - BATTFS_HEADER_LEN, buf, BATTFS_HEADER_LEN)
!= BATTFS_HEADER_LEN)
{
TRACEMSG("Error: page[%d]\n", page);
return true;
}
+/**
+ * Write header of page \a page.
+ * \return true on success, false otherwise.
+ * \note \a hdr is dirtyed even on errors.
+ */
+static bool battfs_writeHeader(struct BattFsSuper *disk, pgcnt_t page, struct BattFsPageHeader *hdr)
+{
+ uint8_t buf[BATTFS_HEADER_LEN];
+
+ /* Fill buffer */
+ battfs_to_disk(hdr, buf);
+
+ /*
+ * write header to disk.
+ * Header is actually a footer, and so
+ * resides at page end.
+ */
+ if (disk->write(disk, page, disk->page_size - BATTFS_HEADER_LEN, buf, BATTFS_HEADER_LEN)
+ != BATTFS_HEADER_LEN)
+ {
+ TRACEMSG("Error: page[%d]\n", page);
+ return false;
+ }
+ return true;
+}
+
/**
* Count the number of pages from
* inode 0 to \a inode in \a filelen_table.
* No valid interval found.
* Hopefully the disk is brand new.
*/
- TRACEMSG("No valid marked free block found, new disk?\n");
+ TRACEMSG("No valid marked free block found, new disk or disk full\n");
disk->free_start = 0;
disk->free_next = -1; //to be incremented ahead
}
}
+bool battfs_writeTestBlock(struct BattFsSuper *disk, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff, mark_t mark)
+{
+ BattFsPageHeader hdr;
+ TRACEMSG("page %d, inode %d, pgoff %d\n", page, inode, pgoff);
+
+ hdr.inode = inode;
+ hdr.seq = seq;
+ hdr.fill = fill;
+ hdr.pgoff = pgoff;
+ hdr.mark = MARK_PAGE_VALID;
+ hdr.fcs_free = FCS_FREE_VALID;
+ hdr.fcs = computeFcs(&hdr);
+ if (mark != MARK_PAGE_VALID)
+ {
+ hdr.mark = mark;
+ hdr.fcs_free = computeFcsFree(&hdr);
+ }
+
+ if (!battfs_writeHeader(disk, page, &hdr))
+ {
+ TRACEMSG("error writing hdr\n");
+ return false;
+ }
+
+ return true;
+}
* Simply set to 1 all field bits.
* \{
*/
-#define MARK_PAGE_VALID ((1LL << (CPU_BITS_PER_CHAR * sizeof(mark_t))) - 1)
+#define MARK_PAGE_VALID ((1 << (CPU_BITS_PER_CHAR * sizeof(pgaddr_t) + 1)) - 1)
#define FCS_FREE_VALID ((1 << (CPU_BITS_PER_CHAR * sizeof(fcs_t))) - 1)
/* \} */
* \a size the lenght to be written.
* \return the number of bytes written.
*/
-typedef size_t (*disk_page_write_t) (struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, void *buf, size_t);
+typedef size_t (*disk_page_write_t) (struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, const void *buf, size_t);
/**
* Type interface for disk page erase function.
} BattFsSuper;
bool battfs_init(struct BattFsSuper *d);
+bool battfs_writeTestBlock(struct BattFsSuper *disk, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff, mark_t mark);
#endif /* FS_BATTFS_H */