static int vbr_write(struct exfat_dev* dev) { struct exfat_super_block sb; uint32_t checksum; le32_t* sector = malloc(get_sector_size()); size_t i; if (sector == NULL) { exfat_error("failed to allocate sector-sized block of memory"); return 1; } init_sb(&sb); if (exfat_write(dev, &sb, sizeof(struct exfat_super_block)) < 0) { free(sector); exfat_error("failed to write super block sector"); return 1; } checksum = exfat_vbr_start_checksum(&sb, sizeof(struct exfat_super_block)); memset(sector, 0, get_sector_size()); sector[get_sector_size() / sizeof(sector[0]) - 1] = cpu_to_le32(0xaa550000); for (i = 0; i < 8; i++) { if (exfat_write(dev, sector, get_sector_size()) < 0) { free(sector); exfat_error("failed to write a sector with boot signature"); return 1; } checksum = exfat_vbr_add_checksum(sector, get_sector_size(), checksum); } memset(sector, 0, get_sector_size()); for (i = 0; i < 2; i++) { if (exfat_write(dev, sector, get_sector_size()) < 0) { free(sector); exfat_error("failed to write an empty sector"); return 1; } checksum = exfat_vbr_add_checksum(sector, get_sector_size(), checksum); } for (i = 0; i < get_sector_size() / sizeof(sector[0]); i++) sector[i] = cpu_to_le32(checksum); if (exfat_write(dev, sector, get_sector_size()) < 0) { free(sector); exfat_error("failed to write checksum sector"); return 1; } free(sector); return 0; }
static int cbm_write(struct exfat_dev* dev) { uint32_t allocated_clusters = DIV_ROUND_UP(cbm.get_size(), get_cluster_size()) + DIV_ROUND_UP(uct.get_size(), get_cluster_size()) + DIV_ROUND_UP(rootdir.get_size(), get_cluster_size()); size_t bitmap_size = DIV_ROUND_UP(allocated_clusters, CHAR_BIT); bitmap_t* bitmap = malloc(BMAP_SIZE(bitmap_size)); size_t i; if (bitmap == NULL) { exfat_error("failed to allocate bitmap of %zu bytes", BMAP_SIZE(bitmap_size)); return 1; } memset(bitmap, 0, BMAP_SIZE(bitmap_size)); for (i = 0; i < bitmap_size * CHAR_BIT; i++) if (i < allocated_clusters) BMAP_SET(bitmap, i); if (exfat_write(dev, bitmap, bitmap_size) < 0) { free(bitmap); exfat_error("failed to write bitmap of %zu bytes", bitmap_size); return 1; } free(bitmap); return 0; }
static int uct_write(struct exfat_dev* dev) { if (exfat_write(dev, upcase_table, sizeof(upcase_table)) < 0) { exfat_error("failed to write upcase table of %zu bytes", sizeof(upcase_table)); return 1; } return 0; }
static cluster_t fat_write_entry(struct exfat_dev* dev, cluster_t cluster, cluster_t value) { le32_t fat_entry = cpu_to_le32(value); if (exfat_write(dev, &fat_entry, sizeof(fat_entry)) < 0) { exfat_error("failed to write FAT entry 0x%x", value); return 0; } return cluster + 1; }
static int erase_object(struct exfat_dev* dev, const void* block, size_t block_size, off64_t start, off64_t size) { const off64_t block_count = DIV_ROUND_UP(size, block_size); off64_t i; if (exfat_seek(dev, start, SEEK_SET) == (off64_t) -1) { exfat_error("seek to 0x%"PRIx64" failed", start); return 1; } for (i = 0; i < size; i += block_size) { if (exfat_write(dev, block, MIN(size - i, block_size)) < 0) { exfat_error("failed to erase block %"PRIu64"/%"PRIu64 " at 0x%"PRIx64, i + 1, block_count, start); return 1; } } return 0; }