/* * Remove a temporary symlink entry from /afs. */ int afs_DynrootVOPRemove(struct vcache *avc, afs_ucred_t *acred, char *aname) { struct afs_dynSymlink **tpps; struct afs_dynSymlink *tps; int found = 0; #if defined(AFS_SUN510_ENV) if (crgetruid(acred)) #else if (afs_cr_uid(acred)) #endif return EPERM; ObtainWriteLock(&afs_dynSymlinkLock, 97); tpps = &afs_dynSymlinkBase; while (*tpps) { tps = *tpps; if (afs_strcasecmp(aname, tps->name) == 0) { afs_osi_Free(tps->name, strlen(tps->name) + 1); afs_osi_Free(tps->target, strlen(tps->target) + 1); *tpps = tps->next; afs_osi_Free(tps, sizeof(*tps)); afs_dynSymlinkIndex++; found = 1; break; } tpps = &(tps->next); } ReleaseWriteLock(&afs_dynSymlinkLock); if (found) { afs_DynrootInvalidate(); return 0; } if (afs_CellOrAliasExists(aname)) return EROFS; else return ENOENT; }
/* * Create a temporary symlink entry in /afs. */ int afs_DynrootVOPSymlink(struct vcache *avc, afs_ucred_t *acred, char *aname, char *atargetName) { struct afs_dynSymlink *tps; if (afs_cr_uid(acred)) return EPERM; if (afs_CellOrAliasExists(aname)) return EEXIST; /* Check if it's already a symlink */ ObtainWriteLock(&afs_dynSymlinkLock, 91); tps = afs_dynSymlinkBase; while (tps) { if (afs_strcasecmp(aname, tps->name) == 0) { ReleaseWriteLock(&afs_dynSymlinkLock); return EEXIST; } tps = tps->next; } /* Doesn't already exist -- go ahead and create it */ tps = afs_osi_Alloc(sizeof(*tps)); tps->index = afs_dynSymlinkIndex++; tps->next = afs_dynSymlinkBase; tps->name = afs_osi_Alloc(strlen(aname) + 1); strcpy(tps->name, aname); tps->target = afs_osi_Alloc(strlen(atargetName) + 1); strcpy(tps->target, atargetName); afs_dynSymlinkBase = tps; ReleaseWriteLock(&afs_dynSymlinkLock); afs_DynrootInvalidate(); return 0; }
/*! * \brief Entry point for user-space AFSDB request handler. * Reads cell data from kerlenMsg and add new cell, or alias. * \param acellName Cell name. If a cell is found, it's name will be filled in here. * \param acellNameLen Cell name length. * \param kernelMsg Buffer containing data about host count, time out, and cell hosts ids. * \return 0 for success, < 0 for error. */ int afs_AFSDBHandler(char *acellName, int acellNameLen, afs_int32 * kernelMsg) { afs_int32 timeout, code; afs_int32 cellHosts[AFS_MAXCELLHOSTS]; if (afsdb_handler_shutdown) return -2; afsdb_handler_running = 1; ObtainSharedLock(&afsdb_req_lock, 683); if (afsdb_req.pending) { int i, hostCount; UpgradeSToWLock(&afsdb_req_lock, 684); hostCount = kernelMsg[0]; timeout = kernelMsg[1]; if (timeout) timeout += osi_Time(); for (i = 0; i < AFS_MAXCELLHOSTS; i++) { if (i >= hostCount) cellHosts[i] = 0; else cellHosts[i] = kernelMsg[2 + i]; } if (hostCount) code = afs_NewCell(acellName, cellHosts, CNoSUID, NULL, 0, 0, timeout); if (!hostCount || (code && code != EEXIST)) /* null out the cellname if the lookup failed */ afsdb_req.cellname = NULL; else /* If we found an alias, create it */ if (afs_strcasecmp(afsdb_req.cellname, acellName)) afs_NewCellAlias(afsdb_req.cellname, acellName); /* Request completed, wake up the relevant thread */ afsdb_req.pending = 0; afsdb_req.complete = 1; afs_osi_Wakeup(&afsdb_req); ConvertWToSLock(&afsdb_req_lock); } ConvertSToRLock(&afsdb_req_lock); /* Wait for a request */ while (afsdb_req.pending == 0 && afs_termState != AFSOP_STOP_AFSDB) { ReleaseReadLock(&afsdb_req_lock); afs_osi_Sleep(&afsdb_req); ObtainReadLock(&afsdb_req_lock); } /* Check if we're shutting down */ if (afs_termState == AFSOP_STOP_AFSDB) { ReleaseReadLock(&afsdb_req_lock); /* Inform anyone waiting for us that we're going away */ afsdb_handler_shutdown = 1; afsdb_handler_running = 0; afs_osi_Wakeup(&afsdb_req); afs_termState = AFSOP_STOP_RXEVENT; afs_osi_Wakeup(&afs_termState); return -2; } /* Return the lookup request to userspace */ strncpy(acellName, afsdb_req.cellname, acellNameLen); ReleaseReadLock(&afsdb_req_lock); return 0; }