1 /* 2 Copyright 1999-2001, Be Incorporated. All Rights Reserved. 3 This file may be used under the terms of the Be Sample Code License. 4 */ 5 #ifndef _DOSFS_H_ 6 #define _DOSFS_H_ 7 8 9 #include "system_dependencies.h" 10 11 12 //#define DEBUG 1 13 14 15 /* Unfortunately, ino_t's are defined as signed. This causes problems with 16 * programs (notably cp) that use the modulo of a ino_t as a 17 * hash function to index an array. This means the high bit of every ino_t 18 * is off-limits. Luckily, FAT32 is actually FAT28, so dosfs can make do with 19 * only 63 bits. 20 */ 21 #define ARTIFICIAL_VNID_BITS (0x6LL << 60) 22 #define DIR_CLUSTER_VNID_BITS (0x4LL << 60) 23 #define DIR_INDEX_VNID_BITS 0 24 #define INVALID_VNID_BITS_MASK (0x9LL << 60) 25 26 #define IS_DIR_CLUSTER_VNID(vnid) \ 27 (((vnid) & ARTIFICIAL_VNID_BITS) == DIR_CLUSTER_VNID_BITS) 28 29 #define IS_DIR_INDEX_VNID(vnid) \ 30 (((vnid) & ARTIFICIAL_VNID_BITS) == DIR_INDEX_VNID_BITS) 31 32 #define IS_ARTIFICIAL_VNID(vnid) \ 33 (((vnid) & ARTIFICIAL_VNID_BITS) == ARTIFICIAL_VNID_BITS) 34 35 #define IS_INVALID_VNID(vnid) \ 36 ((!IS_DIR_CLUSTER_VNID((vnid)) && \ 37 !IS_DIR_INDEX_VNID((vnid)) && \ 38 !IS_ARTIFICIAL_VNID((vnid))) || \ 39 ((vnid) & INVALID_VNID_BITS_MASK)) 40 41 #define GENERATE_DIR_INDEX_VNID(dircluster, index) \ 42 (DIR_INDEX_VNID_BITS | ((ino_t)(dircluster) << 32) | (index)) 43 44 #define GENERATE_DIR_CLUSTER_VNID(dircluster, filecluster) \ 45 (DIR_CLUSTER_VNID_BITS | ((ino_t)(dircluster) << 32) | (filecluster)) 46 47 #define CLUSTER_OF_DIR_CLUSTER_VNID(vnid) \ 48 ((uint32)((vnid) & 0xffffffff)) 49 50 #define INDEX_OF_DIR_INDEX_VNID(vnid) \ 51 ((uint32)((vnid) & 0xffffffff)) 52 53 #define DIR_OF_VNID(vnid) \ 54 ((uint32)(((vnid) >> 32) & ~0xf0000000)) 55 56 #define VNODE_PARENT_DIR_CLUSTER(vnode) \ 57 CLUSTER_OF_DIR_CLUSTER_VNID((vnode)->dir_vnid) 58 59 60 typedef struct vnode { 61 ino_t vnid; // self id 62 ino_t dir_vnid; // parent vnode id (directory containing entry) 63 void *cache; 64 void *file_map; 65 66 uint32 disk_image; // 0 = no, 1 = BEOS, 2 = IMAGE.BE 67 68 /* iteration is incremented each time the fat chain changes. it's used by 69 * the file read/write code to determine if it needs to retraverse the 70 * fat chain 71 */ 72 uint32 iteration; 73 74 /* any changes to this block of information should immediately be reflected 75 * on the disk (or at least in the cache) so that get_next_dirent continues 76 * to function properly 77 */ 78 uint32 sindex, eindex; // starting and ending index of directory entry 79 uint32 cluster; // starting cluster of the data 80 uint32 mode; // dos-style attributes 81 off_t st_size; // in bytes 82 time_t st_time; 83 time_t st_crtim; 84 85 uint32 end_cluster; // last cluster of the data 86 87 const char *mime; // mime type (null if none) 88 89 bool dirty; // track if vnode had been written to 90 91 char *filename; 92 } vnode; 93 94 // mode bits 95 #define FAT_READ_ONLY 1 96 #define FAT_HIDDEN 2 97 #define FAT_SYSTEM 4 98 #define FAT_VOLUME 8 99 #define FAT_SUBDIR 16 100 #define FAT_ARCHIVE 32 101 102 103 struct vcache_entry; 104 105 typedef struct _nspace { 106 fs_volume *volume; // fs_volume passed in to fs_mount 107 dev_t id; 108 int fd; // File descriptor 109 char device[256]; 110 uint32 flags; // see <fcntl.be.h> for modes 111 void *fBlockCache; 112 113 // info from bpb 114 uint32 bytes_per_sector; 115 uint32 sectors_per_cluster; 116 uint32 reserved_sectors; 117 uint32 fat_count; 118 uint32 root_entries_count; 119 uint32 total_sectors; 120 uint32 sectors_per_fat; 121 uint8 media_descriptor; 122 uint16 fsinfo_sector; 123 124 uint32 total_clusters; // data clusters, that is 125 uint32 free_clusters; 126 uint8 fat_bits; 127 bool fat_mirrored; // true if fat mirroring on 128 uint8 active_fat; 129 130 uint32 root_start; // for fat12 + fat16 only 131 uint32 root_sectors; // for fat12 + fat16 only 132 vnode root_vnode; // root directory 133 int32 vol_entry; // index in root directory 134 char vol_label[12]; // lfn's need not apply 135 136 uint32 data_start; 137 uint32 last_allocated; // last allocated cluster 138 139 ino_t beos_vnid; // vnid of \BEOS directory 140 bool respect_disk_image; 141 142 int fs_flags; // flags for this mount 143 144 recursive_lock vlock; // volume lock 145 146 // vcache state 147 struct { 148 rw_lock lock; 149 ino_t cur_vnid; 150 uint32 cache_size; 151 struct vcache_entry **by_vnid, **by_loc; 152 } vcache; 153 154 struct { 155 uint32 entries; 156 uint32 allocated; 157 ino_t *vnid_list; 158 } dlist; 159 } nspace; 160 161 #define FS_FLAGS_OP_SYNC 0x1 162 #define FS_FLAGS_LOCK_DOOR 0x2 163 164 extern fs_vnode_ops gFATVnodeOps; 165 extern fs_volume_ops gFATVolumeOps; 166 167 /* debug levels */ 168 extern int debug_attr, debug_dir, debug_dlist, debug_dosfs, debug_encodings, 169 debug_fat, debug_file, debug_iter, debug_vcache; 170 171 status_t _dosfs_sync(nspace *vol); 172 173 #endif 174