* can't be locked. Thus, this must always be called in a while loop to stabilize
* things, since we can always lose the race condition getting to the parent vnode.
*/
-int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up, afs_uint32 rights,
+int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *userp, afs_uint32 rights,
afs_uint32 *outRightsp)
{
cm_scache_t *aclScp;
*outRightsp = rights;
} else {
/* we have to check the specific rights info */
- code = cm_FindACLCache(aclScp, up, &trights);
+ code = cm_FindACLCache(aclScp, userp, &trights);
if (code) {
code = 0;
goto done;
}
/* called with locked scp; ensures that we have an ACL cache entry for the
- * user specified by the parameter "up."
+ * user specified by the parameter "userp."
* In pathological race conditions, this function may return success without
* having loaded the entry properly (due to a racing callback revoke), so this
* function must also be called in a while loop to make sure that we eventually
* succeed.
*/
-long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *up,
+long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *userp,
struct cm_req *reqp)
{
long code;
cm_fid_t tfid;
cm_scache_t *aclScp;
+ int got_cb = 0;
/* pretty easy: just force a pass through the fetch status code */
- osi_Log2(afsd_logp, "GetAccess scp %x user %x", scp, up);
+ osi_Log2(afsd_logp, "GetAccess scp %x user %x", 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.
*/
- code = cm_SyncOp(scp, NULL, up, reqp, 0,
+ if (!cm_HaveCallback(scp)) {
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if (code)
- return code;
+ if (code)
+ return code;
+
+ got_cb = 1;
+ }
if (scp->fileType != CM_SCACHETYPE_DIRECTORY) {
/* not a dir, use parent dir's acl */
tfid.vnode = scp->parentVnode;
tfid.unique = scp->parentUnique;
lock_ReleaseMutex(&scp->mx);
- code = cm_GetSCache(&tfid, &aclScp, up, reqp);
+ code = cm_GetSCache(&tfid, &aclScp, userp, reqp);
if (code) {
lock_ObtainMutex(&scp->mx);
return code;
}
- osi_Log1(afsd_logp, "GetAccess parent scp %x user %x", aclScp, up);
+ osi_Log1(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp);
lock_ObtainMutex(&aclScp->mx);
- code = cm_SyncOp(aclScp, NULL, up, reqp, 0,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+
+ code = cm_GetCallback(aclScp, userp, reqp, 1);
lock_ReleaseMutex(&aclScp->mx);
cm_ReleaseSCache(aclScp);
lock_ObtainMutex(&scp->mx);
+ } else if (!got_cb) {
+ code = cm_GetCallback(scp, userp, reqp, 1);
}
return code;
* is to serialize all StoreData RPC's. This is the reason we defined
* CM_SCACHESYNC_STOREDATA_EXCL and CM_SCACHEFLAG_DATASTORING.
*/
-long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
+long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *reqp,
afs_uint32 rights, afs_uint32 flags)
{
osi_queueData_t *qdp;
osi_Log1(afsd_logp, "CM SyncOp getting callback on scp 0x%p",
scp);
if (bufLocked) lock_ReleaseMutex(&bufp->mx);
- code = cm_GetCallback(scp, up, reqp, 0);
+ code = cm_GetCallback(scp, userp, reqp, 0);
if (bufLocked) {
lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufp->mx);
if ((rights & PRSFS_WRITE) && (scp->flags & CM_SCACHEFLAG_RO))
return CM_ERROR_READONLY;
- if (cm_HaveAccessRights(scp, up, rights, &outRights)) {
+ if (cm_HaveAccessRights(scp, userp, rights, &outRights)) {
if (~outRights & rights)
return CM_ERROR_NOACCESS;
}
else {
/* we don't know the required access rights */
if (bufLocked) lock_ReleaseMutex(&bufp->mx);
- code = cm_GetAccessRights(scp, up, reqp);
+ code = cm_GetAccessRights(scp, userp, reqp);
if (code)
return code;
if (bufLocked) {