Exemplo n.º 1
0
int
SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
		       char **a_name, serverList * a_hosts)
{
    afs_int32 i, j = 0;
    struct cell *tcell;
    char *t_name, *p_name = NULL;

    RX_AFS_GLOCK();
    AFS_STATCNT(SRXAFSCB_GetCellServDB);

    tcell = afs_GetCellByIndex(a_index, READ_LOCK);

    if (!tcell) {
	i = 0;
	a_hosts->serverList_val = 0;
	a_hosts->serverList_len = 0;
    } else {
	p_name = tcell->cellName;
	for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++);
	i = strlen(p_name);
	a_hosts->serverList_val = afs_osi_Alloc(j * sizeof(afs_int32));
	osi_Assert(a_hosts->serverList_val != NULL);
	a_hosts->serverList_len = j;
	for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++)
	    a_hosts->serverList_val[j] =
		ntohl(tcell->cellHosts[j]->addr->sa_ip);
	afs_PutCell(tcell, READ_LOCK);
    }

    t_name = afs_osi_Alloc(i + 1);
    if (t_name == NULL) {
	afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
	RX_AFS_GUNLOCK();
	return ENOMEM;
    }

    t_name[i] = '\0';
    if (p_name)
	memcpy(t_name, p_name, i);

    RX_AFS_GUNLOCK();

    *a_name = t_name;
    return 0;
}
Exemplo n.º 2
0
/*
 * 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;
}
Exemplo n.º 3
0
/*
 * 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);
}
Exemplo n.º 4
0
static int afs_encode_fh(struct dentry *de, __u32 *fh, int *max_len,
			 int connectable)
{
    struct vcache *tvc;
    struct cell *tc;
    int vntype;

    if (!de->d_inode) /* encode a negative dentry?! */
	return 255;
    if (*max_len < 4)  /* not enough space */
	return 255;

    tvc = VTOAFS(de->d_inode);

#ifdef OSI_EXPORT_DEBUG
    printk("afs: encode_fh(0x%08x/%d/%d.%d)\n",
	   tvc->f.fid.Cell,      tvc->f.fid.Fid.Volume,
	   tvc->f.fid.Fid.Vnode, tvc->f.fid.Fid.Unique);
#endif
    if (afs_IsDynrootAnyFid(&tvc->f.fid)) {
	vntype = VNUM_TO_VNTYPE(tvc->f.fid.Fid.Vnode);
	switch (vntype) {
	    case 0:
		/* encode as a normal filehandle */
		break;

	    case VN_TYPE_MOUNT:
		if (*max_len < 5) {
		    return 255;
		}
		/* fall through */

	    case VN_TYPE_CELL:
	    case VN_TYPE_ALIAS:
		AFS_GLOCK();
		tc = afs_GetCellByIndex(VNUM_TO_CIDX(tvc->f.fid.Fid.Vnode),
					READ_LOCK);
		if (!tc) {
		    AFS_GUNLOCK();
		    return 255;
		}
		memcpy((void *)fh, tc->cellHandle, 16);
		afs_PutCell(tc, READ_LOCK);
		AFS_GUNLOCK();
		if (vntype == VN_TYPE_MOUNT) {
		    fh[4] = htonl(tvc->f.fid.Fid.Unique);
		    *max_len = 5;
		    return AFSFH_DYN_MOUNT;
		}
		*max_len = 4;
		if (vntype == VN_TYPE_CELL) {
		    return AFSFH_DYN_RO_CELL | VNUM_TO_RW(tvc->f.fid.Fid.Vnode);
		} else {
		    return AFSFH_DYN_RO_LINK | VNUM_TO_RW(tvc->f.fid.Fid.Vnode);
		}

	    case VN_TYPE_SYMLINK:
		/* XXX fill in filehandle for dynroot symlink */
		/* XXX return AFSFH_DYN_SYMLINK; */

	    default:
		return 255;
	}
    }

    if (*max_len < 7) {
	/* not big enough for a migratable filehandle */
	/* always encode in network order */
	fh[0] = htonl(tvc->f.fid.Cell);
	fh[1] = htonl(tvc->f.fid.Fid.Volume);
	fh[2] = htonl(tvc->f.fid.Fid.Vnode);
	fh[3] = htonl(tvc->f.fid.Fid.Unique);
	*max_len = 4;
	return AFSFH_NET_VENUSFID;
    }

    AFS_GLOCK();
    tc = afs_GetCell(tvc->f.fid.Cell, READ_LOCK);
    if (!tc) {
	AFS_GUNLOCK();
	return 255;
    }
    memcpy((void *)fh, tc->cellHandle, 16);
    afs_PutCell(tc, READ_LOCK);
    AFS_GUNLOCK();
    /* always encode in network order */
    fh[4] = htonl(tvc->f.fid.Fid.Volume);
    fh[5] = htonl(tvc->f.fid.Fid.Vnode);
    fh[6] = htonl(tvc->f.fid.Fid.Unique);

    *max_len = 7;
    return AFSFH_NET_CELLFID;
}
Exemplo n.º 5
0
int
SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
		 struct AFSDBLock *a_result)
{
    struct ltable *tl;		/*Ptr to lock table entry */
    int nentries;		/*Num entries in table */
    int code;			/*Return code */
    XSTATS_DECLS;

    RX_AFS_GLOCK();

    XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);

    AFS_STATCNT(SRXAFSCB_GetLock);
    nentries = sizeof(ltable) / sizeof(struct ltable);
    if (a_index < 0 || a_index >= nentries+afs_cellindex) {
	/*
	 * Past EOF
	 */
	code = 1;
    } else if (a_index >= nentries) {
	struct cell *tc = afs_GetCellByIndex(a_index-nentries, 0);
	strcpy(a_result->name, tc->cellName);
	a_result->lock.waitStates =
	    ((struct afs_lock *)&(tc->lock))->wait_states;
	a_result->lock.exclLocked =
	    ((struct afs_lock *)&(tc->lock))->excl_locked;
	a_result->lock.readersReading =
	    ((struct afs_lock *)&(tc->lock))->readers_reading;
	a_result->lock.numWaiting =
	    ((struct afs_lock *)&(tc->lock))->num_waiting;
#ifdef INSTRUMENT_LOCKS
	a_result->lock.pid_last_reader =
	    MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_last_reader);
	a_result->lock.pid_writer =
	    MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_writer);
	a_result->lock.src_indicator =
	    ((struct afs_lock *)&(tc->lock))->src_indicator;
#else
	a_result->lock.pid_last_reader = 0;
	a_result->lock.pid_writer = 0;
	a_result->lock.src_indicator = 0;
#endif
	code = 0;
    } else {
	/*
	 * Found it - copy out its contents.
	 */
	tl = &ltable[a_index];
	strcpy(a_result->name, tl->name);
	a_result->lock.waitStates =
	    ((struct afs_lock *)(tl->addr))->wait_states;
	a_result->lock.exclLocked =
	    ((struct afs_lock *)(tl->addr))->excl_locked;
	a_result->lock.readersReading =
	    ((struct afs_lock *)(tl->addr))->readers_reading;
	a_result->lock.numWaiting =
	    ((struct afs_lock *)(tl->addr))->num_waiting;
#ifdef INSTRUMENT_LOCKS
	a_result->lock.pid_last_reader =
	    MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_last_reader);
	a_result->lock.pid_writer =
	    MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_writer);
	a_result->lock.src_indicator =
	    ((struct afs_lock *)(tl->addr))->src_indicator;
#else
	a_result->lock.pid_last_reader = 0;
	a_result->lock.pid_writer = 0;
	a_result->lock.src_indicator = 0;
#endif
	code = 0;
    }

    XSTATS_END_TIME;

    RX_AFS_GUNLOCK();

    return (code);

}				/*SRXAFSCB_GetLock */