xref: /haiku/src/add-ons/kernel/file_systems/fat/dosfs.h (revision 1454f3c27aec3e7879a58e7cedc9d66d90c773a7)
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