321 lines
8.1 KiB
C
321 lines
8.1 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) Initialization module
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
|
|
|
| $Author: taysom $
|
|
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
|
|
|
|
| $RCSfile$
|
|
| $Revision: 465 $
|
|
|
|
|
|---------------------------------------------------------------------------
|
|
| This module is used to:
|
|
| Common lock definitions needed by byte range locks, logical or record
|
|
| locks, and file name locks.
|
|
|
|
|
| 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 _COMNLOCK_H_
|
|
#define _COMNLOCK_H_
|
|
|
|
#ifndef _OMNI_H
|
|
#include <omni.h>
|
|
#endif
|
|
|
|
#ifndef _RBPTREE_H_
|
|
#include <rbpTree.h>
|
|
#endif
|
|
|
|
#ifndef _COMNBEASTS_H_
|
|
#include <comnBeasts.h>
|
|
#endif
|
|
|
|
#ifndef _PSSCONNECTION_H_
|
|
#include <pssConnection.h>
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Pre-define struct(s) so Linux compiler doesn't complain */
|
|
struct LockByteRangeMsg_s;
|
|
struct LockSetMsg_s;
|
|
struct UnlockByteRangeMsg_s;
|
|
|
|
typedef enum LockType_t
|
|
{
|
|
LK_BYTERANGE,
|
|
LK_LOGICAL,
|
|
LK_FILENAME
|
|
} LockType_t;
|
|
|
|
typedef enum LockState_t
|
|
{
|
|
LK_IDLE,
|
|
LK_WAITING,
|
|
LK_LOCKED
|
|
} LockState_t;
|
|
|
|
typedef struct Reply_s Reply_s;
|
|
|
|
struct Reply_s
|
|
{
|
|
FsmLite_s fsm; /* Fsm for callbacks */
|
|
OneShot_s alarm; /* Limits how long we wait for locks*/
|
|
voidfunc_t saCallBack; /* Semantic Agent specific call back*/
|
|
voidfunc_t userCallBack; /* Call back function */
|
|
ADDR userData; /* What we pass back to the user */
|
|
};
|
|
|
|
typedef struct LockSet_s
|
|
{
|
|
Reply_s reply; /* Reply for lock set requests */
|
|
RBP_Node_s *setRoot; /* Locks in this lock set */
|
|
NINT waiting; /* Num locks we are waiting for */
|
|
STATUS saStatus; /* Status from the Semantic Agent */
|
|
NINT otherSAs; /* Other SAs we are waiting for */
|
|
} LockSet_s;
|
|
|
|
typedef struct LockHeader_s
|
|
{
|
|
Reply_s reply; /* Reply for single lock requests */
|
|
LockSet_s *lockSet; /* Lock is a member of this set */
|
|
RBP_Node_s sibling; /* Other byte range locks for task */
|
|
DQhead_t waiters; /* Those waiting for the lock */
|
|
DQlink_t waiting; /* Waiting for lock (could use waiters) */
|
|
BOOL waitForever; /* How long to wait if blocked */
|
|
BYTE mode; /* Mode of the lock (S, X, N) */
|
|
BYTE state; /* Lock state (LockState_t) */
|
|
BYTE reserved[2];
|
|
} LockHeader_s;
|
|
|
|
typedef struct ByteRangeLock_s
|
|
{
|
|
LockHeader_s head;
|
|
RBP_Node_s startHeld; /* Starting offset tree for held locks */
|
|
RBP_Node_s endHeld; /* Ending offset tree for held locks */
|
|
QUAD start; /* Starting address for byte range lock */
|
|
QUAD end; /* Ending address for byte range lock */
|
|
ADDR lockData; /* compared when finding a lock */
|
|
NamedBeast_s *beast; /* Beast for byte range lock */
|
|
FileHandle_s *fh; /* File handle that owns the lock */
|
|
} ByteRangeLock_s;
|
|
|
|
#if NSS_DEBUG IS_ENABLED
|
|
#define INIT_REPLY(_reply) \
|
|
{ \
|
|
static NINT instance = 0; \
|
|
\
|
|
FSMLITE_INIT( &(_reply)->fsm, WHERE, instance); \
|
|
++instance; \
|
|
INIT_ONESHOT((_reply)->alarm); \
|
|
(_reply)->saCallBack = NULL; \
|
|
}
|
|
#else
|
|
#define INIT_REPLY(_reply) \
|
|
{ \
|
|
FSMLITE_INIT( &(_reply)->fsm, NULL, 0); \
|
|
INIT_ONESHOT((_reply)->alarm); \
|
|
(_reply)->saCallBack = NULL; \
|
|
}
|
|
#endif
|
|
|
|
#define COPY_CALLBACKS(_reply, _msg) \
|
|
{ \
|
|
(_reply)->saCallBack = (_msg)->saCallBack; \
|
|
(_reply)->userCallBack = (_msg)->userCallBack; \
|
|
(_reply)->userData = (_msg)->userData; \
|
|
}
|
|
|
|
/*
|
|
* INIT_LOCKHEAD initializes the lock header and
|
|
* sets its initialize state to FREE. Assumes fields
|
|
* are all already set to 0.
|
|
*/
|
|
#define INIT_LOCKHEAD(_head, _lockSet, _mode, _waitForever) \
|
|
{ \
|
|
INIT_REPLY( &((_head)->reply)); \
|
|
DQ_INIT( &(_head)->waiters); \
|
|
(_head)->lockSet = (_lockSet); \
|
|
(_head)->mode = (_mode); \
|
|
(_head)->state = LK_IDLE; \
|
|
(_head)->waitForever = (_waitForever); \
|
|
}
|
|
|
|
#define HAS_BYTE_RANGE_LOCKS(_beast) \
|
|
(((NamedBeast_s *)(_beast))->startLocks != NULL)
|
|
|
|
/*
|
|
* Function prototypes
|
|
*/
|
|
struct UserXaction_s *COMN_FindDefaultXaction (
|
|
struct GeneralMsg_s *genMsg);
|
|
|
|
void COMN_ConnectionUnlockByteRange(
|
|
struct NSSConnection_s *nssConn);
|
|
|
|
void COMN_TaskUnlockByteRange(
|
|
struct GeneralMsg_s *genMsg);
|
|
|
|
void COMN_BeastUnlockByteRange(
|
|
struct GeneralMsg_s *genMsg,
|
|
struct NamedBeast_s *beast,
|
|
struct FileHandle_s *fileHandle);
|
|
|
|
STATUS COMN_LockByteRange(
|
|
struct GeneralMsg_s *genMsg,
|
|
struct LockByteRangeMsg_s *lockMsg);
|
|
|
|
STATUS COMN_LockByteRangeSet(
|
|
struct GeneralMsg_s *genMsg,
|
|
struct LockSetMsg_s *setMsg);
|
|
|
|
STATUS COMN_UnlockByteRange(
|
|
struct GeneralMsg_s *genMsg,
|
|
struct UnlockByteRangeMsg_s *unlockMsg);
|
|
|
|
ByteRangeLock_s *COMN_FindByteRangeLock(
|
|
struct GeneralMsg_s *genMsg,
|
|
struct LockByteRangeMsg_s *lockMsg);
|
|
|
|
STATUS COMN_UnlockByteRangeSet(
|
|
struct GeneralMsg_s *genMsg,
|
|
BOOL clear);
|
|
|
|
BOOL LOCK_IsSharedByteRange (
|
|
struct FileHandle_s *fh,
|
|
Xid_t userXid,
|
|
QUAD start,
|
|
QUAD length);
|
|
|
|
BOOL LOCK_IsExclusiveByteRange (
|
|
struct FileHandle_s *fh,
|
|
Xid_t userXid,
|
|
QUAD start,
|
|
QUAD length);
|
|
|
|
BOOL LOCK_IsExclusiveByteRangeMandatory (
|
|
NamedBeast_s *beast,
|
|
QUAD start,
|
|
QUAD length);
|
|
|
|
ByteRangeLock_s *findByteRangeLock(
|
|
struct UnlockByteRangeMsg_s *unlockMsg);
|
|
|
|
void unlockByteRangeSet(
|
|
struct LockSet_s *lockSet,
|
|
BOOL clear);
|
|
|
|
ByteRangeLock_s *testLock(
|
|
NamedBeast_s *beast,
|
|
QUAD start,
|
|
QUAD end,
|
|
NINT mode,
|
|
LockSet_s *lockSet,
|
|
NINT semanticAgentID);
|
|
|
|
void lockChangeStart(ByteRangeLock_s *lock, QUAD start);
|
|
void lockChangeEnd(ByteRangeLock_s *lock, QUAD end);
|
|
void lockForceLock(ByteRangeLock_s *lock);
|
|
|
|
void unlockByteRange (
|
|
ByteRangeLock_s *lock,
|
|
BOOL clear);
|
|
|
|
void unlockXaction(struct UserXaction_s *userXaction);
|
|
|
|
void initLockSet(struct LockSet_s *lockSet);
|
|
|
|
void wakeupLockRequests(ByteRangeLock_s *lock);
|
|
|
|
ByteRangeLock_s *allocByteRangeLock (
|
|
GeneralMsg_s *genMsg,
|
|
LockSet_s *lockSet,
|
|
struct LockByteRangeMsg_s *msg);
|
|
|
|
|
|
BOOL checkDeadLockByFH(
|
|
FileHandle_s *waiter,
|
|
FileHandle_s *holder,
|
|
BOOL setWaitFor);
|
|
|
|
void clearXactionWaitForByFH(
|
|
FileHandle_s *fh);
|
|
|
|
/***************************************************************************
|
|
* Logical lock definitions
|
|
***************************************************************************/
|
|
|
|
#define LOCK_HASH_SIZE 128
|
|
#define LOCK_MODE_EXCLUSIVE 1
|
|
#define LOCK_MODE_SHARED 2
|
|
|
|
#define LOCKED TRUE
|
|
#define NOT_LOCKED FALSE
|
|
|
|
#define MAX_KEY_LEN_BYTES 128
|
|
|
|
typedef struct Lock_s
|
|
{
|
|
BYTE key[MAX_KEY_LEN_BYTES];
|
|
BYTE keyLen;
|
|
BYTE pad[3];
|
|
Latch_s latch;
|
|
OneShot_s alarm;
|
|
DQlink_t hashLink;
|
|
} Lock_s;
|
|
|
|
|
|
extern STATUS LOCK_Startup(void);
|
|
extern void LOCK_Shutdown(void);
|
|
|
|
extern Lock_s *COMN_LookupLock(
|
|
BYTE *key,
|
|
NINT keyBytes,
|
|
BOOL allocIfNotThere);
|
|
|
|
extern BOOL COMN_LockFunc(
|
|
BYTE *key,
|
|
NINT keyBytes,
|
|
NINT mode,
|
|
SLONG msecs);
|
|
|
|
extern void COMN_UnLockFunc(
|
|
BYTE *key,
|
|
NINT keyBytes);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|