LICENSE MIT
Do not permit GetAccessRights() to be called multiple times within
cm_SyncOp for the same rights check. If the GetAccessRights() succeeded
and in the next loop the rights check fails, the user simply doesn't
have the rights.
Move a call to cm_SyncOpDone(FETCHSTATUS) from GetBuffer() to MergeStatus().
Anytime an RPC completes successfully we get updated status info for
the object. Might as well allow threads waiting for status info to us
it.
(cherry picked from commit
aab4b2b32f933daf48cc138c0eb5d8cf5a2023b5)
/* pretty easy: just force a pass through the fetch status code */
- osi_Log2(afsd_logp, "GetAccess scp 0x%p user 0x%p", scp, userp);
+ osi_Log2(afsd_logp, "GetAccessRights scp 0x%p user 0x%p", scp, userp);
/* first, start by finding out whether we have a directory or something
* else, so we can find what object's ACL we need.
goto _done;
}
- osi_Log2(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp);
+ osi_Log2(afsd_logp, "GetAccessRights parent scp %x user %x", aclScp, userp);
lock_ObtainWrite(&aclScp->rw);
code = cm_SyncOp(aclScp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB);
lock_ObtainWrite(&scp->rw);
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS);
-
/* we know that no one else has changed the buffer, since we still have
* the fetching flag on the buffers, and we have the scp locked again.
* Copy in the version # into the buffer if we got code 0 back from the
afs_uint32 sleep_buf_cmflags = 0;
afs_uint32 sleep_scp_bufs = 0;
int wakeupCycle;
+ int getAccessRights = 1;
/* lookup this first */
bufLocked = flags & CM_SCACHESYNC_BUFLOCKED;
if ((rights & PRSFS_WRITE) && (scp->flags & CM_SCACHEFLAG_RO))
return CM_ERROR_READONLY;
- if (cm_HaveAccessRights(scp, userp, rights, &outRights)) {
+ if (cm_HaveAccessRights(scp, userp, rights, &outRights) || !getAccessRights) {
if (~outRights & rights)
return CM_ERROR_NOACCESS;
}
}
if (code)
return code;
+ getAccessRights = 0; /* do not repeat */
continue;
}
}
scp->bufDataVersionLow = dataVersion;
scp->dataVersion = dataVersion;
+
+ /*
+ * If someone is waiting for status information, we can wake them up
+ * now even though the entity that issued the FetchStatus may not
+ * have completed yet.
+ */
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS);
}
/* note that our stat cache info is incorrect, so force us eventually