Пример #1
0
/*!
 * 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;
}
Пример #2
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 */
Пример #3
0
/** 
 * 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 */