From: Jeffrey Altman Date: Fri, 12 Apr 2013 05:14:39 +0000 (-0400) Subject: Windows: RDR_DeleteFileEntry test for empty directory X-Git-Tag: upstream/1.8.0_pre1^2~1213 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=2632c3f459dc47946b2e973c045056c3dca719f2;p=packages%2Fo%2Fopenafs.git Windows: RDR_DeleteFileEntry test for empty directory RDR_DeleteFileEntry should check to see that a directory entry that is a directory is in fact empty. The most frequent use of RDR_DeleteFileEntry is to check whether the object can be deleted prior to setting the DeletePending state which in turn results in the object being deleted during Cleanup. If the directory is not empty during Cleanup it is too late for the error to be seen by the application. Change-Id: I3207bab0527406e3003e97bccf4195abeed31423 Reviewed-on: http://gerrit.openafs.org/9779 Tested-by: BuildBot Reviewed-by: Jeffrey Altman --- diff --git a/src/WINNT/afsrdr/user/RDRFunction.c b/src/WINNT/afsrdr/user/RDRFunction.c index fca4332f9..0ecfdaea3 100644 --- a/src/WINNT/afsrdr/user/RDRFunction.c +++ b/src/WINNT/afsrdr/user/RDRFunction.c @@ -2327,6 +2327,37 @@ RDR_DeleteFileEntry( IN cm_user_t *userp, return; } + if (scp->fileType == CM_SCACHETYPE_DIRECTORY) { + cm_dirOp_t dirop; + + lock_ReleaseWrite(&scp->rw); + + code = cm_BeginDirOp(scp, userp, &req, CM_DIRLOCK_READ, + CM_DIROP_FLAG_NONE, &dirop); + if (code == 0) { + /* is the directory empty? if not, CM_ERROR_NOTEMPTY */ + afs_uint32 bEmpty; + + code = cm_BPlusDirIsEmpty(&dirop, &bEmpty); + if (code == 0 && !bEmpty) + code = CM_ERROR_NOTEMPTY; + + cm_EndDirOp(&dirop); + } + + if (code) { + smb_MapNTError(cm_MapRPCError(code, &req), &status, TRUE); + (*ResultCB)->ResultStatus = status; + (*ResultCB)->ResultBufferLength = 0; + cm_ReleaseSCache(scp); + cm_ReleaseSCache(dscp); + osi_Log3(afsd_logp, "RDR_DeleteFileEntry cm_SyncOp failure scp=0x%p code=0x%x status=0x%x", + scp, code, status); + return; + } + lock_ObtainWrite(&scp->rw); + } + if (!bCheckOnly) { /* Drop all locks since the file is being deleted */ code = cm_SyncOp(scp, NULL, userp, &req, 0,