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