/*! * Write in-kernel list of cells to disk. */ int afs_cellname_write(void) { struct osi_file *tfile; struct cell_name *cn; int off; if (!afs_cellname_dirty || !afs_cellname_inode_set) return 0; if (afs_initState != 300) return 0; ObtainWriteLock(&afs_xcell, 693); afs_cellname_dirty = 0; off = 0; tfile = osi_UFSOpen(&afs_cellname_inode); if (!tfile) { ReleaseWriteLock(&afs_xcell); return EIO; } for (cn = afs_cellname_head; cn; cn = cn->next) { afs_int32 magic, cellnum, clen; int cc; if (!cn->used) continue; magic = AFS_CELLINFO_MAGIC; cc = afs_osi_Write(tfile, off, &magic, sizeof(magic)); if (cc != sizeof(magic)) break; off += cc; cellnum = cn->cellnum; cc = afs_osi_Write(tfile, off, &cellnum, sizeof(cellnum)); if (cc != sizeof(cellnum)) break; off += cc; clen = strlen(cn->cellname); cc = afs_osi_Write(tfile, off, &clen, sizeof(clen)); if (cc != sizeof(clen)) break; off += cc; cc = afs_osi_Write(tfile, off, cn->cellname, clen); if (cc != clen) break; off += clen; } osi_UFSClose(tfile); ReleaseWriteLock(&afs_xcell); return 0; }
/** * UFS specific version of afs_GetVolSlot * @return */ struct volume * afs_UFSGetVolSlot(void) { struct volume *tv = NULL, **lv; struct osi_file *tfile; afs_int32 i = -1, code; afs_int32 bestTime; struct volume *bestVp, *oldLp = NULL, **bestLp = NULL; char *oldname = NULL; afs_int32 oldvtix = -2; /* Initialize to a value that doesn't occur */ AFS_STATCNT(afs_UFSGetVolSlot); if (!afs_freeVolList) { /* get free slot */ bestTime = 0x7fffffff; bestVp = 0; bestLp = 0; for (i = 0; i < NVOLS; i++) { lv = &afs_volumes[i]; for (tv = *lv; tv; lv = &tv->next, tv = *lv) { if (tv->refCount == 0) { /* is this one available? */ if (tv->accessTime < bestTime) { /* best one available? */ bestTime = tv->accessTime; bestLp = lv; bestVp = tv; } } } } if (!bestVp) { afs_warn("afs_UFSGetVolSlot: no vol slots available\n"); goto error; } tv = bestVp; oldLp = *bestLp; *bestLp = tv->next; oldname = tv->name; tv->name = NULL; oldvtix = tv->vtix; /* now write out volume structure to file */ if (tv->vtix < 0) { tv->vtix = afs_volCounter++; /* now put on hash chain */ i = FVHash(tv->cell, tv->volume); staticFVolume.next = fvTable[i]; fvTable[i] = tv->vtix; } else { /* * Haul the guy in from disk so we don't overwrite hash table * next chain */ if (afs_FVIndex != tv->vtix) { tfile = osi_UFSOpen(&volumeInode); code = afs_osi_Read(tfile, sizeof(struct fvolume) * tv->vtix, &staticFVolume, sizeof(struct fvolume)); osi_UFSClose(tfile); if (code != sizeof(struct fvolume)) { afs_warn("afs_UFSGetVolSlot: error %d reading volumeinfo\n", (int)code); goto error; } afs_FVIndex = tv->vtix; } } afs_FVIndex = tv->vtix; staticFVolume.volume = tv->volume; staticFVolume.cell = tv->cell; staticFVolume.mtpoint = tv->mtpoint; staticFVolume.dotdot = tv->dotdot; staticFVolume.rootVnode = tv->rootVnode; staticFVolume.rootUnique = tv->rootUnique; tfile = osi_UFSOpen(&volumeInode); code = afs_osi_Write(tfile, sizeof(struct fvolume) * afs_FVIndex, &staticFVolume, sizeof(struct fvolume)); osi_UFSClose(tfile); if (code != sizeof(struct fvolume)) { afs_warn("afs_UFSGetVolSlot: error %d writing volumeinfo\n", (int)code); goto error; } if (oldname) { afs_osi_Free(oldname, strlen(oldname) + 1); oldname = NULL; } } else { tv = afs_freeVolList; afs_freeVolList = tv->next; } return tv; error: if (tv) { if (oldvtix == -2) { afs_warn("afs_UFSGetVolSlot: oldvtix is uninitialized\n"); return NULL; } if (oldname) { tv->name = oldname; oldname = NULL; } if (oldvtix < 0) { afs_volCounter--; fvTable[i] = staticFVolume.next; } if (bestLp) { *bestLp = oldLp; } tv->vtix = oldvtix; /* we messed with staticFVolume, so make sure someone else * doesn't think it's fine to use */ afs_FVIndex = -1; } return NULL; } /*afs_UFSGetVolSlot */
/** * UFS specific version of afs_GetVolSlot * @return */ struct volume * afs_UFSGetVolSlot(void) { register struct volume *tv, **lv; struct osi_file *tfile; register afs_int32 i, code; afs_int32 bestTime; struct volume *bestVp, **bestLp; AFS_STATCNT(afs_UFSGetVolSlot); if (!afs_freeVolList) { /* get free slot */ bestTime = 0x7fffffff; bestVp = 0; bestLp = 0; for (i = 0; i < NVOLS; i++) { lv = &afs_volumes[i]; for (tv = *lv; tv; lv = &tv->next, tv = *lv) { if (tv->refCount == 0) { /* is this one available? */ if (tv->accessTime < bestTime) { /* best one available? */ bestTime = tv->accessTime; bestLp = lv; bestVp = tv; } } } } if (!bestVp) osi_Panic("getvolslot none"); tv = bestVp; *bestLp = tv->next; if (tv->name) afs_osi_Free(tv->name, strlen(tv->name) + 1); tv->name = NULL; /* now write out volume structure to file */ if (tv->vtix < 0) { tv->vtix = afs_volCounter++; /* now put on hash chain */ i = FVHash(tv->cell, tv->volume); staticFVolume.next = fvTable[i]; fvTable[i] = tv->vtix; } else { /* * Haul the guy in from disk so we don't overwrite hash table * next chain */ if (afs_FVIndex != tv->vtix) { #if defined(LINUX_USE_FH) tfile = osi_UFSOpen_fh(&volumeinfo_fh, volumeinfo_fh_type); #else tfile = osi_UFSOpen(volumeInode); #endif code = afs_osi_Read(tfile, sizeof(struct fvolume) * tv->vtix, &staticFVolume, sizeof(struct fvolume)); if (code != sizeof(struct fvolume)) osi_Panic("read volumeinfo"); osi_UFSClose(tfile); afs_FVIndex = tv->vtix; } } afs_FVIndex = tv->vtix; staticFVolume.volume = tv->volume; staticFVolume.cell = tv->cell; staticFVolume.mtpoint = tv->mtpoint; staticFVolume.dotdot = tv->dotdot; staticFVolume.rootVnode = tv->rootVnode; staticFVolume.rootUnique = tv->rootUnique; #if defined(LINUX_USE_FH) tfile = osi_UFSOpen_fh(&volumeinfo_fh, volumeinfo_fh_type); #else tfile = osi_UFSOpen(volumeInode); #endif code = afs_osi_Write(tfile, sizeof(struct fvolume) * afs_FVIndex, &staticFVolume, sizeof(struct fvolume)); if (code != sizeof(struct fvolume)) osi_Panic("write volumeinfo"); osi_UFSClose(tfile); } else { tv = afs_freeVolList; afs_freeVolList = tv->next; } return tv; } /*afs_UFSGetVolSlot */