int afscp_StoreStatus(const struct afscp_venusfid *fid, struct AFSStoreStatus *s) { struct afscp_volume *v; struct afscp_server *server; struct AFSVolSync vs; struct AFSFetchStatus fst; struct AFSFid tf = fid->fid; int code, i, j; v = afscp_VolumeById(fid->cell, fid->fid.Volume); if (v == NULL) { return -1; } 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++) { code = RXAFS_StoreStatus(server->conns[j], &tf, s, &fst, &vs); if (code == 0) { _StatStuff(fid, &fst); /* calls _StatStuff */ return 0; } } } } afscp_errno = code; return -1; }
afs_int32 rpc_test_afs_store_status(rpc_test_request_ctx *ctx, AFSFid *fid, AFSStoreStatus *instatus, AFSFetchStatus *outstatus) { struct AFSVolSync tsync; afs_int32 code = 0; RXCALL_WITH_SOCK(code, ctx, (RXAFS_StoreStatus(ctx->conn, fid, instatus, outstatus, &tsync))); return (code); } /* rpc_test_afs_fetch_status */
/*! * Send disconnected file changes to the server. * * \note Call with vnode locked both locally and on the server. * * \param avc Vnode that gets synchronized to the server. * \param areq Used for obtaining a conn struct. * * \return 0 for success. On failure, other error codes. */ int afs_SendChanges(struct vcache *avc, struct vrequest *areq) { struct afs_conn *tc; struct rx_connection *rxconn; struct AFSStoreStatus sstat; struct AFSFetchStatus fstat; struct AFSVolSync tsync; int code = 0; int flags = 0; XSTATS_DECLS; /* Start multiplexing dirty operations from ddirty_flags field: */ if (avc->f.ddirty_flags & VDisconSetAttrMask) { /* Setattr OPS: */ /* Turn dirty vc data into a new store status... */ if (afs_GenStoreStatus(avc, &sstat) > 0) { do { tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn); if (tc) { /* ... and send it. */ XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_STORESTATUS); RX_AFS_GUNLOCK(); code = RXAFS_StoreStatus(rxconn, (struct AFSFid *) &avc->f.fid.Fid, &sstat, &fstat, &tsync); RX_AFS_GLOCK(); XSTATS_END_TIME; } else code = -1; } while (afs_Analyze(tc, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_STORESTATUS, SHARED_LOCK, NULL)); } /* if (afs_GenStoreStatus() > 0)*/ } /* disconnected SETATTR */ if (code) return code; if (avc->f.ddirty_flags & (VDisconTrunc | VDisconWriteClose | VDisconWriteFlush | VDisconWriteOsiFlush)) { /* Truncate OP: */ do { tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn); if (tc) { /* Set storing flags. XXX: A tad inefficient ... */ if (avc->f.ddirty_flags & VDisconWriteClose) flags |= AFS_LASTSTORE; if (avc->f.ddirty_flags & VDisconWriteOsiFlush) flags |= (AFS_SYNC | AFS_LASTSTORE); if (avc->f.ddirty_flags & VDisconWriteFlush) flags |= AFS_SYNC; /* Try to send store to server. */ /* XXX: AFS_LASTSTORE for writes? Or just AFS_SYNC for all? */ code = afs_StoreAllSegments(avc, areq, flags); } else code = -1; } while (afs_Analyze(tc, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_STOREDATA, SHARED_LOCK, NULL)); } /* disconnected TRUNC | WRITE */ return code; }