Commit | Line | Data |
---|---|---|
984263bc | 1 | /* $FreeBSD: src/sys/msdosfs/denode.h,v 1.20 1999/12/29 04:54:52 peter Exp $ */ |
dadab5e9 | 2 | /* $DragonFly: src/sys/vfs/msdosfs/denode.h,v 1.3 2003/06/25 03:56:01 dillon Exp $ */ |
984263bc MD |
3 | /* $NetBSD: denode.h,v 1.25 1997/11/17 15:36:28 ws Exp $ */ |
4 | ||
5 | /*- | |
6 | * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. | |
7 | * Copyright (C) 1994, 1995, 1997 TooLs GmbH. | |
8 | * All rights reserved. | |
9 | * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by TooLs GmbH. | |
22 | * 4. The name of TooLs GmbH may not be used to endorse or promote products | |
23 | * derived from this software without specific prior written permission. | |
24 | * | |
25 | * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR | |
26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
28 | * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
29 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
31 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
32 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
33 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
34 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
35 | */ | |
36 | /* | |
37 | * Written by Paul Popelka (paulp@uts.amdahl.com) | |
38 | * | |
39 | * You can do anything you want with this software, just don't say you wrote | |
40 | * it, and don't remove this notice. | |
41 | * | |
42 | * This software is provided "as is". | |
43 | * | |
44 | * The author supplies this software to be publicly redistributed on the | |
45 | * understanding that the author is not responsible for the correct | |
46 | * functioning of this software in any circumstances and is not liable for | |
47 | * any damages caused by this software. | |
48 | * | |
49 | * October 1992 | |
50 | */ | |
51 | ||
52 | /* | |
53 | * This is the pc filesystem specific portion of the vnode structure. | |
54 | * | |
55 | * To describe a file uniquely the de_dirclust, de_diroffset, and | |
56 | * de_StartCluster fields are used. | |
57 | * | |
58 | * de_dirclust contains the cluster number of the directory cluster | |
59 | * containing the entry for a file or directory. | |
60 | * de_diroffset is the index into the cluster for the entry describing | |
61 | * a file or directory. | |
62 | * de_StartCluster is the number of the first cluster of the file or directory. | |
63 | * | |
64 | * Now to describe the quirks of the pc filesystem. | |
65 | * - Clusters 0 and 1 are reserved. | |
66 | * - The first allocatable cluster is 2. | |
67 | * - The root directory is of fixed size and all blocks that make it up | |
68 | * are contiguous. | |
69 | * - Cluster 0 refers to the root directory when it is found in the | |
70 | * startcluster field of a directory entry that points to another directory. | |
71 | * - Cluster 0 implies a 0 length file when found in the start cluster field | |
72 | * of a directory entry that points to a file. | |
73 | * - You can't use the cluster number 0 to derive the address of the root | |
74 | * directory. | |
75 | * - Multiple directory entries can point to a directory. The entry in the | |
76 | * parent directory points to a child directory. Any directories in the | |
77 | * child directory contain a ".." entry that points back to the parent. | |
78 | * The child directory itself contains a "." entry that points to itself. | |
79 | * - The root directory does not contain a "." or ".." entry. | |
80 | * - Directory entries for directories are never changed once they are created | |
81 | * (except when removed). The size stays 0, and the last modification time | |
82 | * is never changed. This is because so many directory entries can point to | |
83 | * the physical clusters that make up a directory. It would lead to an | |
84 | * update nightmare. | |
85 | * - The length field in a directory entry pointing to a directory contains 0 | |
86 | * (always). The only way to find the end of a directory is to follow the | |
87 | * cluster chain until the "last cluster" marker is found. | |
88 | * | |
89 | * My extensions to make this house of cards work. These apply only to the in | |
90 | * memory copy of the directory entry. | |
91 | * - A reference count for each denode will be kept since dos doesn't keep such | |
92 | * things. | |
93 | */ | |
94 | ||
95 | /* | |
96 | * Internal pseudo-offset for (nonexistent) directory entry for the root | |
97 | * dir in the root dir | |
98 | */ | |
99 | #define MSDOSFSROOT_OFS 0x1fffffff | |
100 | ||
101 | /* | |
102 | * The fat cache structure. fc_fsrcn is the filesystem relative cluster | |
103 | * number that corresponds to the file relative cluster number in this | |
104 | * structure (fc_frcn). | |
105 | */ | |
106 | struct fatcache { | |
107 | u_long fc_frcn; /* file relative cluster number */ | |
108 | u_long fc_fsrcn; /* filesystem relative cluster number */ | |
109 | }; | |
110 | ||
111 | /* | |
112 | * The fat entry cache as it stands helps make extending files a "quick" | |
113 | * operation by avoiding having to scan the fat to discover the last | |
114 | * cluster of the file. The cache also helps sequential reads by | |
115 | * remembering the last cluster read from the file. This also prevents us | |
116 | * from having to rescan the fat to find the next cluster to read. This | |
117 | * cache is probably pretty worthless if a file is opened by multiple | |
118 | * processes. | |
119 | */ | |
120 | #define FC_SIZE 2 /* number of entries in the cache */ | |
121 | #define FC_LASTMAP 0 /* entry the last call to pcbmap() resolved | |
122 | * to */ | |
123 | #define FC_LASTFC 1 /* entry for the last cluster in the file */ | |
124 | ||
125 | #define FCE_EMPTY 0xffffffff /* doesn't represent an actual cluster # */ | |
126 | ||
127 | /* | |
128 | * Set a slot in the fat cache. | |
129 | */ | |
130 | #define fc_setcache(dep, slot, frcn, fsrcn) \ | |
131 | (dep)->de_fc[slot].fc_frcn = frcn; \ | |
132 | (dep)->de_fc[slot].fc_fsrcn = fsrcn; | |
133 | ||
134 | /* | |
135 | * This is the in memory variant of a dos directory entry. It is usually | |
136 | * contained within a vnode. | |
137 | */ | |
138 | struct denode { | |
139 | struct lock de_lock; /* denode lock >Keep this first< */ | |
140 | struct denode *de_next; /* Hash chain forward */ | |
141 | struct denode **de_prev; /* Hash chain back */ | |
142 | struct vnode *de_vnode; /* addr of vnode we are part of */ | |
143 | struct vnode *de_devvp; /* vnode of blk dev we live on */ | |
144 | u_long de_flag; /* flag bits */ | |
145 | dev_t de_dev; /* device where direntry lives */ | |
146 | u_long de_dirclust; /* cluster of the directory file containing this entry */ | |
147 | u_long de_diroffset; /* offset of this entry in the directory cluster */ | |
148 | u_long de_fndoffset; /* offset of found dir entry */ | |
149 | int de_fndcnt; /* number of slots before de_fndoffset */ | |
150 | long de_refcnt; /* reference count */ | |
151 | struct msdosfsmount *de_pmp; /* addr of our mount struct */ | |
152 | u_char de_Name[12]; /* name, from DOS directory entry */ | |
153 | u_char de_Attributes; /* attributes, from directory entry */ | |
154 | u_char de_LowerCase; /* NT VFAT lower case flags */ | |
155 | u_char de_CHun; /* Hundredth of second of CTime*/ | |
156 | u_short de_CTime; /* creation time */ | |
157 | u_short de_CDate; /* creation date */ | |
158 | u_short de_ADate; /* access date */ | |
159 | u_short de_MTime; /* modification time */ | |
160 | u_short de_MDate; /* modification date */ | |
161 | u_long de_StartCluster; /* starting cluster of file */ | |
162 | u_long de_FileSize; /* size of file in bytes */ | |
163 | struct fatcache de_fc[FC_SIZE]; /* fat cache */ | |
164 | u_quad_t de_modrev; /* Revision level for lease. */ | |
165 | }; | |
166 | ||
167 | /* | |
168 | * Values for the de_flag field of the denode. | |
169 | */ | |
170 | #define DE_UPDATE 0x0004 /* Modification time update request */ | |
171 | #define DE_CREATE 0x0008 /* Creation time update */ | |
172 | #define DE_ACCESS 0x0010 /* Access time update */ | |
173 | #define DE_MODIFIED 0x0020 /* Denode has been modified */ | |
174 | #define DE_RENAME 0x0040 /* Denode is in the process of being renamed */ | |
175 | ||
176 | ||
177 | /* | |
178 | * Transfer directory entries between internal and external form. | |
179 | * dep is a struct denode * (internal form), | |
180 | * dp is a struct direntry * (external form). | |
181 | */ | |
182 | #define DE_INTERNALIZE32(dep, dp) \ | |
183 | ((dep)->de_StartCluster |= getushort((dp)->deHighClust) << 16) | |
184 | #define DE_INTERNALIZE(dep, dp) \ | |
185 | (bcopy((dp)->deName, (dep)->de_Name, 11), \ | |
186 | (dep)->de_Attributes = (dp)->deAttributes, \ | |
187 | (dep)->de_LowerCase = (dp)->deLowerCase, \ | |
188 | (dep)->de_CHun = (dp)->deCHundredth, \ | |
189 | (dep)->de_CTime = getushort((dp)->deCTime), \ | |
190 | (dep)->de_CDate = getushort((dp)->deCDate), \ | |
191 | (dep)->de_ADate = getushort((dp)->deADate), \ | |
192 | (dep)->de_MTime = getushort((dp)->deMTime), \ | |
193 | (dep)->de_MDate = getushort((dp)->deMDate), \ | |
194 | (dep)->de_StartCluster = getushort((dp)->deStartCluster), \ | |
195 | (dep)->de_FileSize = getulong((dp)->deFileSize), \ | |
196 | (FAT32((dep)->de_pmp) ? DE_INTERNALIZE32((dep), (dp)) : 0)) | |
197 | ||
198 | #define DE_EXTERNALIZE(dp, dep) \ | |
199 | (bcopy((dep)->de_Name, (dp)->deName, 11), \ | |
200 | (dp)->deAttributes = (dep)->de_Attributes, \ | |
201 | (dp)->deLowerCase = (dep)->de_LowerCase, \ | |
202 | (dp)->deCHundredth = (dep)->de_CHun, \ | |
203 | putushort((dp)->deCTime, (dep)->de_CTime), \ | |
204 | putushort((dp)->deCDate, (dep)->de_CDate), \ | |
205 | putushort((dp)->deADate, (dep)->de_ADate), \ | |
206 | putushort((dp)->deMTime, (dep)->de_MTime), \ | |
207 | putushort((dp)->deMDate, (dep)->de_MDate), \ | |
208 | putushort((dp)->deStartCluster, (dep)->de_StartCluster), \ | |
209 | putulong((dp)->deFileSize, \ | |
210 | ((dep)->de_Attributes & ATTR_DIRECTORY) ? 0 : (dep)->de_FileSize), \ | |
211 | putushort((dp)->deHighClust, (dep)->de_StartCluster >> 16)) | |
212 | ||
213 | #define de_forw de_chain[0] | |
214 | #define de_back de_chain[1] | |
215 | ||
216 | #ifdef _KERNEL | |
217 | ||
218 | #define VTODE(vp) ((struct denode *)(vp)->v_data) | |
219 | #define DETOV(de) ((de)->de_vnode) | |
220 | ||
221 | #define DETIMES(dep, acc, mod, cre) do { \ | |
222 | if ((dep)->de_flag & DE_UPDATE) { \ | |
223 | (dep)->de_flag |= DE_MODIFIED; \ | |
224 | unix2dostime((mod), &(dep)->de_MDate, &(dep)->de_MTime, \ | |
225 | NULL); \ | |
226 | (dep)->de_Attributes |= ATTR_ARCHIVE; \ | |
227 | } \ | |
228 | if ((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95) { \ | |
229 | (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \ | |
230 | break; \ | |
231 | } \ | |
232 | if ((dep)->de_flag & DE_ACCESS) { \ | |
233 | u_int16_t adate; \ | |
234 | \ | |
235 | unix2dostime((acc), &adate, NULL, NULL); \ | |
236 | if (adate != (dep)->de_ADate) { \ | |
237 | (dep)->de_flag |= DE_MODIFIED; \ | |
238 | (dep)->de_ADate = adate; \ | |
239 | } \ | |
240 | } \ | |
241 | if ((dep)->de_flag & DE_CREATE) { \ | |
242 | unix2dostime((cre), &(dep)->de_CDate, &(dep)->de_CTime, \ | |
243 | &(dep)->de_CHun); \ | |
244 | (dep)->de_flag |= DE_MODIFIED; \ | |
245 | } \ | |
246 | (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \ | |
247 | } while (0); | |
248 | ||
249 | /* | |
250 | * This overlays the fid structure (see mount.h) | |
251 | */ | |
252 | struct defid { | |
253 | u_short defid_len; /* length of structure */ | |
254 | u_short defid_pad; /* force long alignment */ | |
255 | ||
256 | u_long defid_dirclust; /* cluster this dir entry came from */ | |
257 | u_long defid_dirofs; /* offset of entry within the cluster */ | |
258 | #if 0 | |
259 | u_long defid_gen; /* generation number */ | |
260 | #endif | |
261 | }; | |
262 | ||
263 | extern vop_t **msdosfs_vnodeop_p; | |
264 | ||
265 | int msdosfs_lookup __P((struct vop_cachedlookup_args *)); | |
266 | int msdosfs_inactive __P((struct vop_inactive_args *)); | |
267 | int msdosfs_reclaim __P((struct vop_reclaim_args *)); | |
268 | ||
269 | /* | |
270 | * Internal service routine prototypes. | |
271 | */ | |
272 | int deget __P((struct msdosfsmount *, u_long, u_long, struct denode **)); | |
273 | int uniqdosname __P((struct denode *, struct componentname *, u_char *)); | |
274 | int findwin95 __P((struct denode *)); | |
275 | ||
276 | int readep __P((struct msdosfsmount *pmp, u_long dirclu, u_long dirofs, struct buf **bpp, struct direntry **epp)); | |
277 | int readde __P((struct denode *dep, struct buf **bpp, struct direntry **epp)); | |
278 | int deextend __P((struct denode *dep, u_long length, struct ucred *cred)); | |
279 | int fillinusemap __P((struct msdosfsmount *pmp)); | |
280 | void reinsert __P((struct denode *dep)); | |
281 | int dosdirempty __P((struct denode *dep)); | |
282 | int createde __P((struct denode *dep, struct denode *ddep, struct denode **depp, struct componentname *cnp)); | |
283 | int deupdat __P((struct denode *dep, int waitfor)); | |
284 | int removede __P((struct denode *pdep, struct denode *dep)); | |
dadab5e9 | 285 | int detrunc __P((struct denode *dep, u_long length, int flags, struct ucred *cred, struct thread *td)); |
984263bc MD |
286 | int doscheckpath __P(( struct denode *source, struct denode *target)); |
287 | #endif /* _KERNEL */ |