コード例 #1
0
ファイル: afs_cell.c プロジェクト: SimonWilkinson/openafs
/*!
 * Check if the given name exists as a cell or alias. Does not lock afs_xcell.
 * \param aname
 * \return
 */
static int
afs_CellOrAliasExists_nl(char *aname)
{
    struct cell *c;
    struct cell_alias *ca;

    c = afs_FindCellByName_nl(aname, READ_LOCK);
    if (c) {
	afs_PutCell(c, READ_LOCK);
	return 1;
    }

    ca = afs_FindCellAlias(aname);
    if (ca) {
	afs_PutCellAlias(ca);
	return 1;
    }

    return 0;
}
コード例 #2
0
ファイル: afs_dynroot.c プロジェクト: stevenjenkins/openafs
/*
 * Inform dynroot that a new vnode is being created.  Return value
 * is non-zero if this vnode is handled by dynroot, in which case
 * FetchStatus will be filled in.
 */
int
afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
{
    char *bp, tbuf[CVBS];

    if (_afs_IsDynrootFid(&avc->f.fid)) {
	if (!afs_dynrootEnable)
	    return 0;
	afs_GetDynroot(0, 0, status);
	afs_PutDynroot();
	return 1;
    }

    if (afs_IsDynrootMount(avc)) {
	afs_GetDynrootMount(0, 0, status);
	afs_PutDynroot();
	return 1;
    }

    /*
     * Check if this is an entry under /afs, e.g. /afs/cellname.
     */
    if (avc->f.fid.Cell == afs_dynrootCell
	&& avc->f.fid.Fid.Volume == AFS_DYNROOT_VOLUME) {

	struct cell *c;
	struct cell_alias *ca;
	int namelen, linklen, cellidx, rw;

	memset(status, 0, sizeof(struct AFSFetchStatus));

	status->FileType = SymbolicLink;
	status->LinkCount = 1;
	status->DataVersion = 1;
	status->CallerAccess = PRSFS_LOOKUP | PRSFS_READ;
	status->AnonymousAccess = PRSFS_LOOKUP | PRSFS_READ;
	status->ParentVnode = 1;
	status->ParentUnique = 1;

	if (VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) == VN_TYPE_SYMLINK) {
	    struct afs_dynSymlink *ts;
	    int index = VNUM_TO_VNID(avc->f.fid.Fid.Vnode);

	    ObtainReadLock(&afs_dynSymlinkLock);
	    ts = afs_dynSymlinkBase;
	    while (ts) {
		if (ts->index == index)
		    break;
		ts = ts->next;
	    }

	    if (ts) {
		linklen = strlen(ts->target);
		avc->linkData = afs_osi_Alloc(linklen + 1);
		strcpy(avc->linkData, ts->target);

		status->Length = linklen;
		status->UnixModeBits = 0755;
	    }
	    ReleaseReadLock(&afs_dynSymlinkLock);

	    return ts ? 1 : 0;
	}

	if (VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) != VN_TYPE_CELL
	    && VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) != VN_TYPE_ALIAS
	    && VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) != VN_TYPE_MOUNT) {
	    afs_warn("dynroot vnode inconsistency, unknown VNTYPE %d\n",
		     VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode));
	    return 0;
	}

	cellidx = VNUM_TO_CIDX(avc->f.fid.Fid.Vnode);
	rw = VNUM_TO_RW(avc->f.fid.Fid.Vnode);

	if (VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) == VN_TYPE_ALIAS) {
	    char *realName;

	    ca = afs_GetCellAlias(cellidx);
	    if (!ca) {
		afs_warn("dynroot vnode inconsistency, can't find alias %d\n",
			 cellidx);
		return 0;
	    }

	    /*
	     * linkData needs to contain the name of the cell
	     * we're aliasing for.
	     */
	    realName = ca->cell;
	    if (!realName) {
		afs_warn("dynroot: alias %s missing real cell name\n",
			 ca->alias);
		avc->linkData = afs_strdup("unknown");
		linklen = 7;
	    } else {
		int namelen = strlen(realName);
		linklen = rw + namelen;
		avc->linkData = afs_osi_Alloc(linklen + 1);
		strcpy(avc->linkData, rw ? "." : "");
		afs_strcat(avc->linkData, realName);
	    }

	    status->UnixModeBits = 0755;
	    afs_PutCellAlias(ca);

	} else if (VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) == VN_TYPE_MOUNT) {
	    c = afs_GetCellByIndex(cellidx, READ_LOCK);
	    if (!c) {
		afs_warn("dynroot vnode inconsistency, can't find cell %d\n",
			 cellidx);
		return 0;
	    }

	    /*
	     * linkData needs to contain "%cell:volumeid"
	     */
	    namelen = strlen(c->cellName);
	    bp = afs_cv2string(&tbuf[CVBS], avc->f.fid.Fid.Unique);
	    linklen = 2 + namelen + strlen(bp);
	    avc->linkData = afs_osi_Alloc(linklen + 1);
	    strcpy(avc->linkData, "%");
	    afs_strcat(avc->linkData, c->cellName);
	    afs_strcat(avc->linkData, ":");
	    afs_strcat(avc->linkData, bp);

	    status->UnixModeBits = 0644;
	    status->ParentVnode = AFS_DYNROOT_MOUNT_VNODE;
	    afs_PutCell(c, READ_LOCK);

	} else {
	    c = afs_GetCellByIndex(cellidx, READ_LOCK);
	    if (!c) {
		afs_warn("dynroot vnode inconsistency, can't find cell %d\n",
			 cellidx);
		return 0;
	    }

	    /*
	     * linkData needs to contain "#cell:root.cell" or "%cell:root.cell"
	     */
	    namelen = strlen(c->cellName);
	    linklen = 1 + namelen + 10;
	    avc->linkData = afs_osi_Alloc(linklen + 1);
	    strcpy(avc->linkData, rw ? "%" : "#");
	    afs_strcat(avc->linkData, c->cellName);
	    afs_strcat(avc->linkData, ":root.cell");

	    status->UnixModeBits = 0644;
	    afs_PutCell(c, READ_LOCK);
	}

	status->Length = linklen;
	return 1;
    }

    return 0;
}
コード例 #3
0
ファイル: afs_dynroot.c プロジェクト: stevenjenkins/openafs
/*
 * Regenerates the dynroot contents from the current list of
 * cells.  Useful when the list of cells has changed due to
 * an AFSDB lookup, for instance.
 */
static void
afs_RebuildDynroot(void)
{
    int cellidx, maxcellidx, i;
    int aliasidx, maxaliasidx;
    struct cell *c;
    struct cell_alias *ca;
    int curChunk, curPage;
    int dirSize, dotLen;
    char *newDir, *dotCell;
    struct DirHeader *dirHeader;
    int linkCount = 0;
    struct afs_dynSymlink *ts;
    int newVersion;

    ObtainReadLock(&afs_dynrootDirLock);
    newVersion = afs_dynrootVersion;
    ReleaseReadLock(&afs_dynrootDirLock);

    /*
     * Compute the amount of space we need for the fake dir
     */
    curChunk = 13;
    curPage = 0;

    /* Reserve space for "." and ".." */
    curChunk += 2;

    /* Reserve space for the dynamic-mount directory */
    afs_dynroot_computeDirEnt(AFS_DYNROOT_MOUNTNAME, &curPage, &curChunk);

    for (cellidx = 0;; cellidx++) {
	c = afs_GetCellByIndex(cellidx, READ_LOCK);
	if (!c)
	    break;
	if (c->cellNum == afs_dynrootCell)
	    continue;

	dotLen = strlen(c->cellName) + 2;
	dotCell = afs_osi_Alloc(dotLen);
	strcpy(dotCell, ".");
	afs_strcat(dotCell, c->cellName);

	afs_dynroot_computeDirEnt(c->cellName, &curPage, &curChunk);
	afs_dynroot_computeDirEnt(dotCell, &curPage, &curChunk);

	afs_osi_Free(dotCell, dotLen);
	afs_PutCell(c, READ_LOCK);
    }
    maxcellidx = cellidx;

    for (aliasidx = 0;; aliasidx++) {
	ca = afs_GetCellAlias(aliasidx);
	if (!ca)
	    break;

	dotLen = strlen(ca->alias) + 2;
	dotCell = afs_osi_Alloc(dotLen);
	strcpy(dotCell, ".");
	afs_strcat(dotCell, ca->alias);

	afs_dynroot_computeDirEnt(ca->alias, &curPage, &curChunk);
	afs_dynroot_computeDirEnt(dotCell, &curPage, &curChunk);

	afs_osi_Free(dotCell, dotLen);
	afs_PutCellAlias(ca);
    }
    maxaliasidx = aliasidx;

    ObtainReadLock(&afs_dynSymlinkLock);
    ts = afs_dynSymlinkBase;
    while (ts) {
	afs_dynroot_computeDirEnt(ts->name, &curPage, &curChunk);
	ts = ts->next;
    }

    dirSize = (curPage + 1) * AFS_PAGESIZE;
    newDir = afs_osi_Alloc(dirSize);

    /*
     * Now actually construct the directory.
     */
    curChunk = 13;
    curPage = 0;
    dirHeader = (struct DirHeader *)newDir;

    dirHeader->header.pgcount = 0;
    dirHeader->header.tag = htons(1234);
    dirHeader->header.freecount = 0;

    dirHeader->header.freebitmap[0] = 0xff;
    dirHeader->header.freebitmap[1] = 0x1f;
    for (i = 2; i < EPP / 8; i++)
	dirHeader->header.freebitmap[i] = 0;
    dirHeader->alloMap[0] = EPP - DHE - 1;
    for (i = 1; i < MAXPAGES; i++)
	dirHeader->alloMap[i] = EPP;
    for (i = 0; i < NHASHENT; i++)
	dirHeader->hashTable[i] = 0;

    /* Install ".", "..", and the dynamic mount directory */
    afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, ".", 1);
    afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, "..", 1);
    afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
			  AFS_DYNROOT_MOUNTNAME, AFS_DYNROOT_MOUNT_VNODE);
    linkCount += 3;

    for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
	c = afs_GetCellByIndex(cellidx, READ_LOCK);
	if (!c)
	    continue;
	if (c->cellNum == afs_dynrootCell)
	    continue;

	dotLen = strlen(c->cellName) + 2;
	dotCell = afs_osi_Alloc(dotLen);
	strcpy(dotCell, ".");
	afs_strcat(dotCell, c->cellName);
	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, c->cellName,
			      VNUM_FROM_CIDX_RW(cellidx, 0));
	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, dotCell,
			      VNUM_FROM_CIDX_RW(cellidx, 1));
	afs_osi_Free(dotCell, dotLen);

	linkCount += 2;
	afs_PutCell(c, READ_LOCK);
    }

    for (aliasidx = 0; aliasidx < maxaliasidx; aliasidx++) {
	ca = afs_GetCellAlias(aliasidx);
	if (!ca)
	    continue;

	dotLen = strlen(ca->alias) + 2;
	dotCell = afs_osi_Alloc(dotLen);
	strcpy(dotCell, ".");
	afs_strcat(dotCell, ca->alias);
	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, ca->alias,
			      VNUM_FROM_CAIDX_RW(aliasidx, 0));
	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, dotCell,
			      VNUM_FROM_CAIDX_RW(aliasidx, 1));
	afs_osi_Free(dotCell, dotLen);
	afs_PutCellAlias(ca);
    }

    ts = afs_dynSymlinkBase;
    while (ts) {
	int vnum = VNUM_FROM_TYPEID(VN_TYPE_SYMLINK, ts->index);
	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, ts->name, vnum);
	ts = ts->next;
    }

    ReleaseReadLock(&afs_dynSymlinkLock);

    ObtainWriteLock(&afs_dynrootDirLock, 549);
    if (afs_dynrootDir)
	afs_osi_Free(afs_dynrootDir, afs_dynrootDirLen);
    afs_dynrootDir = newDir;
    afs_dynrootDirLen = dirSize;
    afs_dynrootDirLinkcnt = linkCount;
    afs_dynrootDirVersion = newVersion;
    ReleaseWriteLock(&afs_dynrootDirLock);
}