1 /* 2 * Copyright 1999-2001, Be Incorporated. All Rights Reserved. 3 * Copyright 2024, Haiku, Inc. All rights reserved. 4 * This file may be used under the terms of the Be Sample Code License. 5 */ 6 #ifndef DOSFS_H_ 7 #define DOSFS_H_ 8 9 10 #ifdef FS_SHELL 11 #include "fssh_defines.h" 12 #else 13 #include <SupportDefs.h> 14 #endif 15 16 17 #define CACHED_BLOCK_SIZE 512 18 #define BUF_CACHE_SIZE 20 19 20 // notify every second if the file size has changed 21 #define INODE_NOTIFICATION_INTERVAL 1000000LL 22 23 // the value given to the VFS as the preferred length of a read and write 24 #define FAT_IO_SIZE 65536 25 26 #define read16(buffer, off) B_LENDIAN_TO_HOST_INT16(*(uint16*)&buffer[off]) 27 28 #define read32(buffer, off) B_LENDIAN_TO_HOST_INT32(*(uint32*)&buffer[off]) 29 30 // true only for the root directory in a FAT12/FAT16 volume 31 #define IS_FIXED_ROOT(fatNode) ((fatNode)->de_StartCluster == 0) 32 33 #define SECTORS_PER_CLUSTER(fat_volume) \ 34 ((fat_volume->pm_bpcluster) / (fat_volume->pm_BlkPerSec * DEV_BSIZE)) 35 #define BLOCKS_PER_CLUSTER(fatVolume) (fatVolume->pm_bpcluster / DEV_BSIZE) 36 37 #define vIS_DATA_CLUSTER(fatVolume, cluster) \ 38 (((cluster) >= 2) && ((uint32)(cluster) <= fatVolume->pm_maxcluster)) 39 #define IS_DATA_CLUSTER(cluster) vIS_DATA_CLUSTER(fatVolume, cluster) 40 41 #define MOUNTED_READ_ONLY(fatVolume) \ 42 ((fatVolume->pm_flags & MSDOSFSMNT_RONLY) != 0 \ 43 || (fatVolume->pm_mountp->mnt_flag & MNT_RDONLY) != 0) 44 // these 2 flags are redundant (a side effect of simulating pieces of the FreeBSD VFS); 45 // both are checked to err on the side of caution 46 47 /* Unfortunately, ino_t's are defined as signed. This causes problems with 48 * programs (notably cp) that use the modulo of a ino_t as a 49 * hash function to index an array. This means the high bit of every ino_t 50 * is off-limits. Luckily, FAT32 is actually FAT28, so dosfs can make do with 51 * only 63 bits. 52 */ 53 #define INVALID_VNID_BITS_MASK (0x9LL << 60) 54 // the lower limit of the range of artificial inode numbers (the numbers used 55 // when the location-based inode is already taken by a renamed or deleted file) 56 #define ARTIFICIAL_VNID_BITS (0x6LL << 60) 57 #define DIR_INDEX_VNID_BITS 0 58 59 #define IS_DIR_INDEX_VNID(vnid) (((vnid) & ARTIFICIAL_VNID_BITS) == DIR_INDEX_VNID_BITS) 60 #define IS_ARTIFICIAL_VNID(vnid) (((vnid) & ARTIFICIAL_VNID_BITS) == ARTIFICIAL_VNID_BITS) 61 #define IS_INVALID_VNID(vnid) \ 62 ((!IS_DIR_INDEX_VNID(vnid) && !IS_ARTIFICIAL_VNID(vnid)) || ((vnid) & INVALID_VNID_BITS_MASK)) 63 64 // FreeBSD macros, modified to be compatible with Haiku's struct dirent. 65 // GENERIC_DIRSIZ returns an appropriate value for dirent::d_reclen. 66 #define _GENERIC_DIRLEN(namlen) ((offsetof(struct dirent, d_name) + (namlen) + 1 + 7) & ~7) 67 #define GENERIC_DIRSIZ(dp) _GENERIC_DIRLEN(strlen((dp)->d_name)) 68 69 struct mount; 70 struct vnode; 71 struct fs_vnode_ops; 72 struct fs_volume_ops; 73 74 75 enum FatType { fat12, fat16, fat32 }; 76 77 78 extern const char* LABEL_ILLEGAL; 79 extern struct fs_vnode_ops gFATVnodeOps; 80 extern struct fs_volume_ops gFATVolumeOps; 81 82 83 #ifdef __cplusplus 84 extern "C" 85 { 86 #endif 87 status_t _dosfs_access(const struct mount* bsdVolume, const struct vnode* bsdNode, 88 const int mode); 89 status_t assign_inode(struct mount* volume, ino_t* inode); 90 bool node_exists(struct mount* bsdVolume, uint64_t inode); 91 status_t discard_clusters(struct vnode* bsdNode, off_t newLength); 92 #ifdef __cplusplus 93 } 94 #endif 95 96 97 #endif // DOSFS_H_ 98