more on time-based coherency

changing the code to keeping track of fcbs and not srv_opens.

problem of keeping srv_opens was that we could get an open for
attribute which will then do a setacl which will modify a change
attribute of the file but because the open is not for reading
data we won't have it on the list of opens.
This commit is contained in:
Olga Kornievskaia 2012-02-14 17:05:42 -05:00
parent fb7c379f06
commit 8adad77d4b

View file

@ -81,7 +81,7 @@ PRDBSS_DEVICE_OBJECT nfs41_dev;
#define NFS41_MM_POOLTAG ('nfs4') #define NFS41_MM_POOLTAG ('nfs4')
KEVENT upcallEvent; KEVENT upcallEvent;
FAST_MUTEX upcallLock, downcallLock, srvopenLock; FAST_MUTEX upcallLock, downcallLock, fcblistLock;
FAST_MUTEX xidLock; FAST_MUTEX xidLock;
FAST_MUTEX openOwnerLock; FAST_MUTEX openOwnerLock;
@ -433,18 +433,19 @@ typedef struct _NFS41_DEVICE_EXTENSION {
PNFS41_DEVICE_EXTENSION pExt = (PNFS41_DEVICE_EXTENSION) \ PNFS41_DEVICE_EXTENSION pExt = (PNFS41_DEVICE_EXTENSION) \
((PBYTE)(RxContext->RxDeviceObject) + sizeof(RDBSS_DEVICE_OBJECT)) ((PBYTE)(RxContext->RxDeviceObject) + sizeof(RDBSS_DEVICE_OBJECT))
typedef struct _nfs41_srvopen_list_entry { typedef struct _nfs41_fcb_list_entry {
LIST_ENTRY next; LIST_ENTRY next;
PMRX_SRV_OPEN srv_open; PMRX_FCB fcb;
HANDLE session;
PNFS41_FOBX nfs41_fobx; PNFS41_FOBX nfs41_fobx;
ULONGLONG ChangeTime; ULONGLONG ChangeTime;
BOOLEAN skip; BOOLEAN skip;
} nfs41_srvopen_list_entry; } nfs41_fcb_list_entry;
typedef struct _nfs41_srvopen_list { typedef struct _nfs41_fcb_list {
LIST_ENTRY head; LIST_ENTRY head;
} nfs41_srvopen_list; } nfs41_fcb_list;
nfs41_srvopen_list *openlist = NULL; nfs41_fcb_list *openlist = NULL;
typedef enum _NULMRX_STORAGE_TYPE_CODES { typedef enum _NULMRX_STORAGE_TYPE_CODES {
NTC_NFS41_DEVICE_EXTENSION = (NODE_TYPE_CODE)0xFC00, NTC_NFS41_DEVICE_EXTENSION = (NODE_TYPE_CODE)0xFC00,
@ -3495,23 +3496,24 @@ NTSTATUS nfs41_Create(
DbgP("nfs41_Create: disabling buffering\n"); DbgP("nfs41_Create: disabling buffering\n");
#endif #endif
SrvOpen->BufferingFlags = FCB_STATE_DISABLE_LOCAL_BUFFERING; SrvOpen->BufferingFlags = FCB_STATE_DISABLE_LOCAL_BUFFERING;
} else if (!entry->u.Open.deleg_type) { } else if (!entry->u.Open.deleg_type && !Fcb->OpenCount) {
nfs41_srvopen_list_entry *oentry; nfs41_fcb_list_entry *oentry;
#ifdef DEBUG_OPEN #ifdef DEBUG_OPEN
DbgP("nfs41_Create: received no delegations: srv_open=%p " DbgP("nfs41_Create: received no delegations: srv_open=%p "
"ctime=%llu\n", SrvOpen, entry->u.Open.changeattr); "ctime=%llu\n", SrvOpen, entry->u.Open.changeattr);
#endif #endif
oentry = RxAllocatePoolWithTag(NonPagedPool, oentry = RxAllocatePoolWithTag(NonPagedPool,
sizeof(nfs41_srvopen_list_entry), NFS41_MM_POOLTAG); sizeof(nfs41_fcb_list_entry), NFS41_MM_POOLTAG);
if (oentry == NULL) { if (oentry == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES; status = STATUS_INSUFFICIENT_RESOURCES;
goto out; goto out;
} }
oentry->srv_open = SrvOpen; oentry->fcb = RxContext->pFcb;
oentry->nfs41_fobx = nfs41_fobx; oentry->nfs41_fobx = nfs41_fobx;
oentry->session = pVNetRootContext->session;
oentry->ChangeTime = entry->u.Open.changeattr; oentry->ChangeTime = entry->u.Open.changeattr;
oentry->skip = FALSE; oentry->skip = FALSE;
nfs41_AddEntry(srvopenLock, openlist, oentry); nfs41_AddEntry(fcblistLock, openlist, oentry);
} }
} }
@ -3604,21 +3606,21 @@ ULONG nfs41_ExtendForCache(
return status; return status;
} }
VOID nfs41_remove_srvopen_entry( VOID nfs41_remove_fcb_entry(
PMRX_SRV_OPEN SrvOpen) PMRX_FCB fcb)
{ {
PLIST_ENTRY pEntry; PLIST_ENTRY pEntry;
nfs41_srvopen_list_entry *cur; nfs41_fcb_list_entry *cur;
ExAcquireFastMutex(&srvopenLock); ExAcquireFastMutex(&fcblistLock);
pEntry = openlist->head.Flink; pEntry = openlist->head.Flink;
#ifdef DEBUG_CLOSE #ifdef DEBUG_CLOSE
DbgP("nfs41_remove_srvopen_entry: Looking for srv_open=%p\n", SrvOpen); DbgP("nfs41_remove_srvopen_entry: Looking for fcb=%p\n", fcb);
#endif #endif
while (!IsListEmpty(&openlist->head)) { while (!IsListEmpty(&openlist->head)) {
cur = (nfs41_srvopen_list_entry *)CONTAINING_RECORD(pEntry, cur = (nfs41_fcb_list_entry *)CONTAINING_RECORD(pEntry,
nfs41_srvopen_list_entry, next); nfs41_fcb_list_entry, next);
if (cur->srv_open == SrvOpen) { if (cur->fcb == fcb) {
#ifdef DEBUG_CLOSE #ifdef DEBUG_CLOSE
DbgP("nfs41_remove_srvopen_entry: Found match\n"); DbgP("nfs41_remove_srvopen_entry: Found match\n");
#endif #endif
@ -3634,7 +3636,7 @@ VOID nfs41_remove_srvopen_entry(
} }
pEntry = pEntry->Flink; pEntry = pEntry->Flink;
} }
ExReleaseFastMutex(&srvopenLock); ExReleaseFastMutex(&fcblistLock);
} }
NTSTATUS map_close_errors( NTSTATUS map_close_errors(
@ -3675,9 +3677,8 @@ NTSTATUS nfs41_CloseSrvOpen(
#endif #endif
if (!nfs41_fobx->deleg_type && !nfs41_fcb->StandardInfo.Directory && if (!nfs41_fobx->deleg_type && !nfs41_fcb->StandardInfo.Directory &&
(SrvOpen->DesiredAccess & !RxContext->pFcb->OpenCount) {
(FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA))) { nfs41_remove_fcb_entry(RxContext->pFcb);
nfs41_remove_srvopen_entry(SrvOpen);
} }
status = nfs41_UpcallCreate(NFS41_CLOSE, &nfs41_fobx->sec_ctx, status = nfs41_UpcallCreate(NFS41_CLOSE, &nfs41_fobx->sec_ctx,
@ -4067,26 +4068,26 @@ out:
return status; return status;
} }
VOID nfs41_update_srvopen_list( VOID nfs41_update_fcb_list(
PMRX_SRV_OPEN SrvOpen, PMRX_FCB fcb,
ULONGLONG ChangeTime) ULONGLONG ChangeTime)
{ {
PLIST_ENTRY pEntry; PLIST_ENTRY pEntry;
nfs41_srvopen_list_entry *cur; nfs41_fcb_list_entry *cur;
ExAcquireFastMutex(&srvopenLock); ExAcquireFastMutex(&fcblistLock);
pEntry = openlist->head.Flink; pEntry = openlist->head.Flink;
#if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \ #if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \
defined(DEBUG_WRITE) || defined(DEBUG_EA_SET) defined(DEBUG_WRITE) || defined(DEBUG_EA_SET)
DbgP("nfs41_update_srvopen_list: Looking for srv_open=%p\n", SrvOpen); DbgP("nfs41_update_fcb_list: Looking for fcb=%p\n", fcb);
#endif #endif
while (!IsListEmpty(&openlist->head)) { while (!IsListEmpty(&openlist->head)) {
cur = (nfs41_srvopen_list_entry *)CONTAINING_RECORD(pEntry, cur = (nfs41_fcb_list_entry *)CONTAINING_RECORD(pEntry,
nfs41_srvopen_list_entry, next); nfs41_fcb_list_entry, next);
if (cur->srv_open == SrvOpen && if (cur->fcb == fcb &&
cur->ChangeTime != ChangeTime) { cur->ChangeTime != ChangeTime) {
#if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \ #if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \
defined(DEBUG_WRITE) || defined(DEBUG_EA_SET) defined(DEBUG_WRITE) || defined(DEBUG_EA_SET)
DbgP("nfs41_update_srvopen_list: Found match: updating %llu to " DbgP("nfs41_update_fcb_list: Found match: updating %llu to "
"%llu\n", cur->ChangeTime, ChangeTime); "%llu\n", cur->ChangeTime, ChangeTime);
#endif #endif
cur->ChangeTime = ChangeTime; cur->ChangeTime = ChangeTime;
@ -4096,13 +4097,13 @@ VOID nfs41_update_srvopen_list(
if (pEntry->Flink == &openlist->head) { if (pEntry->Flink == &openlist->head) {
#if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \ #if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \
defined(DEBUG_WRITE) || defined(DEBUG_EA_SET) defined(DEBUG_WRITE) || defined(DEBUG_EA_SET)
DbgP("nfs41_update_srvopen_list: reached end of the list\n"); DbgP("nfs41_update_fcb_list: reached end of the list\n");
#endif #endif
break; break;
} }
pEntry = pEntry->Flink; pEntry = pEntry->Flink;
} }
ExReleaseFastMutex(&srvopenLock); ExReleaseFastMutex(&fcblistLock);
} }
void print_nfs3_attrs( void print_nfs3_attrs(
@ -4238,7 +4239,7 @@ NTSTATUS nfs41_SetEaInformation(
if (!nfs41_fobx->deleg_type && entry->u.SetEa.ChangeTime && if (!nfs41_fobx->deleg_type && entry->u.SetEa.ChangeTime &&
(SrvOpen->DesiredAccess & (SrvOpen->DesiredAccess &
(FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA))) (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
nfs41_update_srvopen_list(SrvOpen, entry->u.SetEa.ChangeTime); nfs41_update_fcb_list(RxContext->pFcb, entry->u.SetEa.ChangeTime);
nfs41_fcb->changeattr = entry->u.SetEa.ChangeTime; nfs41_fcb->changeattr = entry->u.SetEa.ChangeTime;
} }
RxFreePool(entry); RxFreePool(entry);
@ -4606,7 +4607,7 @@ NTSTATUS nfs41_SetSecurityInformation(
if (!nfs41_fobx->deleg_type && entry->u.Acl.ChangeTime && if (!nfs41_fobx->deleg_type && entry->u.Acl.ChangeTime &&
(SrvOpen->DesiredAccess & (SrvOpen->DesiredAccess &
(FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA))) (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
nfs41_update_srvopen_list(SrvOpen, entry->u.Acl.ChangeTime); nfs41_update_fcb_list(RxContext->pFcb, entry->u.Acl.ChangeTime);
nfs41_fcb->changeattr = entry->u.Acl.ChangeTime; nfs41_fcb->changeattr = entry->u.Acl.ChangeTime;
} }
RxFreePool(entry); RxFreePool(entry);
@ -4974,7 +4975,7 @@ NTSTATUS nfs41_SetFileInformation(
if (!nfs41_fobx->deleg_type && entry->u.SetFile.ChangeTime && if (!nfs41_fobx->deleg_type && entry->u.SetFile.ChangeTime &&
(SrvOpen->DesiredAccess & (SrvOpen->DesiredAccess &
(FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA))) (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)))
nfs41_update_srvopen_list(SrvOpen, entry->u.SetFile.ChangeTime); nfs41_update_fcb_list(RxContext->pFcb, entry->u.SetFile.ChangeTime);
nfs41_fcb->changeattr = entry->u.SetFile.ChangeTime; nfs41_fcb->changeattr = entry->u.SetFile.ChangeTime;
} }
RxFreePool(entry); RxFreePool(entry);
@ -5072,11 +5073,12 @@ void print_readwrite_args(
void enable_caching( void enable_caching(
PMRX_SRV_OPEN SrvOpen, PMRX_SRV_OPEN SrvOpen,
PNFS41_FOBX nfs41_fobx, PNFS41_FOBX nfs41_fobx,
ULONGLONG ChangeTime) ULONGLONG ChangeTime,
HANDLE session)
{ {
ULONG flag = 0; ULONG flag = 0;
PLIST_ENTRY pEntry; PLIST_ENTRY pEntry;
nfs41_srvopen_list_entry *cur; nfs41_fcb_list_entry *cur;
BOOLEAN found = FALSE; BOOLEAN found = FALSE;
if (SrvOpen->DesiredAccess & FILE_READ_DATA) if (SrvOpen->DesiredAccess & FILE_READ_DATA)
@ -5094,13 +5096,13 @@ void enable_caching(
RxChangeBufferingState((PSRV_OPEN)SrvOpen, ULongToPtr(flag), 1); RxChangeBufferingState((PSRV_OPEN)SrvOpen, ULongToPtr(flag), 1);
ExAcquireFastMutex(&srvopenLock); ExAcquireFastMutex(&fcblistLock);
pEntry = openlist->head.Flink; pEntry = openlist->head.Flink;
DbgP("enable_caching: Looking for srv_open=%p\n", SrvOpen); DbgP("enable_caching: Looking for fcb=%p\n", SrvOpen->pFcb);
while (!IsListEmpty(&openlist->head)) { while (!IsListEmpty(&openlist->head)) {
cur = (nfs41_srvopen_list_entry *)CONTAINING_RECORD(pEntry, cur = (nfs41_fcb_list_entry *)CONTAINING_RECORD(pEntry,
nfs41_srvopen_list_entry, next); nfs41_fcb_list_entry, next);
if (cur->srv_open == SrvOpen) { if (cur->fcb == SrvOpen->pFcb) {
DbgP("enable_caching: Found match\n"); DbgP("enable_caching: Found match\n");
cur->skip = FALSE; cur->skip = FALSE;
found = TRUE; found = TRUE;
@ -5113,19 +5115,20 @@ void enable_caching(
pEntry = pEntry->Flink; pEntry = pEntry->Flink;
} }
if (!found && nfs41_fobx->deleg_type) { if (!found && nfs41_fobx->deleg_type) {
nfs41_srvopen_list_entry *oentry; nfs41_fcb_list_entry *oentry;
DbgP("enable_caching: delegation recalled: srv_open=%p\n", SrvOpen); DbgP("enable_caching: delegation recalled: srv_open=%p\n", SrvOpen);
oentry = RxAllocatePoolWithTag(NonPagedPool, oentry = RxAllocatePoolWithTag(NonPagedPool,
sizeof(nfs41_srvopen_list_entry), NFS41_MM_POOLTAG); sizeof(nfs41_fcb_list_entry), NFS41_MM_POOLTAG);
if (oentry == NULL) return; if (oentry == NULL) return;
oentry->srv_open = SrvOpen; oentry->fcb = SrvOpen->pFcb;
oentry->session = session;
oentry->nfs41_fobx = nfs41_fobx; oentry->nfs41_fobx = nfs41_fobx;
oentry->ChangeTime = ChangeTime; oentry->ChangeTime = ChangeTime;
oentry->skip = FALSE; oentry->skip = FALSE;
InsertTailList(&openlist->head, &oentry->next); InsertTailList(&openlist->head, &oentry->next);
nfs41_fobx->deleg_type = 0; nfs41_fobx->deleg_type = 0;
} }
ExReleaseFastMutex(&srvopenLock); ExReleaseFastMutex(&fcblistLock);
} }
NTSTATUS map_readwrite_errors( NTSTATUS map_readwrite_errors(
@ -5211,7 +5214,8 @@ NTSTATUS nfs41_Read(
!(SrvOpen->BufferingFlags & !(SrvOpen->BufferingFlags &
(FCB_STATE_READBUFFERING_ENABLED | (FCB_STATE_READBUFFERING_ENABLED |
FCB_STATE_READCACHING_ENABLED)))) { FCB_STATE_READCACHING_ENABLED)))) {
enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr); enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
pVNetRootContext->session);
} }
} else { } else {
status = map_readwrite_errors(entry->status); status = map_readwrite_errors(entry->status);
@ -5313,9 +5317,10 @@ NTSTATUS nfs41_Write(
!(SrvOpen->BufferingFlags & !(SrvOpen->BufferingFlags &
(FCB_STATE_WRITEBUFFERING_ENABLED | (FCB_STATE_WRITEBUFFERING_ENABLED |
FCB_STATE_WRITECACHING_ENABLED)))) { FCB_STATE_WRITECACHING_ENABLED)))) {
enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr); enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
pVNetRootContext->session);
} else if (!nfs41_fobx->deleg_type) } else if (!nfs41_fobx->deleg_type)
nfs41_update_srvopen_list(SrvOpen, entry->u.ReadWrite.ChangeTime); nfs41_update_fcb_list(RxContext->pFcb, entry->u.ReadWrite.ChangeTime);
} else { } else {
status = map_readwrite_errors(entry->status); status = map_readwrite_errors(entry->status);
@ -5971,8 +5976,8 @@ NTSTATUS nfs41_init_ops()
#define MILLISECONDS(milli) (((signed __int64)(milli)) * MICROSECONDS(1000L)) #define MILLISECONDS(milli) (((signed __int64)(milli)) * MICROSECONDS(1000L))
#define SECONDS(seconds) (((signed __int64)(seconds)) * MILLISECONDS(1000L)) #define SECONDS(seconds) (((signed __int64)(seconds)) * MILLISECONDS(1000L))
KSTART_ROUTINE srvopen_main; KSTART_ROUTINE fcbopen_main;
VOID srvopen_main(PVOID ctx) VOID fcbopen_main(PVOID ctx)
{ {
NTSTATUS status; NTSTATUS status;
LARGE_INTEGER timeout; LARGE_INTEGER timeout;
@ -5981,33 +5986,29 @@ VOID srvopen_main(PVOID ctx)
timeout.QuadPart = RELATIVE(SECONDS(30)); timeout.QuadPart = RELATIVE(SECONDS(30));
while(1) { while(1) {
PLIST_ENTRY pEntry; PLIST_ENTRY pEntry;
nfs41_srvopen_list_entry *cur; nfs41_fcb_list_entry *cur;
status = KeDelayExecutionThread(KernelMode, TRUE, &timeout); status = KeDelayExecutionThread(KernelMode, TRUE, &timeout);
ExAcquireFastMutex(&srvopenLock); ExAcquireFastMutex(&fcblistLock);
pEntry = openlist->head.Flink; pEntry = openlist->head.Flink;
while (!IsListEmpty(&openlist->head)) { while (!IsListEmpty(&openlist->head)) {
PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext;
PNFS41_NETROOT_EXTENSION pNetRootContext; PNFS41_NETROOT_EXTENSION pNetRootContext;
nfs41_updowncall_entry *entry; nfs41_updowncall_entry *entry;
FILE_BASIC_INFORMATION binfo; FILE_BASIC_INFORMATION binfo;
PNFS41_FCB nfs41_fcb; PNFS41_FCB nfs41_fcb;
cur = (nfs41_srvopen_list_entry *)CONTAINING_RECORD(pEntry, cur = (nfs41_fcb_list_entry *)CONTAINING_RECORD(pEntry,
nfs41_srvopen_list_entry, next); nfs41_fcb_list_entry, next);
DbgP("srvopen_main: Checking attributes for srv_open=%p " DbgP("fcbopen_main: Checking attributes for fcb=%p "
"change_time=%llu skipping=%d\n", cur->srv_open, "change_time=%llu skipping=%d\n", cur->fcb,
cur->ChangeTime, cur->skip); cur->ChangeTime, cur->skip);
if (cur->skip) goto out; if (cur->skip) goto out;
pVNetRootContext =
NFS41GetVNetRootExtension(cur->srv_open->pVNetRoot);
pNetRootContext = pNetRootContext =
NFS41GetNetRootExtension(cur->srv_open->pVNetRoot->pNetRoot); NFS41GetNetRootExtension(cur->fcb->pNetRoot);
/* place an upcall for this srv_open */ /* place an upcall for this srv_open */
status = nfs41_UpcallCreate(NFS41_FILE_QUERY, status = nfs41_UpcallCreate(NFS41_FILE_QUERY,
&cur->nfs41_fobx->sec_ctx, pVNetRootContext->session, &cur->nfs41_fobx->sec_ctx, cur->session,
cur->nfs41_fobx->nfs41_open_state, cur->nfs41_fobx->nfs41_open_state,
pNetRootContext->nfs41d_version, pNetRootContext->nfs41d_version, NULL, &entry);
cur->srv_open->pAlreadyPrefixedName, &entry);
if (status) if (status)
goto out; goto out;
entry->u.QueryFile.InfoClass = FileBasicInformation; entry->u.QueryFile.InfoClass = FileBasicInformation;
@ -6020,26 +6021,44 @@ VOID srvopen_main(PVOID ctx)
} }
if (cur->ChangeTime != entry->u.QueryFile.ChangeTime) { if (cur->ChangeTime != entry->u.QueryFile.ChangeTime) {
ULONG flag = DISABLE_CACHING; ULONG flag = DISABLE_CACHING;
DbgP("srvopen_main: old ctime=%llu new_ctime=%llu\n", PMRX_SRV_OPEN srv_open;
PLIST_ENTRY psrvEntry;
DbgP("fcbopen_main: old ctime=%llu new_ctime=%llu\n",
cur->ChangeTime, entry->u.QueryFile.ChangeTime); cur->ChangeTime, entry->u.QueryFile.ChangeTime);
DbgP("srvopen_main: ************ Invalidate the cache for %wZ "
"************\n", cur->srv_open->pAlreadyPrefixedName);
RxChangeBufferingState((PSRV_OPEN)cur->srv_open,
ULongToPtr(flag), 1);
cur->ChangeTime = entry->u.QueryFile.ChangeTime; cur->ChangeTime = entry->u.QueryFile.ChangeTime;
cur->skip = TRUE; cur->skip = TRUE;
psrvEntry = &cur->fcb->SrvOpenList;
psrvEntry = psrvEntry->Flink;
while (!IsListEmpty(&cur->fcb->SrvOpenList)) {
srv_open = (PMRX_SRV_OPEN)CONTAINING_RECORD(psrvEntry,
MRX_SRV_OPEN, SrvOpenQLinks);
if (srv_open->DesiredAccess &
(FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)) {
DbgP("fcbopen_main: ************ Invalidate the cache %wZ"
"************\n", srv_open->pAlreadyPrefixedName);
RxIndicateChangeOfBufferingStateForSrvOpen(
cur->fcb->pNetRoot->pSrvCall, srv_open,
srv_open->Key, ULongToPtr(flag));
}
if (psrvEntry->Flink == &cur->fcb->SrvOpenList) {
DbgP("fcbopen_main: reached end of srvopen for fcb %p\n",
cur->fcb);
break;
}
pEntry = pEntry->Flink;
};
} }
nfs41_fcb = (PNFS41_FCB)cur->srv_open->pFcb->Context; nfs41_fcb = (PNFS41_FCB)cur->fcb->Context;
nfs41_fcb->changeattr = entry->u.QueryFile.ChangeTime; nfs41_fcb->changeattr = entry->u.QueryFile.ChangeTime;
RxFreePool(entry); RxFreePool(entry);
out: out:
if (pEntry->Flink == &openlist->head) { if (pEntry->Flink == &openlist->head) {
DbgP("srvopen_main: reached end of the list\n"); DbgP("fcbopen_main: reached end of the fcb list\n");
break; break;
} }
pEntry = pEntry->Flink; pEntry = pEntry->Flink;
} }
ExReleaseFastMutex(&srvopenLock); ExReleaseFastMutex(&fcblistLock);
} }
DbgEx(); DbgEx();
} }
@ -6104,7 +6123,7 @@ NTSTATUS DriverEntry(
ExInitializeFastMutex(&downcallLock); ExInitializeFastMutex(&downcallLock);
ExInitializeFastMutex(&xidLock); ExInitializeFastMutex(&xidLock);
ExInitializeFastMutex(&openOwnerLock); ExInitializeFastMutex(&openOwnerLock);
ExInitializeFastMutex(&srvopenLock); ExInitializeFastMutex(&fcblistLock);
upcall = RxAllocatePoolWithTag(NonPagedPool, sizeof(nfs41_updowncall_list), upcall = RxAllocatePoolWithTag(NonPagedPool, sizeof(nfs41_updowncall_list),
NFS41_MM_POOLTAG); NFS41_MM_POOLTAG);
if (upcall == NULL) if (upcall == NULL)
@ -6117,7 +6136,7 @@ NTSTATUS DriverEntry(
goto out_unregister; goto out_unregister;
} }
InitializeListHead(&downcall->head); InitializeListHead(&downcall->head);
openlist = RxAllocatePoolWithTag(NonPagedPool, sizeof(nfs41_srvopen_list), openlist = RxAllocatePoolWithTag(NonPagedPool, sizeof(nfs41_fcb_list),
NFS41_MM_POOLTAG); NFS41_MM_POOLTAG);
if (openlist == NULL) { if (openlist == NULL) {
RxFreePool(upcall); RxFreePool(upcall);
@ -6127,7 +6146,7 @@ NTSTATUS DriverEntry(
InitializeListHead(&openlist->head); InitializeListHead(&openlist->head);
InitializeObjectAttributes(&oattrs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); InitializeObjectAttributes(&oattrs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = PsCreateSystemThread(&dev_exts->openlistHandle, mask, status = PsCreateSystemThread(&dev_exts->openlistHandle, mask,
&oattrs, NULL, NULL, &srvopen_main, NULL); &oattrs, NULL, NULL, &fcbopen_main, NULL);
if (status != STATUS_SUCCESS) { if (status != STATUS_SUCCESS) {
RxFreePool(upcall); RxFreePool(upcall);
RxFreePool(downcall); RxFreePool(downcall);