1f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle/* 2f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Copyright (C) 2010 The Android Open Source Project 3f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 4f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Licensed under the Apache License, Version 2.0 (the "License"); 5f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * you may not use this file except in compliance with the License. 6f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * You may obtain a copy of the License at 7f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 8f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * http://www.apache.org/licenses/LICENSE-2.0 9f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 10f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Unless required by applicable law or agreed to in writing, software 11f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * distributed under the License is distributed on an "AS IS" BASIS, 12f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * See the License for the specific language governing permissions and 14f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * limitations under the License. 15f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle */ 16f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 17f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <assert.h> 18f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <string.h> 19957010bef327f255cdb6909109a1f31b5ee8f443Kenny Root#include <endian.h> 20f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 210cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle#include "fatblock.h" 22f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "fat.h" 23f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "fs.h" 24f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "utils.h" 25f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 26f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#define DEFAULT_SECTOR_SIZE 512 27f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 28f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic void fs_add_extent(struct fs *fs, struct extent *extent, 29f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t start, offset_t len, int type) 30f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 31f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 32f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(extent); 33f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 34f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->start = start; 35f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->len = len; 36f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->type = type; 37f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 38f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->next = fs->extents; 39f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->extents = extent; 40f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 41f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 42f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestruct extent *fs_find_extent(struct fs *fs, offset_t start, offset_t len, 43f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct extent *last, 44f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t *r_start_out, 45f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t *e_start_out, 46f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t *len_out) 47f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 48f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct extent *e; 49f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t end; 50f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t e_start, e_end, e_len, e_rel_start, r_rel_start, rel_len; 51f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 52f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 53f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 54f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle end = start + len; 55f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 56f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e = last ? last->next : fs->extents; 57f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (; e; e = e->next) { 58f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_start = e->start; 59f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_len = e->len; 60f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_end = e_start + e_len; 61f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 62f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (start >= e_end) 63f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle continue; 64f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 65f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (end <= e_start) 66f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle continue; 67f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 68f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (e_start <= start) { 69f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle r_rel_start = 0; 70f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_rel_start = start - e_start; 71f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (end <= e_end) 72f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle rel_len = len; 73f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle else 74f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle rel_len = e_end - start; 75f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } else { 76f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_rel_start = 0; 77f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle r_rel_start = e_start - start; 78f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (e_end <= end) 79f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle rel_len = e_len; 80f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle else 81f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle rel_len = end - e_start; 82f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 83f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 84f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(e_rel_start < e_len); 85f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(e_rel_start + rel_len <= e_len); 86f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(r_rel_start < len); 87f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(r_rel_start + rel_len <= len); 88f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 89f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (r_start_out) 90f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *r_start_out = r_rel_start; 91f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (e_start_out) 92f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *e_start_out = e_rel_start; 93f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (len_out) 94f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *len_out = rel_len; 95f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 96f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return e; 97f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 98f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 99f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return NULL; 100f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 101f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 102f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic void fs_set_fat(struct fs *fs, cluster_t cluster, fat_entry_t entry) 103f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 104f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 105f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 106f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->fat[cluster] = htole32(entry); 107f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 108f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 109f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttleint fs_alloc_extent(struct fs *fs, struct extent *extent, 110f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t len, int type, cluster_t *first_cluster_out) 111f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 112f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 113f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(extent); 114f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 115f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t clusters_needed, start; 116f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t i; 117f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 118f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (len == 0) { 119f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->start = 0; 120f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->len = 0; 121f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->type = type; 122f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *first_cluster_out = 0; 123f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 124f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 125f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 126f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle clusters_needed = (len + fs->cluster_size - 1) / fs->cluster_size; 127f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 128f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* Check for adequate space. */ 129f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (fs->next_cluster + clusters_needed > fs->num_clusters) { 130f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("allocating extent: filesystem is full!\n"); 131f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 132f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 133f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 134f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* Allocate clusters. */ 135f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle start = fs->next_cluster; 136f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->next_cluster += clusters_needed; 137f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 138f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* Update FAT. */ 139f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (i = 0; i < clusters_needed - 1; i++) { 140f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_set_fat(fs, start + i, start + i + 1); 141f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 142f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_set_fat(fs, start + clusters_needed - 1, FAT_ENTRY_EOC); 143f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 144f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *first_cluster_out = start; 145f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 146f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_add_extent(fs, 147f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent, 148f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->data_offset + (offset_t)(start - FAT_CLUSTER_ZERO) 149f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * fs->cluster_size, 150f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle (offset_t)clusters_needed * fs->cluster_size, 151f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle type); 152f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 153f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 154f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 155f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 1560cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttleint fs_init(struct fs *fs, uint16_t cluster_size, offset_t data_size, 1570cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle offset_t *total_size_out) 158f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 159f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle uint16_t sector_size; 160f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t data_clusters; 161f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sector_t reserved_sectors, fat_sectors, data_sectors, total_sectors; 162f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sector_t sectors_per_cluster; 163f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int fat_entries_per_sector; 164f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_entry_t *fat; 165f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct fat_boot_sector *bs; 166f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct fat_info_sector *is; 167f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 168f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 169f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 170f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sector_size = DEFAULT_SECTOR_SIZE; 171f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->cluster_size = cluster_size; 172f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 173f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sectors_per_cluster = cluster_size / DEFAULT_SECTOR_SIZE; 174f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_entries_per_sector = sector_size / sizeof(fat_entry_t); 175f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 176f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle data_clusters = (data_size + cluster_size - 1) / cluster_size; 177f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle data_sectors = data_clusters * sectors_per_cluster; 178f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_sectors = ((data_clusters + 2) + fat_entries_per_sector - 1) 179f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle / fat_entries_per_sector; 180f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle reserved_sectors = 3; 181f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle total_sectors = reserved_sectors + fat_sectors + data_sectors; 182f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 183f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(&fs->boot, 0, sizeof(fs->boot)); 184f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs = &fs->boot; 185f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 186f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle strpadcpy(bs->name, "FATBLOCK", ' ', sizeof(bs->name)); 187f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->sector_size = htole16(sector_size); 188f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->sectors_per_cluster = sectors_per_cluster; 189f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->reserved_sectors = htole16(reserved_sectors); 190f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->fats = 1; 191f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->media_desc = FAT_MEDIA_DESC_FIXED; 192f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* TODO: Calculate geometry? */ 193f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->sectors_per_track = htole16(42); 194f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->heads = htole16(42); 195f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->sectors32 = htole32(total_sectors); 196f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->fat_sectors32 = htole32(fat_sectors); 197f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* bs->rootdir_start will be set later. */ 198f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->fs_info_sector = htole16(1); 199f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->backup_boot_sector = htole16(2); 200f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->phys_drive = FAT_PHYS_DRIVE_REMOVABLE; 201f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->ext_boot_sig = FAT_EXT_BOOT_SIG; 202f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->serial = 0x42424242; 203f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle strpadcpy(bs->vol_label, "FATBLOCK", ' ', sizeof(bs->vol_label)); 204f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle strpadcpy(bs->type, "FAT32", ' ', sizeof(bs->type)); 205f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(bs->boot_sig, FAT_BOOT_SIG, sizeof(bs->boot_sig)); 206f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 207f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(&fs->info, 0, sizeof(fs->info)); 208f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle is = &fs->info; 209f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 210f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(is->info_sig1, FAT_INFO_SIG1, sizeof(is->info_sig1)); 211f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(is->info_sig2, FAT_INFO_SIG2, sizeof(is->info_sig2)); 212f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle is->free_clusters = htole32(-1); 213f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle is->last_cluster = htole32(FAT_CLUSTER_ZERO); 214f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(is->info_sig3, FAT_INFO_SIG3, sizeof(is->info_sig3)); 215f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 216f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->num_clusters = FAT_CLUSTER_ZERO + data_clusters; 217f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->next_cluster = FAT_CLUSTER_ZERO; 218f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 219f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->fat_size = fat_sectors * sector_size; 220f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->fat = malloc(fs->fat_size); 221f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!fs->fat) { 2220cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle WARN("initializing filesystem: couldn't allocate FAT extent: " 2230cb61411eadd92b7202e045c1c9ec8df7fb636feThomas Tuttle "out of memory\n"); 224f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return MALLOC_FAIL; 225f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 226f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(fs->fat, 0, fs->fat_size); 227f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 228f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->data_offset = (reserved_sectors + fat_sectors) * sector_size; 229f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 230f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->extents = NULL; 231f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_add_extent(fs, &fs->boot_extent, 232f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 0, sector_size, 233f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle EXTENT_TYPE_BOOT); 234f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_add_extent(fs, &fs->info_extent, 235f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sector_size, sector_size, 236f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle EXTENT_TYPE_INFO); 237f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_add_extent(fs, &fs->backup_boot_extent, 238f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 2 * sector_size, sector_size, 239f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle EXTENT_TYPE_BOOT); 240f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_add_extent(fs, &fs->fat_extent, 241f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle reserved_sectors * sector_size, fs->fat_size, 242f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle EXTENT_TYPE_FAT); 243f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 244f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *total_size_out = (offset_t)total_sectors * sector_size; 245f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 246f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 247f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 248f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 249f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlevoid fs_set_rootdir_start(struct fs *fs, cluster_t rootdir_start) 250f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 251f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 252f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 253f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->boot.rootdir_start = htole32(rootdir_start); 254f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 255f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 256f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlevoid fs_update_free_clusters(struct fs *fs) 257f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 258f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 259f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 260f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->info.free_clusters = htole32(fs->num_clusters - fs->next_cluster); 261f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 262