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>
37 #define UBIK_INTERNALS 1
40 /* these routines are called via the proc ptr in the ubik_dbase structure. They provide access to
41 * the physical disk, by converting the file numbers being processed (>= 0 for user data space, < 0
42 * for ubik system files, such as the log) to actual pathnames to open, read, write, truncate, sync,
47 static struct fdcache {
51 } fdcache[MAXFDCACHE];
53 static char pbuffer[1024];
55 /* beware, when using this function, of the header in front of most files */
57 uphys_open(register struct ubik_dbase *adbase, afs_int32 afid)
63 register struct fdcache *tfd;
64 struct fdcache *bestfd;
66 /* initialize package */
70 for (i = 0; i < MAXFDCACHE; tfd++, i++) {
71 tfd->fd = -1; /* invalid value */
72 tfd->fileID = -10000; /* invalid value */
77 /* scan file descr cache */
78 for (tfd = fdcache, i = 0; i < MAXFDCACHE; i++, tfd++) {
79 if (afid == tfd->fileID && tfd->refCount == 0) { /* don't use open fd */
80 lseek(tfd->fd, 0, 0); /* reset ptr just like open would have */
86 /* not found, open it and try to enter in cache */
87 strcpy(pbuffer, adbase->pathName);
88 strcat(pbuffer, ".DB");
91 strcat(pbuffer, "SYS");
94 sprintf(temp, "%d", i);
95 strcat(pbuffer, temp);
96 fd = open(pbuffer, O_CREAT | O_RDWR, 0600);
98 /* try opening read-only */
99 fd = open(pbuffer, O_RDONLY, 0);
104 /* enter it in the cache */
107 for (i = 0; i < MAXFDCACHE; i++, tfd++) { /* look for empty slot */
113 if (!bestfd) { /* look for reclaimable slot */
115 for (i = 0; i < MAXFDCACHE; i++, tfd++) {
116 if (tfd->refCount == 0) {
122 if (bestfd) { /* found a usable slot */
127 tfd->refCount = 1; /* us */
131 /* finally, we're done */
135 /* close the file, maintaining ref count in cache structure */
137 uphys_close(register int afd)
140 register struct fdcache *tfd;
145 for (i = 0; i < MAXFDCACHE; i++, tfd++) {
146 if (tfd->fd == afd) {
155 uphys_stat(struct ubik_dbase *adbase, afs_int32 afid, struct ubik_stat *astat)
159 register afs_int32 code;
161 fd = uphys_open(adbase, afid);
164 code = fstat(fd, &tstat);
169 astat->mtime = tstat.st_mtime;
170 code = tstat.st_size - HDRSIZE;
179 uphys_read(register struct ubik_dbase *adbase, afs_int32 afile,
180 register char *abuffer, afs_int32 apos, afs_int32 alength)
183 register afs_int32 code;
185 fd = uphys_open(adbase, afile);
188 code = lseek(fd, apos + HDRSIZE, 0);
193 code = read(fd, abuffer, alength);
199 uphys_write(register struct ubik_dbase *adbase, afs_int32 afile,
200 register char *abuffer, afs_int32 apos, afs_int32 alength)
203 register afs_int32 code;
206 fd = uphys_open(adbase, afile);
209 code = lseek(fd, apos + HDRSIZE, 0);
214 length = write(fd, abuffer, alength);
215 code = uphys_close(fd);
223 uphys_truncate(register struct ubik_dbase *adbase, afs_int32 afile,
226 register afs_int32 code, fd;
227 fd = uphys_open(adbase, afile);
230 code = ftruncate(fd, asize + HDRSIZE);
235 /* get number of dbase files */
237 uphys_getnfiles(register struct ubik_dbase *adbase)
239 /* really should scan dir for data */
243 /* get database label, with aversion in host order */
245 uphys_getlabel(register struct ubik_dbase *adbase, afs_int32 afile,
246 struct ubik_version *aversion)
248 struct ubik_hdr thdr;
249 register afs_int32 code, fd;
251 fd = uphys_open(adbase, afile);
254 code = read(fd, &thdr, sizeof(thdr));
255 if (code != sizeof(thdr)) {
259 aversion->epoch = ntohl(thdr.version.epoch);
260 aversion->counter = ntohl(thdr.version.counter);
265 /* label database, with aversion in host order */
267 uphys_setlabel(register struct ubik_dbase *adbase, afs_int32 afile,
268 struct ubik_version *aversion)
270 struct ubik_hdr thdr;
271 register afs_int32 code, fd;
273 fd = uphys_open(adbase, afile);
276 thdr.version.epoch = htonl(aversion->epoch);
277 thdr.version.counter = htonl(aversion->counter);
278 thdr.magic = htonl(UBIK_MAGIC);
279 thdr.size = htonl(HDRSIZE);
280 code = write(fd, &thdr, sizeof(thdr));
281 fsync(fd); /* preserve over crash */
283 if (code != sizeof(thdr)) {
290 uphys_sync(register struct ubik_dbase *adbase, afs_int32 afile)
292 register afs_int32 code, fd;
293 fd = uphys_open(adbase, afile);