fs.c revision f79b2dff1024db4f6326f3422236bed169dd902f
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> 19f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <sys/endian.h> 20f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 21f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "extent.h" 22f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "errors.h" 23f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "fat.h" 24f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "fs.h" 25f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "types.h" 26f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "utils.h" 27f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 28f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#define DEFAULT_SECTOR_SIZE 512 29f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 30f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic void fs_add_extent(struct fs *fs, struct extent *extent, 31f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t start, offset_t len, int type) 32f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 33f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 34f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(extent); 35f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 36f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->start = start; 37f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->len = len; 38f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->type = type; 39f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 40f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->next = fs->extents; 41f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->extents = extent; 42f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 43f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 44f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestruct extent *fs_find_extent(struct fs *fs, offset_t start, offset_t len, 45f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct extent *last, 46f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t *r_start_out, 47f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t *e_start_out, 48f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t *len_out) 49f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 50f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct extent *e; 51f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t end; 52f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t e_start, e_end, e_len, e_rel_start, r_rel_start, rel_len; 53f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 54f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 55f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 56f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle end = start + len; 57f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 58f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e = last ? last->next : fs->extents; 59f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (; e; e = e->next) { 60f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_start = e->start; 61f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_len = e->len; 62f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_end = e_start + e_len; 63f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 64f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (start >= e_end) 65f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle continue; 66f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 67f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (end <= e_start) 68f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle continue; 69f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 70f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (e_start <= start) { 71f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle r_rel_start = 0; 72f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_rel_start = start - e_start; 73f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (end <= e_end) 74f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle rel_len = len; 75f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle else 76f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle rel_len = e_end - start; 77f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } else { 78f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle e_rel_start = 0; 79f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle r_rel_start = e_start - start; 80f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (e_end <= end) 81f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle rel_len = e_len; 82f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle else 83f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle rel_len = end - e_start; 84f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 85f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 86f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(e_rel_start < e_len); 87f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(e_rel_start + rel_len <= e_len); 88f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(r_rel_start < len); 89f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(r_rel_start + rel_len <= len); 90f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 91f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (r_start_out) 92f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *r_start_out = r_rel_start; 93f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (e_start_out) 94f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *e_start_out = e_rel_start; 95f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (len_out) 96f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *len_out = rel_len; 97f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 98f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return e; 99f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 100f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 101f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return NULL; 102f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 103f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 104f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic void fs_set_fat(struct fs *fs, cluster_t cluster, fat_entry_t entry) 105f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 106f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 107f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 108f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->fat[cluster] = htole32(entry); 109f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 110f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 111f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttleint fs_alloc_extent(struct fs *fs, struct extent *extent, 112f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle offset_t len, int type, cluster_t *first_cluster_out) 113f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 114f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 115f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(extent); 116f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 117f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t clusters_needed, start; 118f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t i; 119f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 120f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (len == 0) { 121f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->start = 0; 122f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->len = 0; 123f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent->type = type; 124f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *first_cluster_out = 0; 125f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 126f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 127f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 128f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle clusters_needed = (len + fs->cluster_size - 1) / fs->cluster_size; 129f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 130f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* Check for adequate space. */ 131f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (fs->next_cluster + clusters_needed > fs->num_clusters) { 132f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("allocating extent: filesystem is full!\n"); 133f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 134f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 135f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 136f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* Allocate clusters. */ 137f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle start = fs->next_cluster; 138f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->next_cluster += clusters_needed; 139f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 140f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* Update FAT. */ 141f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (i = 0; i < clusters_needed - 1; i++) { 142f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_set_fat(fs, start + i, start + i + 1); 143f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 144f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_set_fat(fs, start + clusters_needed - 1, FAT_ENTRY_EOC); 145f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 146f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle *first_cluster_out = start; 147f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 148f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_add_extent(fs, 149f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle extent, 150f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->data_offset + (offset_t)(start - FAT_CLUSTER_ZERO) 151f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * fs->cluster_size, 152f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle (offset_t)clusters_needed * fs->cluster_size, 153f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle type); 154f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 155f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 156f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 157f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 158f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttleint fs_init(struct fs *fs, uint16_t cluster_size, offset_t data_size, offset_t *total_size_out) 159f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 160f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle uint16_t sector_size; 161f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t data_clusters; 162f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sector_t reserved_sectors, fat_sectors, data_sectors, total_sectors; 163f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sector_t sectors_per_cluster; 164f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int fat_entries_per_sector; 165f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_entry_t *fat; 166f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct fat_boot_sector *bs; 167f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct fat_info_sector *is; 168f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 169f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(fs); 170f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 171f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sector_size = DEFAULT_SECTOR_SIZE; 172f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->cluster_size = cluster_size; 173f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 174f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle sectors_per_cluster = cluster_size / DEFAULT_SECTOR_SIZE; 175f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_entries_per_sector = sector_size / sizeof(fat_entry_t); 176f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 177f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle data_clusters = (data_size + cluster_size - 1) / cluster_size; 178f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle data_sectors = data_clusters * sectors_per_cluster; 179f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_sectors = ((data_clusters + 2) + fat_entries_per_sector - 1) 180f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle / fat_entries_per_sector; 181f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle reserved_sectors = 3; 182f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle total_sectors = reserved_sectors + fat_sectors + data_sectors; 183f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 184f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(&fs->boot, 0, sizeof(fs->boot)); 185f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs = &fs->boot; 186f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 187f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle strpadcpy(bs->name, "FATBLOCK", ' ', sizeof(bs->name)); 188f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->sector_size = htole16(sector_size); 189f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->sectors_per_cluster = sectors_per_cluster; 190f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->reserved_sectors = htole16(reserved_sectors); 191f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->fats = 1; 192f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->media_desc = FAT_MEDIA_DESC_FIXED; 193f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* TODO: Calculate geometry? */ 194f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->sectors_per_track = htole16(42); 195f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->heads = htole16(42); 196f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->sectors32 = htole32(total_sectors); 197f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->fat_sectors32 = htole32(fat_sectors); 198f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* bs->rootdir_start will be set later. */ 199f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->fs_info_sector = htole16(1); 200f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->backup_boot_sector = htole16(2); 201f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->phys_drive = FAT_PHYS_DRIVE_REMOVABLE; 202f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->ext_boot_sig = FAT_EXT_BOOT_SIG; 203f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle bs->serial = 0x42424242; 204f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle strpadcpy(bs->vol_label, "FATBLOCK", ' ', sizeof(bs->vol_label)); 205f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle strpadcpy(bs->type, "FAT32", ' ', sizeof(bs->type)); 206f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(bs->boot_sig, FAT_BOOT_SIG, sizeof(bs->boot_sig)); 207f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 208f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(&fs->info, 0, sizeof(fs->info)); 209f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle is = &fs->info; 210f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 211f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(is->info_sig1, FAT_INFO_SIG1, sizeof(is->info_sig1)); 212f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(is->info_sig2, FAT_INFO_SIG2, sizeof(is->info_sig2)); 213f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle is->free_clusters = htole32(-1); 214f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle is->last_cluster = htole32(FAT_CLUSTER_ZERO); 215f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memcpy(is->info_sig3, FAT_INFO_SIG3, sizeof(is->info_sig3)); 216f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 217f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->num_clusters = FAT_CLUSTER_ZERO + data_clusters; 218f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->next_cluster = FAT_CLUSTER_ZERO; 219f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 220f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->fat_size = fat_sectors * sector_size; 221f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs->fat = malloc(fs->fat_size); 222f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!fs->fat) { 223f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("initializing filesystem: couldn't allocate FAT extent: 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