/* 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; }
/* Cannot have static linkage--called from BPrefetch (afs_daemons) */ afs_int32 afs_PrefetchNoCache(struct vcache *avc, afs_ucred_t *acred, struct nocache_read_request *bparms) { struct uio *auio; #ifndef UKERNEL struct iovec *iovecp; #endif struct vrequest *areq; afs_int32 code = 0; struct rx_connection *rxconn; #ifdef AFS_64BIT_CLIENT afs_int32 length_hi, bytes, locked; #endif struct afs_conn *tc; struct rx_call *tcall; struct tlocal1 { struct AFSVolSync tsync; struct AFSFetchStatus OutStatus; struct AFSCallBack CallBack; }; struct tlocal1 *tcallspec; auio = bparms->auio; areq = bparms->areq; #ifndef UKERNEL iovecp = auio->uio_iov; #endif tcallspec = osi_Alloc(sizeof(struct tlocal1)); do { tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK /* ignored */, &rxconn); if (tc) { avc->callback = tc->parent->srvr->server; tcall = rx_NewCall(rxconn); #ifdef AFS_64BIT_CLIENT if (!afs_serverHasNo64Bit(tc)) { code = StartRXAFS_FetchData64(tcall, (struct AFSFid *) &avc->f.fid.Fid, auio->uio_offset, bparms->length); if (code == 0) { COND_GUNLOCK(locked); bytes = rx_Read(tcall, (char *)&length_hi, sizeof(afs_int32)); COND_RE_GLOCK(locked); if (bytes != sizeof(afs_int32)) { length_hi = 0; code = rx_Error(tcall); COND_GUNLOCK(locked); code = rx_EndCall(tcall, code); COND_RE_GLOCK(locked); tcall = NULL; } } } /* afs_serverHasNo64Bit */ if (code == RXGEN_OPCODE || afs_serverHasNo64Bit(tc)) { if (auio->uio_offset > 0x7FFFFFFF) { code = EFBIG; } else { afs_int32 pos; pos = auio->uio_offset; COND_GUNLOCK(locked); if (!tcall) tcall = rx_NewCall(rxconn); code = StartRXAFS_FetchData(tcall, (struct AFSFid *) &avc->f.fid.Fid, pos, bparms->length); COND_RE_GLOCK(locked); } afs_serverSetNo64Bit(tc); } #else code = StartRXAFS_FetchData(tcall, (struct AFSFid *) &avc->f.fid.Fid, auio->uio_offset, bparms->length); #endif if (code == 0) { code = afs_NoCacheFetchProc(tcall, avc, auio, 1 /* release_pages */, bparms->length); } else { afs_warn("BYPASS: StartRXAFS_FetchData failed: %d\n", code); unlock_and_release_pages(auio); goto done; } if (code == 0) { code = EndRXAFS_FetchData(tcall, &tcallspec->OutStatus, &tcallspec->CallBack, &tcallspec->tsync); } else { afs_warn("BYPASS: NoCacheFetchProc failed: %d\n", code); } code = rx_EndCall(tcall, code); } else { afs_warn("BYPASS: No connection.\n"); code = -1; unlock_and_release_pages(auio); goto done; } } while (afs_Analyze(tc, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_FETCHDATA, SHARED_LOCK,0)); done: /* * Copy appropriate fields into vcache */ if (!code) afs_ProcessFS(avc, &tcallspec->OutStatus, areq); osi_Free(areq, sizeof(struct vrequest)); osi_Free(tcallspec, sizeof(struct tlocal1)); osi_Free(bparms, sizeof(struct nocache_read_request)); #ifndef UKERNEL /* in UKERNEL, the "pages" are passed in */ osi_Free(iovecp, auio->uio_iovcnt * sizeof(struct iovec)); osi_Free(auio, sizeof(struct uio)); #endif return code; }
int main(int argc, char **argv) { char scell[MAXCELLCHARS], dcell[MAXCELLCHARS]; afs_uint32 ssrv, dsrv; char *databuffer, *srcf = NULL, *destd = NULL, *destf = NULL, *destpath = NULL; struct stat statbuf; struct AFSStoreStatus sst; struct AFSFetchStatus fst, dfst; struct AFSVolSync vs; struct AFSCallBack scb, dcb; struct AFSFid sf, dd, df; int filesz = 0; int ch, blksize, bytesremaining, bytes; struct timeval start, finish; struct timezone tz; struct rx_securityClass *ssc = 0, *dsc = 0; int sscindex, dscindex; struct rx_connection *sconn = NULL, *dconn = NULL; struct rx_call *scall = NULL, *dcall = NULL; int code = 0, fetchcode, storecode, printcallerrs = 0; int slcl = 0, dlcl = 0, unlock = 0; int sfd = 0, dfd = 0, unauth = 0; struct AFSCBFids theFids; struct AFSCBs theCBs; blksize = 8 * 1024; while ((ch = getopt(argc, argv, "iouUb:")) != -1) { switch (ch) { case 'b': blksize = atoi(optarg); break; case 'i': slcl = 1; break; case 'o': dlcl = 1; break; case 'u': unauth = 1; break; case 'U': unlock = 1; break; default: printf("Unknown option '%c'\n", ch); exit(1); } } if (argc - optind + unlock < 2) { fprintf(stderr, "Usage: afscp [-i|-o]] [-b xfersz] [-u] [-U] source [dest]\n"); fprintf(stderr, " -b Set block size\n"); fprintf(stderr, " -i Source is local (copy into AFS)\n"); fprintf(stderr, " -o Dest is local (copy out of AFS)\n"); fprintf(stderr, " -u Run unauthenticated\n"); fprintf(stderr, " -U Send an unlock request for source. (dest path not required)\n"); fprintf(stderr, "source and dest can be paths or specified as:\n"); fprintf(stderr, " @afs:cellname:servername:volume:vnode:uniq\n"); exit(1); } srcf = argv[optind++]; if (!unlock) { destpath = argv[optind++]; destd = strdup(destpath); if (!destd) { perror("strdup"); exit(1); } if ((destf = strrchr(destd, '/'))) { *destf++ = 0; } else { destf = destd; destd = "."; } } else if (slcl) { fprintf(stderr, "-i and -U cannot be used together\n"); } if (!slcl && statfile(srcf, scell, &ssrv, &sf)) { fprintf(stderr, "Cannot get attributes of %s\n", srcf); exit(1); } if (!unlock && !dlcl && statfile(destd, dcell, &dsrv, &dd)) { fprintf(stderr, "Cannot get attributes of %s\n", destd); exit(1); } if ((databuffer = malloc(blksize)) == NULL) { perror("malloc"); exit(1); } if (do_rx_Init()) exit(1); if (start_cb_server()) { printf("Cannot start callback service\n"); goto Fail_rx; } if (!slcl) { sscindex = scindex_RXKAD; if (unauth || (ssc = get_sc(scell)) == NULL) { ssc = rxnull_NewClientSecurityObject(); sscindex = scindex_NULL; /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell); */ } sscindex = scindex_NULL; if ((sconn = rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc, sscindex)) == NULL) { struct in_addr s; s.s_addr = ssrv; printf("Cannot initialize rx connection to source server (%s)\n", inet_ntoa(s)); goto Fail_sc; } } if (!dlcl && !unlock) { if (!slcl && ssrv == dsrv) { dconn = sconn; dsc = NULL; } else { if (slcl || strcmp(scell, dcell)) { dscindex = scindex_RXKAD; if (unauth || (dsc = get_sc(dcell)) == NULL) { dsc = rxnull_NewClientSecurityObject(); dscindex = scindex_NULL; /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell); */ } dscindex = scindex_NULL; } else { dsc = ssc; dscindex = sscindex; } if ((dconn = rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc, dscindex)) == NULL) { struct in_addr s; s.s_addr = dsrv; printf ("Cannot initialize rx connection to dest server (%s)\n", inet_ntoa(s)); goto Fail_sconn; } } } memset(&sst, 0, sizeof(struct AFSStoreStatus)); if (dlcl && !unlock) { dfd = open(destpath, O_RDWR | O_CREAT | O_EXCL, 0666); if (dfd < 0 && errno == EEXIST) { printf("%s already exists, overwriting\n", destpath); dfd = open(destpath, O_RDWR | O_TRUNC, 0666); if (dfd < 0) { fprintf(stderr, "Cannot open %s (%s)\n", destpath, afs_error_message(errno)); goto Fail_dconn; } } else if (dfd < 0) { fprintf(stderr, "Cannot open %s (%s)\n", destpath, afs_error_message(errno)); goto Fail_dconn; } } else if (!unlock) { if ((code = RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst, &dfst, &dcb, &vs))) { if (code == EEXIST) { printf("%s already exits, overwriting\n", destpath); if (statfile(destpath, dcell, &dsrv, &df)) fprintf(stderr, "Cannot get attributes of %s\n", destpath); else code = 0; } else { printf("Cannot create %s (%s)\n", destpath, afs_error_message(code)); if (code) goto Fail_dconn; } } } if (slcl) { sfd = open(srcf, O_RDONLY, 0); if (sfd < 0) { fprintf(stderr, "Cannot open %s (%s)\n", srcf, afs_error_message(errno)); goto Fail_dconn; } if (fstat(sfd, &statbuf) < 0) { fprintf(stderr, "Cannot stat %s (%s)\n", srcf, afs_error_message(errno)); close(sfd); goto Fail_dconn; } } else { if ((code = RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) { printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode, afs_error_message(code)); goto Fail_dconn; } } if (slcl) { filesz = statbuf.st_size; } else { filesz = fst.Length; } printcallerrs = 0; fetchcode = 0; storecode = 0; if (!slcl && !unlock) scall = rx_NewCall(sconn); if (!dlcl && !unlock) dcall = rx_NewCall(dconn); gettimeofday(&start, &tz); if (unlock) { if (fst.lockCount) { printf("Sending 1 unlock for %s (%d locks)\n", srcf, fst.lockCount); if ((code = RXAFS_ReleaseLock(sconn, &sf, &vs))) { printf("Unable to unlock %s (%s)\n", srcf, afs_error_message(code)); } } else { printf("No locks for %s\n", srcf); } fetchcode = code; goto Finish; } if (!slcl) { if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) { printf("Unable to fetch data from %s (%s)\n", srcf, afs_error_message(code)); goto Fail_call; } } if (!dlcl) { if (slcl) { sst.Mask = AFS_SETMODTIME | AFS_SETMODE; sst.ClientModTime = statbuf.st_mtime; sst.UnixModeBits = statbuf.st_mode & ~(S_IFMT | S_ISUID | S_ISGID); } else { sst.Mask = AFS_SETMODTIME | AFS_SETMODE; sst.ClientModTime = fst.ClientModTime; sst.UnixModeBits = fst.UnixModeBits & ~(S_IFMT | S_ISUID | S_ISGID); } if ((code = StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) { printf("Unable to store data to %s (%s)\n", destpath, afs_error_message(code)); goto Fail_call; } } if (slcl) { bytesremaining = statbuf.st_size; } else { rx_Read(scall, (char *)&bytesremaining, sizeof(afs_int32)); bytesremaining = ntohl(bytesremaining); } while (bytesremaining > 0) { /*printf("%d bytes remaining\n",bytesremaining); */ if (slcl) { if ((bytes = read(sfd, databuffer, min(blksize, bytesremaining))) <= 0) { fetchcode = errno; break; } } else { if ((bytes = rx_Read(scall, databuffer, min(blksize, bytesremaining))) <= 0) break; } if (dlcl) { if (write(dfd, databuffer, bytes) != bytes) { storecode = errno; break; } } else { if (rx_Write(dcall, databuffer, bytes) != bytes) break; } bytesremaining -= bytes; /*printf("%d bytes copied\n",bytes); */ } if (bytesremaining > 0) { printf("Some network error occured while copying data\n"); goto Fail_call; } if (!slcl) fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs); if (!dlcl) storecode = EndRXAFS_StoreData(dcall, &fst, &vs); printcallerrs = 1; Fail_call: if (slcl) { if (close(sfd) && !fetchcode) fetchcode = errno; } else { fetchcode = rx_EndCall(scall, fetchcode); } if (fetchcode && printcallerrs) printf("Error returned from fetch: %s\n", afs_error_message(fetchcode)); if (dlcl) { if (close(dfd) && !storecode) storecode = errno; } else if (!unlock) { storecode = rx_EndCall(dcall, storecode); } if (storecode && printcallerrs) printf("Error returned from store: %s\n", afs_error_message(storecode)); Finish: gettimeofday(&finish, &tz); if (!slcl) { theFids.AFSCBFids_len = 1; theFids.AFSCBFids_val = &sf; theCBs.AFSCBs_len = 1; theCBs.AFSCBs_val = &scb; scb.CallBackType = CB_DROPPED; if ((code = RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs))) printf("Could not give up source callback: %s\n", afs_error_message(code)); } if (!dlcl) { theFids.AFSCBFids_len = 1; theFids.AFSCBFids_val = &df; theCBs.AFSCBs_len = 1; theCBs.AFSCBs_val = &dcb; dcb.CallBackType = CB_DROPPED; if ((code = RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs))) printf("Could not give up target callback: %s\n", afs_error_message(code)); } if (code == 0) code = storecode; if (code == 0) code = fetchcode; Fail_dconn: if (!dlcl && !unlock && (slcl || dconn != sconn)) rx_DestroyConnection(dconn); Fail_sconn: if (!slcl) rx_DestroyConnection(sconn); Fail_sc: if (dsc && dsc != ssc) RXS_Close(dsc); if (ssc) RXS_Close(ssc); Fail_rx: rx_Finalize(); free(databuffer); if (printcallerrs && !unlock) { double rate, size, time; if (finish.tv_sec == start.tv_sec) { printf("Copied %d bytes in %d microseconds\n", filesz, (int)(finish.tv_usec - start.tv_usec)); } else { printf("Copied %d bytes in %d seconds\n", filesz, (int)(finish.tv_sec - start.tv_sec)); } size = filesz / 1024.0; time = finish.tv_sec - start.tv_sec + (finish.tv_usec - start.tv_usec) / 1e+06; rate = size / time; printf("Transfer rate %g Kbytes/sec\n", rate); } exit(code != 0); }