From f6168a849cbb5bde34cec11e02df54481fc5d3ca Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Thu, 12 Aug 2010 14:38:55 -0500 Subject: [PATCH] libafs: Set tvcp->callback before BulkStatus When we call InlineBulkStatus or BulkStatus, we currently do not touch tvcp->callback for any of the vcaches before making the call. This can cause us to not notice an InitCallBackState issued by the fileserver before the BulkStatus call returns, since the InitCallBackState handler looks at tvcp->callback to determine what vcaches to clear callbacks for. In turn, this can cause us to think we have a callback agreement with the fileserver on one of the BulkStatus'd files, when the fileserver does not actually have such a callback agreement. So, set tvcp->callback to the server we are contacting, so if we get an InitCallBackState call from that fileserver, the CBulkFetching state will be cleared, and we will correctly discard the callback information for that vcache. Reviewed-on: http://gerrit.openafs.org/2548 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear (cherry picked from commit 37817796c4890683a7e41ed0f3a2fa6a53e1edc7) Change-Id: I85c89eff061af799a7d8f612bee9b2f182312e6f Reviewed-on: http://gerrit.openafs.org/5754 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/afs/VNOPS/afs_vnop_lookup.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 2e575c1e8..46fc72dd8 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -942,6 +942,36 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) tcp = afs_Conn(&adp->f.fid, areqp, SHARED_LOCK, &rxconn); if (tcp) { hostp = tcp->srvr->server; + + for (i = 0; i < fidIndex; i++) { + /* we must set tvcp->callback before the BulkStatus call, so + * we can detect concurrent InitCallBackState's */ + + afid.Cell = adp->f.fid.Cell; + afid.Fid.Volume = adp->f.fid.Fid.Volume; + afid.Fid.Vnode = fidsp[i].Vnode; + afid.Fid.Unique = fidsp[i].Unique; + + do { + retry = 0; + ObtainReadLock(&afs_xvcache); + tvcp = afs_FindVCache(&afid, &retry, 0 /* !stats&!lru */); + ReleaseReadLock(&afs_xvcache); + } while (tvcp && retry); + + if (!tvcp) { + continue; + } + + if ((tvcp->f.states & CBulkFetching) && + (tvcp->f.m.Length == statSeqNo)) { + tvcp->callback = hostp; + } + + afs_PutVCache(tvcp); + tvcp = NULL; + } + XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_BULKSTATUS); if (!(tcp->srvr->server->flags & SNO_INLINEBULK)) { -- 2.39.5