int afscp_GetStatus(const struct afscp_venusfid *fid, struct AFSFetchStatus *s) { struct afscp_volume *v; struct afscp_server *server; struct AFSCallBack cb; struct AFSVolSync vs; struct AFSFid tf = fid->fid; struct afscp_statent *stored, key; void *cached; int code, i, j; time_t now; v = afscp_VolumeById(fid->cell, fid->fid.Volume); if (v == NULL) { return -1; } memset(&key, 0, sizeof(key)); memcpy(&key.me, fid, sizeof(*fid)); cached = tfind(&key, &v->statcache, statcompare); if (cached != NULL) { stored = *(struct afscp_statent **)cached; pthread_mutex_lock(&(stored->mtx)); memmove(s, &stored->status, sizeof(*s)); afs_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n", fid->cell->id, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique)); if (stored->nwaiters) pthread_cond_broadcast(&(stored->cv)); pthread_mutex_unlock(&(stored->mtx)); return 0; } code = ENOENT; for (i = 0; i < v->nservers; i++) { server = afscp_ServerByIndex(v->servers[i]); if (server && server->naddrs > 0) { for (j = 0; j < server->naddrs; j++) { time(&now); code = RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs); if (code == 0) { afscp_AddCallBack(server, &fid->fid, s, &cb, now); /* calls _StatStuff */ afs_dprintf(("Stat %d.%lu.%lu.%lu" " ok: type %ld size %ld\n", fid->cell->id, afs_printable_uint32_lu(fid->fid.Volume), afs_printable_uint32_lu(fid->fid.Vnode), afs_printable_uint32_lu(fid->fid.Unique), afs_printable_int32_ld(s->FileType), afs_printable_int32_ld(s->Length))); return 0; } } } } afscp_errno = code; return -1; }
int afscp_CreateFile(const struct afscp_venusfid *dir, char *name, struct AFSStoreStatus *sst, struct afscp_venusfid **ret) { int code, i, j; struct AFSFid df = dir->fid; struct afscp_volume *vol; struct AFSFetchStatus dfst, fst; struct AFSVolSync vs; struct AFSCallBack cb; struct AFSFid ff; struct afscp_server *server; struct rx_connection *c; time_t now; if (dir == NULL || name == NULL || sst == NULL) { fprintf(stderr, "afscp_CreateFile called with NULL args, cannot continue\n"); return -1; } vol = afscp_VolumeById(dir->cell, dir->fid.Volume); if (vol == NULL) { afscp_errno = ENOENT; return -1; } code = ENOENT; for (i = 0; i < vol->nservers; i++) { server = afscp_ServerByIndex(vol->servers[i]); if (server && server->naddrs > 0) { for (j = 0; j < server->naddrs; j++) { c = afscp_ServerConnection(server, j); if (c == NULL) { break; } time(&now); code = RXAFS_CreateFile(c, &df, name, sst, &ff, &fst, &dfst, &cb, &vs); if (code >= 0) { break; } } } if (code >= 0) { break; } } if (code != 0) { _StatInvalidate(dir); afscp_errno = code; return -1; } _StatStuff(dir, &dfst); afscp_AddCallBack(server, &ff, &fst, &cb, now); if (ret != NULL) *ret = afscp_MakeFid(vol->cell, ff.Volume, ff.Vnode, ff.Unique); return 0; }
/* this is not yet 64-bit clean */ ssize_t afscp_PRead(const struct afscp_venusfid * fid, void *buffer, size_t count, off_t offset) { struct AFSFetchStatus fst; struct AFSVolSync vs; struct AFSCallBack cb; struct AFSFid tf = fid->fid; struct afscp_volume *vol; struct afscp_server *server; struct rx_call *c = NULL; int code, code2 = 0; int i, j, bytes, totalbytes = 0; int bytesremaining; char *p; time_t now; vol = afscp_VolumeById(fid->cell, fid->fid.Volume); if (vol == NULL) { afscp_errno = ENOENT; return -1; } code = ENOENT; for (i = 0; i < vol->nservers; i++) { server = afscp_ServerByIndex(vol->servers[i]); if (server && server->naddrs > 0) { for (j = 0; j < server->naddrs; j++) { c = rx_NewCall(server->conns[j]); if (c != 0) { p = buffer; code = StartRXAFS_FetchData(c, &tf, offset, count); if (code != 0) { code = rx_EndCall(c, code); continue; } bytes = rx_Read(c, (char *)&bytesremaining, sizeof(afs_int32)); if (bytes != sizeof(afs_int32)) { code = rx_EndCall(c, bytes); continue; } bytesremaining = ntohl(bytesremaining); totalbytes = 0; while (bytesremaining > 0) { bytes = rx_Read(c, p, bytesremaining); if (bytes <= 0) break; p += bytes; totalbytes += bytes; bytesremaining -= bytes; } if (bytesremaining == 0) { time(&now); code2 = EndRXAFS_FetchData(c, &fst, &cb, &vs); if (code2 == 0) afscp_AddCallBack(server, &fid->fid, &fst, &cb, now); } code = rx_EndCall(c, code2); } if (code == 0) { return totalbytes; } } } } afscp_errno = code; return -1; }