Commit | Line | Data |
---|---|---|
ad59feb8 RG |
1 | /* |
2 | * Written by Paul Popelka (paulp@uts.amdahl.com) | |
3 | * | |
4 | * You can do anything you want with this software, just don't say you wrote | |
5 | * it, and don't remove this notice. | |
6 | * | |
7 | * This software is provided "as is". | |
8 | * | |
9 | * The author supplies this software to be publicly redistributed on the | |
10 | * understanding that the author is not responsible for the correct | |
11 | * functioning of this software in any circumstances and is not liable for | |
12 | * any damages caused by this software. | |
13 | * | |
14 | * October 1992 | |
15 | * | |
16 | * from NetBSD: denode.h,v 1.2 1993/09/07 15:41:31 ws Exp | |
17 | * $Id$ | |
18 | */ | |
19 | ||
20 | /* | |
21 | * This is the pc filesystem specific portion of the vnode structure. To | |
22 | * describe a file uniquely the de_dirclust, de_diroffset, and | |
23 | * de_de.deStartCluster fields are used. de_dirclust contains the cluster | |
24 | * number of the directory cluster containing the entry for a file or | |
25 | * directory. de_diroffset is the index into the cluster for the entry | |
26 | * describing a file or directory. de_de.deStartCluster is the number of | |
27 | * the first cluster of the file or directory. Now to describe the quirks | |
28 | * of the pc filesystem. - Clusters 0 and 1 are reserved. - The first | |
29 | * allocatable cluster is 2. - The root directory is of fixed size and all | |
30 | * blocks that make it up are contiguous. - Cluster 0 refers to the root | |
31 | * directory when it is found in the startcluster field of a directory | |
32 | * entry that points to another directory. - Cluster 0 implies a 0 length | |
33 | * file when found in the start cluster field of a directory entry that | |
34 | * points to a file. - You can't use the cluster number 0 to derive the | |
35 | * address of the root directory. - Multiple directory entries can point to | |
36 | * a directory. The entry in the parent directory points to a child | |
37 | * directory. Any directories in the child directory contain a ".." entry | |
38 | * that points back to the child. The child directory itself contains a | |
39 | * "." entry that points to itself. - The root directory does not contain a | |
40 | * "." or ".." entry. - Directory entries for directories are never changed | |
41 | * once they are created (except when removed). The size stays 0, and the | |
42 | * last modification time is never changed. This is because so many | |
43 | * directory entries can point to the physical clusters that make up a | |
44 | * directory. It would lead to an update nightmare. - The length field in | |
45 | * a directory entry pointing to a directory contains 0 (always). The only | |
46 | * way to find the end of a directory is to follow the cluster chain until | |
47 | * the "last cluster" marker is found. My extensions to make this house of | |
48 | * cards work. These apply only to the in memory copy of the directory | |
49 | * entry. - A reference count for each denode will be kept since dos | |
50 | * doesn't keep such things. | |
51 | */ | |
52 | ||
53 | /* | |
54 | * Internal pseudo-offset for (nonexistent) directory entry for the root | |
55 | * dir in the root dir | |
56 | */ | |
57 | #define MSDOSFSROOT_OFS 0x1fffffff | |
58 | ||
59 | /* | |
60 | * The fat cache structure. fc_fsrcn is the filesystem relative cluster | |
61 | * number that corresponds to the file relative cluster number in this | |
62 | * structure (fc_frcn). | |
63 | */ | |
64 | struct fatcache { | |
65 | u_short fc_frcn; /* file relative cluster number */ | |
66 | u_short fc_fsrcn; /* filesystem relative cluster number */ | |
67 | }; | |
68 | ||
69 | /* | |
70 | * The fat entry cache as it stands helps make extending files a "quick" | |
71 | * operation by avoiding having to scan the fat to discover the last | |
72 | * cluster of the file. The cache also helps sequential reads by | |
73 | * remembering the last cluster read from the file. This also prevents us | |
74 | * from having to rescan the fat to find the next cluster to read. This | |
75 | * cache is probably pretty worthless if a file is opened by multiple | |
76 | * processes. | |
77 | */ | |
78 | #define FC_SIZE 2 /* number of entries in the cache */ | |
79 | #define FC_LASTMAP 0 /* entry the last call to pcbmap() resolved | |
80 | * to */ | |
81 | #define FC_LASTFC 1 /* entry for the last cluster in the file */ | |
82 | ||
83 | #define FCE_EMPTY 0xffff /* doesn't represent an actual cluster # */ | |
84 | ||
85 | /* | |
86 | * Set a slot in the fat cache. | |
87 | */ | |
88 | #define fc_setcache(dep, slot, frcn, fsrcn) \ | |
89 | (dep)->de_fc[slot].fc_frcn = frcn; \ | |
90 | (dep)->de_fc[slot].fc_fsrcn = fsrcn; | |
91 | ||
92 | /* | |
93 | * This is the in memory variant of a dos directory entry. It is usually | |
94 | * contained within a vnode. | |
95 | */ | |
96 | struct denode { | |
97 | struct denode *de_chain[2]; /* hash chain ptrs */ | |
98 | struct vnode *de_vnode; /* addr of vnode we are part of */ | |
99 | struct vnode *de_devvp; /* vnode of blk dev we live on */ | |
100 | u_long de_flag; /* flag bits */ | |
101 | dev_t de_dev; /* device where direntry lives */ | |
102 | u_long de_dirclust; /* cluster of the directory file containing this entry */ | |
103 | u_long de_diroffset; /* ordinal of this entry in the directory */ | |
104 | long de_refcnt; /* reference count */ | |
105 | struct msdosfsmount *de_pmp; /* addr of our mount struct */ | |
106 | struct lockf *de_lockf; /* byte level lock list */ | |
107 | long de_spare0; /* current lock holder */ | |
108 | long de_spare1; /* lock wanter */ | |
109 | struct direntry de_de; /* the actual directory entry */ | |
110 | struct fatcache de_fc[FC_SIZE]; /* fat cache */ | |
111 | }; | |
112 | ||
113 | /* | |
114 | * Values for the de_flag field of the denode. | |
115 | */ | |
116 | #define DELOCKED 0x0001 /* directory entry is locked */ | |
117 | #define DEWANT 0x0002 /* someone wants this de */ | |
118 | #define DERENAME 0x0004 /* de is being renamed */ | |
119 | #define DEUPD 0x0008 /* file has been modified */ | |
120 | #define DESHLOCK 0x0010 /* file has shared lock */ | |
121 | #define DEEXLOCK 0x0020 /* file has exclusive lock */ | |
122 | #define DELWAIT 0x0040 /* someone waiting on file lock */ | |
123 | #define DEMOD 0x0080 /* denode wants to be written back to disk */ | |
124 | ||
125 | /* | |
126 | * Shorthand macros used to reference fields in the direntry contained in | |
127 | * the denode structure. | |
128 | */ | |
129 | #define de_Name de_de.deName | |
130 | #define de_Extension de_de.deExtension | |
131 | #define de_Attributes de_de.deAttributes | |
132 | #define de_Reserved de_de.deReserved | |
133 | #define de_Time de_de.deTime | |
134 | #define de_Date de_de.deDate | |
135 | #define de_StartCluster de_de.deStartCluster | |
136 | #define de_FileSize de_de.deFileSize | |
137 | #define de_forw de_chain[0] | |
138 | #define de_back de_chain[1] | |
139 | ||
140 | #if defined(KERNEL) | |
141 | ||
142 | #define VTODE(vp) ((struct denode *)(vp)->v_data) | |
143 | #define DETOV(de) ((de)->de_vnode) | |
144 | ||
145 | #define DELOCK(de) delock(de) | |
146 | #define DEUNLOCK(de) deunlock(de) | |
147 | ||
148 | #define DEUPDAT(dep, t, waitfor) \ | |
149 | if (dep->de_flag & DEUPD) \ | |
150 | (void) deupdat(dep, t, waitfor); | |
151 | ||
152 | #define DETIMES(dep, t) \ | |
153 | if (dep->de_flag & DEUPD) { \ | |
154 | (dep)->de_flag |= DEMOD; \ | |
155 | unix2dostime(t, (union dosdate *)&dep->de_Date, \ | |
156 | (union dostime *)&dep->de_Time); \ | |
157 | (dep)->de_flag &= ~DEUPD; \ | |
158 | } | |
159 | ||
160 | /* | |
161 | * This overlays the fid sturcture (see mount.h) | |
162 | */ | |
163 | struct defid { | |
164 | u_short defid_len; /* length of structure */ | |
165 | u_short defid_pad; /* force long alignment */ | |
166 | ||
167 | u_long defid_dirclust; /* cluster this dir entry came from */ | |
168 | u_long defid_dirofs; /* index of entry within the cluster */ | |
169 | ||
170 | /* u_long defid_gen; /* generation number */ | |
171 | }; | |
172 | ||
173 | /* | |
174 | * Prototypes for MSDOSFS vnode operations | |
175 | */ | |
176 | int msdosfs_lookup __P((struct vnode * vp, struct nameidata * ndp, struct proc * p)); | |
177 | int msdosfs_create __P((struct nameidata * ndp, struct vattr * vap, struct proc * p)); | |
178 | int msdosfs_mknod __P((struct nameidata * ndp, struct vattr * vap, struct ucred * cred, struct proc * p)); | |
179 | int msdosfs_open __P((struct vnode * vp, int mode, struct ucred * cred, struct proc * p)); | |
180 | int msdosfs_close __P((struct vnode * vp, int fflag, struct ucred * cred, struct proc * p)); | |
181 | int msdosfs_access __P((struct vnode * vp, int mode, struct ucred * cred, struct proc * p)); | |
182 | int msdosfs_getattr __P((struct vnode * vp, struct vattr * vap, struct ucred * cred, struct proc * p)); | |
183 | int msdosfs_setattr __P((struct vnode * vp, struct vattr * vap, struct ucred * cred, struct proc * p)); | |
184 | int msdosfs_read __P((struct vnode * vp, struct uio * uio, int ioflag, struct ucred * cred)); | |
185 | int msdosfs_write __P((struct vnode * vp, struct uio * uio, int ioflag, struct ucred * cred)); | |
186 | int msdosfs_ioctl __P((struct vnode * vp, int command, caddr_t data, int fflag, struct ucred * cred, struct proc * p)); | |
187 | int msdosfs_select __P((struct vnode * vp, int which, int fflags, struct ucred * cred, struct proc * p)); | |
188 | int msdosfs_mmap __P((struct vnode * vp, int fflags, struct ucred * cred, struct proc * p)); | |
189 | int msdosfs_fsync __P((struct vnode * vp, int fflags, struct ucred * cred, int waitfor, struct proc * p)); | |
190 | int msdosfs_seek __P((struct vnode * vp, off_t oldoff, off_t newoff, struct ucred * cred)); | |
191 | int msdosfs_remove __P((struct nameidata * ndp, struct proc * p)); | |
192 | int msdosfs_link __P((struct vnode * vp, struct nameidata * ndp, struct proc * p)); | |
193 | int msdosfs_rename __P((struct nameidata * fndp, struct nameidata * tdnp, struct proc * p)); | |
194 | int msdosfs_mkdir __P((struct nameidata * ndp, struct vattr * vap, struct proc * p)); | |
195 | int msdosfs_rmdir __P((struct nameidata * ndp, struct proc * p)); | |
196 | int msdosfs_symlink __P((struct nameidata * ndp, struct vattr * vap, char *target, struct proc * p)); | |
197 | int msdosfs_readdir __P((struct vnode * vp, struct uio * uio, struct ucred * cred, int *eofflagp, u_int * cookies, int ncookies)); | |
198 | int msdosfs_readlink __P((struct vnode * vp, struct uio * uio, struct ucred * cred)); | |
199 | int msdosfs_abortop __P((struct nameidata * ndp)); | |
200 | int msdosfs_inactive __P((struct vnode * vp, struct proc * p)); | |
201 | int msdosfs_reclaim __P((struct vnode * vp)); | |
202 | int msdosfs_lock __P((struct vnode * vp)); | |
203 | int msdosfs_unlock __P((struct vnode * vp)); | |
204 | int msdosfs_bmap __P((struct vnode * vp, daddr_t bn, struct vnode ** vpp, daddr_t * bnp)); | |
205 | int msdosfs_strategy __P((struct buf * bp)); | |
206 | int msdosfs_print __P((struct vnode * vp)); | |
207 | int msdosfs_islocked __P((struct vnode * vp)); | |
208 | int msdosfs_advlock __P((struct vnode * vp, caddr_t id, int op, struct flock * fl, int flags)); | |
209 | ||
210 | /* | |
211 | * Internal service routine prototypes. | |
212 | */ | |
213 | int deget __P((struct msdosfsmount * pmp, u_long dirclust, u_long diroffset, struct direntry * direntptr, struct denode ** depp)); | |
214 | ||
215 | #endif /* defined(KERNEL) */ |