263 lines
6.6 KiB
C
263 lines
6.6 KiB
C
/****************************************************************************
|
|
|
|
|
| (C) Copyright 1985, 1991, 1993, 1996 Novell, Inc.
|
|
| All Rights Reserved.
|
|
|
|
|
| This program is free software; you can redistribute it and/or
|
|
| modify it under the terms of version 2 of the GNU General Public
|
|
| License as published by the Free Software Foundation.
|
|
|
|
|
| This program is distributed in the hope that it will be useful,
|
|
| but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| GNU General Public License for more details.
|
|
|
|
|
| You should have received a copy of the GNU General Public License
|
|
| along with this program; if not, contact Novell, Inc.
|
|
|
|
|
| To contact Novell about this file by physical or electronic mail,
|
|
| you may find current contact information at www.novell.com
|
|
|
|
|
|***************************************************************************
|
|
|
|
|
| NetWare Advance File Services (NSS) module
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
|
|
|
| $Author: taysom $
|
|
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
|
|
|
|
| $RCSfile$
|
|
| $Revision: 465 $
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
| This module is used to:
|
|
| Define the Semantic Agent side of OpLocks.
|
|
|
|
|
| WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
|
|
|
|
|
| This header file should ONLY be used for NSS internal development.
|
|
| This includes Semantic Agents (SA) and Loadable Storage Services (LSS).
|
|
| Any other use may cause conflicts which NSS will NOT fix.
|
|
+-------------------------------------------------------------------------*/
|
|
#ifndef _OPLOCK_H_
|
|
#define _OPLOCK_H_
|
|
|
|
#ifndef _MSGGEN_H_
|
|
#include "msgGen.h"
|
|
#endif
|
|
|
|
#ifndef _ALARM_H_
|
|
#include "alarm.h"
|
|
#endif
|
|
|
|
#ifndef _COMNBEASTS_H_
|
|
#include "comnBeasts.h"
|
|
#endif
|
|
|
|
#ifndef _FILEHANDLE_H_
|
|
#include "fileHandle.h"
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
extern LONG NW_ClientFileCachingEnabledFlag;
|
|
extern LONG NW_Level2OpLocksEnabledFlag;
|
|
|
|
typedef struct OpLockInst_s
|
|
{
|
|
NINT timedOut;
|
|
NINT makeShared;
|
|
NINT allocExclusive;
|
|
NINT allocShared;
|
|
|
|
NINT free;
|
|
NINT breakExclusive;
|
|
NINT breakShared;
|
|
NINT breakAll;
|
|
|
|
NINT waitForBreak;
|
|
NINT breakFailed;
|
|
NINT nwsaBreakCallback;
|
|
NINT nwsaClear;
|
|
|
|
NINT nwsaAcked;
|
|
NINT nwsaDeclined;
|
|
NINT nwsaRequestSharedOpLock;
|
|
} OpLockInst_s;
|
|
|
|
extern OpLockInst_s OpLockInst;
|
|
|
|
#if NSS_DEBUG IS_ENABLED
|
|
|
|
extern BOOL OpLockVerbose;
|
|
|
|
#define OPLOCK(_x) { \
|
|
++OpLockInst._x; \
|
|
if (OpLockVerbose) \
|
|
DBG_DebugPrintf(YELLOW, MSGNot("OpLock " # _x "\n")); \
|
|
}
|
|
|
|
#else
|
|
|
|
#define OPLOCK(_x) (++OpLockInst._x)
|
|
|
|
#endif
|
|
/*
|
|
* Samples of how to use OPLOCK to keep OpLock instrumentation
|
|
*
|
|
* OPLOCK(timedOut);
|
|
* OPLOCK(waiting);
|
|
* OPLOCK(allocExclusive);
|
|
* OPLOCK(allocShared);
|
|
*
|
|
* OPLOCK(free);
|
|
* OPLOCK(breakExclusive);
|
|
* OPLOCK(breakShared);
|
|
* OPLOCK(breakAll);
|
|
*
|
|
* OPLOCK(waitForBreak);
|
|
* OPLOCK(breakFailed);
|
|
* OPLOCK(nwsaBreakCallback);
|
|
* OPLOCK(nwsaClear);
|
|
*
|
|
* OPLOCK(nwsaAcked);
|
|
* OPLOCK(nwsaDeclined);
|
|
* OPLOCK(nwsaRequestSharedOpLock);
|
|
*/
|
|
/*
|
|
* These returns are used by the Semantic Agent but are placed here
|
|
* to keep every thing together.
|
|
*/
|
|
#define OPLOCK_FAILED 0
|
|
#define OPLOCK_GRANTED 1
|
|
|
|
/*
|
|
* States for OpLocks
|
|
*/
|
|
#define OPLOCK_IDLE 0
|
|
#define OPLOCK_EXCLUSIVE 1 /* Sometimes called level 1 oplock */
|
|
#define OPLOCK_BREAKING_EXCLUSIVE 2
|
|
#define OPLOCK_SHARED 3 /* Also called level 2 or reader oplock */
|
|
#define OPLOCK_BREAKING_SHARED 4
|
|
|
|
/*
|
|
* OpLock events passed in callback
|
|
*/
|
|
#define OPLOCK_BREAK 0 /* Tell your client to break the oplock */
|
|
#define OPLOCK_CLEAR 1 /* We are about to free the oplock, clean up.
|
|
* We ignore the error return and clean up.
|
|
* genMsg is NULL.
|
|
*/
|
|
#define OPLOCK_TIMEOUT 2 /* Timed out waiting for the oplock to be broken
|
|
* If the SA returns zOK, we will forcefully
|
|
* break the oplock and free it, otherwise, we
|
|
* will return an error to the requestor.
|
|
*/
|
|
#define OPLOCK_WAITING 3 /* Begin waiting for the OPLOCK. NWSA will
|
|
* do deal lock detection.
|
|
*/
|
|
#define OPLOCK_WAIT_OVER 4 /* Waiting for the oplock is over. This lets
|
|
* NWSA cleanup its waits-for graph. Currently,
|
|
* other SAs can ignore this event.
|
|
*/
|
|
|
|
typedef struct OpLockControl_s
|
|
{
|
|
BYTE opState; /* State of the opLock */
|
|
BYTE opHasPSA; /* Has a PSA shared oplock */
|
|
BYTE reserved[2];
|
|
File_s *opFile;
|
|
DQhead_t opLockWaiters; /* Threads waiting for opLock to clear */
|
|
DQhead_t opLocks; /* Oplocks currently held on beast */
|
|
} OpLockControl_s;
|
|
|
|
typedef struct OpLock_s
|
|
{
|
|
DQlink_t opLink;
|
|
statusfunc_t opCallback; /* Function to call in S.A. */
|
|
FileHandle_s *fileHandle; /* File handle for OpLock */
|
|
OpLockControl_s *control;
|
|
ADDR opSaData; /* Pointer to S.A. specific data
|
|
* Field must be set by S.A.; common
|
|
* layer just sets it to 0.
|
|
*/
|
|
/*
|
|
* The following fields are NWSA specific
|
|
*/
|
|
DQlink_t tickle;
|
|
} OpLock_s;
|
|
|
|
OpLock_s *OPLOCK_AllocExclusive(
|
|
FileHandle_s *fh,
|
|
statusfunc_t opCallback);
|
|
|
|
OpLock_s *OPLOCK_AllocShared(
|
|
FileHandle_s *fh,
|
|
statusfunc_t opCallback);
|
|
|
|
void OPLOCK_Free(OpLock_s *opLock);
|
|
void OPLOCK_MakeShared(OpLock_s *opLock);
|
|
void OPLOCK_releaseControl(OpLockControl_s *opLockControl);
|
|
|
|
STATUS OPLOCK_BreakExclusive(
|
|
GeneralMsg_s *genMsg,
|
|
File_s *file,
|
|
BOOL wait);
|
|
|
|
STATUS OPLOCK_BreakShared(File_s *file);
|
|
STATUS OPLOCK_BreakPSA(File_s *file);
|
|
|
|
STATUS OPLOCK_Break(
|
|
GeneralMsg_s *genMsg, /* Brings along the connection ID */
|
|
File_s *file,
|
|
BOOL wait);
|
|
|
|
/*
|
|
* Assumptions:
|
|
* 1. COMN_BreakOpLock or OPLOCK_BreakExclusive
|
|
* has been called and returned zERR_OPLOCK_MUST_WAIT.
|
|
* 2. The thread has released all of its latches. (This does
|
|
* not mean that someone else can't have a latch.)
|
|
* 3. The thread will reaquire the latches its needs after
|
|
* this call returns.
|
|
* 4. Thread hasn't blocked from the return in step 1 thru step 3.
|
|
* 5. If you were trying to also break shared oplocks, you'll have
|
|
* to call OPLOCK_BreakShared
|
|
*/
|
|
STATUS OPLOCK_WaitForBreak(
|
|
GeneralMsg_s *genMsg,
|
|
File_s *file);
|
|
|
|
void OPLOCK_BreakFailed(OpLock_s *opLock);
|
|
|
|
|
|
STATUS NWSA_OpLockCallback(
|
|
NINT event,
|
|
GeneralMsg_s *genMsg,
|
|
OpLock_s *opLock);
|
|
|
|
STATUS NWSA_OpLockClear(
|
|
GeneralMsg_s *genMsg,
|
|
FileHandle_s *fh);
|
|
|
|
STATUS NWSA_OpLockAcked(
|
|
GeneralMsg_s *genMsg,
|
|
FileHandle_s *fh);
|
|
|
|
STATUS NWSA_OpLockDeclined(
|
|
GeneralMsg_s *genMsg,
|
|
FileHandle_s *fh);
|
|
|
|
STATUS NWSA_RequestSharedOpLock(
|
|
GeneralMsg_s *genMsg,
|
|
FileHandle_s *fh);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|