2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <sys/types.h>
23 #include <netinet/in.h>
27 /* #ifdef AFS_PTHREAD_ENV */
28 #if 0 /* temporary hack - klm */
38 #define UBIK_INTERNALS 1
41 /* these routines are called via the proc ptr in the ubik_dbase structure. They provide access to
42 * the physical disk, by converting the file numbers being processed (>= 0 for user data space, < 0
43 * for ubik system files, such as the log) to actual pathnames to open, read, write, truncate, sync,
48 static struct fdcache {
52 } fdcache[MAXFDCACHE];
54 static char pbuffer[1024];
56 /* beware, when using this function, of the header in front of most files */
58 uphys_open(register struct ubik_dbase *adbase, afs_int32 afid)
64 register struct fdcache *tfd;
65 struct fdcache *bestfd;
67 /* initialize package */
71 for (i = 0; i < MAXFDCACHE; tfd++, i++) {
72 tfd->fd = -1; /* invalid value */
73 tfd->fileID = -10000; /* invalid value */
78 /* scan file descr cache */
79 for (tfd = fdcache, i = 0; i < MAXFDCACHE; i++, tfd++) {
80 if (afid == tfd->fileID && tfd->refCount == 0) { /* don't use open fd */
81 lseek(tfd->fd, 0, 0); /* reset ptr just like open would have */
87 /* not found, open it and try to enter in cache */
88 afs_snprintf(pbuffer, sizeof(pbuffer), "%s.DB%s%d", adbase->pathName,
89 (afid<0)?"SYS":"", (afid<0)?-afid:afid);
90 fd = open(pbuffer, O_CREAT | O_RDWR, 0600);
92 /* try opening read-only */
93 fd = open(pbuffer, O_RDONLY, 0);
98 /* enter it in the cache */
101 for (i = 0; i < MAXFDCACHE; i++, tfd++) { /* look for empty slot */
107 if (!bestfd) { /* look for reclaimable slot */
109 for (i = 0; i < MAXFDCACHE; i++, tfd++) {
110 if (tfd->refCount == 0) {
116 if (bestfd) { /* found a usable slot */
121 tfd->refCount = 1; /* us */
125 /* finally, we're done */
129 /* close the file, maintaining ref count in cache structure */
131 uphys_close(register int afd)
134 register struct fdcache *tfd;
139 for (i = 0; i < MAXFDCACHE; i++, tfd++) {
141 if (tfd->fileID != -10000) {
145 if (tfd->refCount > 0) {
147 if (tfd->refCount == 0) {
161 uphys_stat(struct ubik_dbase *adbase, afs_int32 afid, struct ubik_stat *astat)
165 register afs_int32 code;
167 fd = uphys_open(adbase, afid);
170 code = fstat(fd, &tstat);
175 astat->mtime = tstat.st_mtime;
176 code = tstat.st_size - HDRSIZE;
185 uphys_read(register struct ubik_dbase *adbase, afs_int32 afile,
186 register char *abuffer, afs_int32 apos, afs_int32 alength)
189 register afs_int32 code;
191 fd = uphys_open(adbase, afile);
194 code = lseek(fd, apos + HDRSIZE, 0);
199 code = read(fd, abuffer, alength);
205 uphys_write(register struct ubik_dbase *adbase, afs_int32 afile,
206 register char *abuffer, afs_int32 apos, afs_int32 alength)
209 register afs_int32 code;
212 fd = uphys_open(adbase, afile);
215 code = lseek(fd, apos + HDRSIZE, 0);
220 length = write(fd, abuffer, alength);
221 code = uphys_close(fd);
229 uphys_truncate(register struct ubik_dbase *adbase, afs_int32 afile,
232 register afs_int32 code, fd;
233 fd = uphys_open(adbase, afile);
236 code = ftruncate(fd, asize + HDRSIZE);
241 /* get number of dbase files */
243 uphys_getnfiles(register struct ubik_dbase *adbase)
245 /* really should scan dir for data */
249 /* get database label, with aversion in host order */
251 uphys_getlabel(register struct ubik_dbase *adbase, afs_int32 afile,
252 struct ubik_version *aversion)
254 struct ubik_hdr thdr;
255 register afs_int32 code, fd;
257 fd = uphys_open(adbase, afile);
260 code = read(fd, &thdr, sizeof(thdr));
261 if (code != sizeof(thdr)) {
265 aversion->epoch = ntohl(thdr.version.epoch);
266 aversion->counter = ntohl(thdr.version.counter);
271 /* label database, with aversion in host order */
273 uphys_setlabel(register struct ubik_dbase *adbase, afs_int32 afile,
274 struct ubik_version *aversion)
276 struct ubik_hdr thdr;
277 register afs_int32 code, fd;
279 fd = uphys_open(adbase, afile);
282 thdr.version.epoch = htonl(aversion->epoch);
283 thdr.version.counter = htonl(aversion->counter);
284 thdr.magic = htonl(UBIK_MAGIC);
285 thdr.size = htons(HDRSIZE);
286 code = write(fd, &thdr, sizeof(thdr));
287 fsync(fd); /* preserve over crash */
289 if (code != sizeof(thdr)) {
296 uphys_sync(register struct ubik_dbase *adbase, afs_int32 afile)
298 register afs_int32 code, fd;
299 fd = uphys_open(adbase, afile);
306 uphys_invalidate(register struct ubik_dbase *adbase, afs_int32 afid)
309 register struct fdcache *tfd;
311 /* scan file descr cache */
312 for (tfd = fdcache, i = 0; i < MAXFDCACHE; i++, tfd++) {
313 if (afid == tfd->fileID) {
314 tfd->fileID = -10000;
315 if (tfd->fd >= 0 && tfd->refCount == 0) {