From de6a01e51d8ea97e943cb4fa93d6bba2ecae9644 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 4 Oct 2006 01:23:30 +0000 Subject: [PATCH 1/1] windows-multi-fix-20061003 misc cleanups hold scp->mx while recycling add FILE_NOTIFY_CHANGE_CREATION to the notification mask when adding or deleting files --- src/WINNT/afsd/cm_callback.c | 11 +++-------- src/WINNT/afsd/cm_dcache.c | 19 +++++++++---------- src/WINNT/afsd/cm_scache.c | 8 ++++++++ src/WINNT/afsd/cm_vnodeops.c | 7 ++++--- src/WINNT/afsd/smb.c | 10 +++++----- src/WINNT/afsd/smb3.c | 16 ++++++++-------- 6 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 5ead137..36fbbb9 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -1622,7 +1622,6 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, AFSFid tfid; cm_callbackRequest_t cbr; int mustCall; - long sflags; cm_fid_t sfid; struct rx_connection * callp = NULL; @@ -1680,16 +1679,14 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, /* turn off mustCall, since it has now forced us past the check above */ mustCall = 0; -#if 0 /* 20060929 jaltman - We are being called from within cm_SyncOp. * if we call cm_SyncOp again and another thread has attempted * to obtain current status CM_SCACHEFLAG_WAITING will be set * and we will deadlock. */ /* otherwise, we have to make an RPC to get the status */ - sflags = CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK; - cm_SyncOp(scp, NULL, userp, reqp, 0, sflags); -#endif /* deadlock */ + cm_SyncOp(scp, NULL, userp, reqp, 0, + CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK); cm_StartCallbackGrantingCall(scp, &cbr); sfid = scp->fid; lock_ReleaseMutex(&scp->mx); @@ -1724,10 +1721,8 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, } else { cm_EndCallbackGrantingCall(NULL, &cbr, NULL, 0); } -#if 0 /* 20060929 jaltman - don't deadlock */ - cm_SyncOpDone(scp, NULL, sflags); -#endif + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK); /* now check to see if we got an error */ if (code) { diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 89c5721..9363f1b 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -611,21 +611,20 @@ void cm_BkgStore(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, if (scp->flags & CM_SCACHEFLAG_DELETED) { osi_Log4(afsd_logp, "Skipping BKG store - Deleted scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3); - return; - } - - cm_InitReq(&req); + } else { + cm_InitReq(&req); #ifdef NO_BKG_RETRIES - req.flags |= CM_REQ_NORETRY; + req.flags |= CM_REQ_NORETRY; #endif - toffset.LowPart = p1; - toffset.HighPart = p2; - length = p3; + toffset.LowPart = p1; + toffset.HighPart = p2; + length = p3; - osi_Log4(afsd_logp, "Starting BKG store scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3); + osi_Log4(afsd_logp, "Starting BKG store scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3); - code = cm_BufWrite(&scp->fid, &toffset, length, /* flags */ 0, userp, &req); + code = cm_BufWrite(&scp->fid, &toffset, length, /* flags */ 0, userp, &req); + } lock_ObtainMutex(&scp->mx); cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_ASYNCSTORE); diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index fa42707..c740afa 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -57,6 +57,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) cm_scache_t *tscp; int i; + lock_ObtainMutex(&scp->mx); if (scp->flags & CM_SCACHEFLAG_INHASH) { /* hash it out first */ i = CM_SCACHE_HASH(&scp->fid); @@ -81,6 +82,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) osi_QRemove((osi_queue_t **) &scp->bufWritesp, &qdp->q); osi_QDFree(qdp); if (bufp) { + lock_ReleaseMutex(&scp->mx); lock_ObtainMutex(&bufp->mx); bufp->cmFlags &= ~CM_BUF_CMSTORING; bufp->flags &= ~CM_BUF_DIRTY; @@ -94,6 +96,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) } lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + lock_ObtainMutex(&scp->mx); } } while(qdp = scp->bufReadsp) { @@ -101,6 +104,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) osi_QRemove((osi_queue_t **) &scp->bufReadsp, &qdp->q); osi_QDFree(qdp); if (bufp) { + lock_ReleaseMutex(&scp->mx); lock_ObtainMutex(&bufp->mx); bufp->cmFlags &= ~CM_BUF_CMFETCHING; bufp->flags &= ~CM_BUF_DIRTY; @@ -114,6 +118,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) } lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + lock_ObtainMutex(&scp->mx); } } buf_CleanDirtyBuffers(scp); @@ -179,6 +184,9 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) */ cm_FreeAllACLEnts(scp); + osi_Wakeup((long)&scp->flags); + + lock_ReleaseMutex(&scp->mx); return 0; } diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index afcc46f..2f4e56d 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -2204,6 +2204,10 @@ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, lock_ObtainMutex(&scp->mx); /* otherwise, we have to make an RPC to get the status */ code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); + return code; + } /* make the attr structure */ cm_StatusFromAttr(&afsInStatus, scp, attrp); @@ -2212,9 +2216,6 @@ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, tfid.Vnode = scp->fid.vnode; tfid.Unique = scp->fid.unique; - lock_ReleaseMutex(&scp->mx); - if (code) - return code; /* now make the RPC */ osi_Log1(afsd_logp, "CALL StoreStatus scp 0x%p", scp); diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index c1742eb..2824c49 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -4849,7 +4849,7 @@ int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hype code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp); if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, dep->name, NULL, TRUE); if (code == 0) { rockp->any = 1; @@ -5407,7 +5407,7 @@ int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp); if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_DIR_NAME, + FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, dep->name, NULL, TRUE); if (code == 0) rockp->any = 1; @@ -5707,7 +5707,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp, scp->flags |= CM_SCACHEFLAG_DELETED; if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_DIR_NAME, + FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, fullPathp, NULL, TRUE); } } else { @@ -5716,7 +5716,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp, scp->flags |= CM_SCACHEFLAG_DELETED; if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, fullPathp, NULL, TRUE); } } @@ -6885,7 +6885,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) created = 1; if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, lastNamep, NULL, TRUE); } else if (!excl && code == CM_ERROR_EXISTS) { /* not an exclusive create, and someone else tried diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 74f2860..f9d54ec 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -2289,7 +2289,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) created = 1; if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, lastNamep, NULL, TRUE); } else if (!excl && code == CM_ERROR_EXISTS) { /* not an exclusive create, and someone else tried @@ -5073,7 +5073,7 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) created = 1; if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, lastNamep, NULL, TRUE); } else if (!excl && code == CM_ERROR_EXISTS) { /* not an exclusive create, and someone else tried @@ -6065,9 +6065,9 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (createOptions & FILE_DELETE_ON_CLOSE) fidflags |= SMB_FID_DELONCLOSE; if (createOptions & FILE_SEQUENTIAL_ONLY && !(createOptions & FILE_RANDOM_ACCESS)) - fidflags | SMB_FID_SEQUENTIAL; + fidflags |= SMB_FID_SEQUENTIAL; if (createOptions & FILE_RANDOM_ACCESS && !(createOptions & FILE_SEQUENTIAL_ONLY)) - fidflags & SMB_FID_RANDOM; + fidflags |= SMB_FID_RANDOM; /* and the share mode */ if (shareAccess & FILE_SHARE_READ) @@ -6339,7 +6339,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) created = 1; if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, lastNamep, NULL, TRUE); } else if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) { /* Not an exclusive create, and someone else tried @@ -6813,9 +6813,9 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (createOptions & FILE_DELETE_ON_CLOSE) fidflags |= SMB_FID_DELONCLOSE; if (createOptions & FILE_SEQUENTIAL_ONLY && !(createOptions & FILE_RANDOM_ACCESS)) - fidflags | SMB_FID_SEQUENTIAL; + fidflags |= SMB_FID_SEQUENTIAL; if (createOptions & FILE_RANDOM_ACCESS && !(createOptions & FILE_SEQUENTIAL_ONLY)) - fidflags & SMB_FID_RANDOM; + fidflags |= SMB_FID_RANDOM; /* And the share mode */ if (shareAccess & FILE_SHARE_READ) @@ -7020,7 +7020,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out created = 1; if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, lastNamep, NULL, TRUE); } else if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) { /* Not an exclusive create, and someone else tried -- 1.9.4