xref: /reactos/drivers/filesystems/ext2/src/lock.c (revision 40462c92)
1 /*
2  * COPYRIGHT:        See COPYRIGHT.TXT
3  * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
4  * FILE:             lock.c
5  * PROGRAMMER:       Matt Wu <mattwu@163.com>
6  * HOMEPAGE:         http://www.ext2fsd.com
7  * UPDATE HISTORY:
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "ext2fs.h"
13 
14 /* GLOBALS ***************************************************************/
15 
16 extern PEXT2_GLOBAL Ext2Global;
17 
18 /* DEFINITIONS *************************************************************/
19 
20 #ifdef ALLOC_PRAGMA
21 #pragma alloc_text(PAGE, Ext2LockControl)
22 #endif
23 
24 NTSTATUS
25 Ext2LockControl (IN PEXT2_IRP_CONTEXT IrpContext)
26 {
27     PDEVICE_OBJECT  DeviceObject = NULL;
28     PFILE_OBJECT    FileObject = NULL;
29     PEXT2_FCB       Fcb = NULL;
30     PIRP            Irp = NULL;
31 
32     NTSTATUS        Status = STATUS_UNSUCCESSFUL;
33     BOOLEAN         CompleteContext = TRUE;
34     BOOLEAN         CompleteIrp = TRUE;
35     BOOLEAN         bFcbAcquired = FALSE;
36 
37     _SEH2_TRY {
38 
39         ASSERT(IrpContext != NULL);
40 
41         ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
42                (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
43 
44         DeviceObject = IrpContext->DeviceObject;
45 
46         if (IsExt2FsDevice(DeviceObject)) {
47             Status = STATUS_INVALID_DEVICE_REQUEST;
48             _SEH2_LEAVE;
49         }
50 
51         FileObject = IrpContext->FileObject;
52 
53         Fcb = (PEXT2_FCB) FileObject->FsContext;
54         ASSERT(Fcb != NULL);
55         if (Fcb->Identifier.Type == EXT2VCB) {
56             Status = STATUS_INVALID_PARAMETER;
57             _SEH2_LEAVE;
58         }
59 
60         ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
61                (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
62 
63         if (FlagOn(Fcb->Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
64             Status = STATUS_INVALID_PARAMETER;
65             _SEH2_LEAVE;
66         }
67 
68         ExAcquireResourceSharedLite(&Fcb->MainResource, TRUE);
69         bFcbAcquired = TRUE;
70 
71         Irp = IrpContext->Irp;
72 
73         CompleteIrp = FALSE;
74 
75         Status = FsRtlCheckOplock( &Fcb->Oplock,
76                                    Irp,
77                                    IrpContext,
78                                    Ext2OplockComplete,
79                                    NULL );
80 
81         if (Status != STATUS_SUCCESS) {
82             CompleteContext = FALSE;
83             _SEH2_LEAVE;
84         }
85 
86         //
87         // FsRtlProcessFileLock acquires FileObject->FsContext->Resource while
88         // modifying the file locks and calls IoCompleteRequest when it's done.
89         //
90 
91         Status = FsRtlProcessFileLock(
92                      &Fcb->FileLockAnchor,
93                      Irp,
94                      NULL );
95 #if EXT2_DEBUG
96         if (!NT_SUCCESS(Status)) {
97             DEBUG(DL_ERR, (
98                       "Ext2LockControl: %-16.16s %-31s Status: %#x ***\n",
99                       Ext2GetCurrentProcessName(),
100                       "IRP_MJ_LOCK_CONTROL",
101                       Status          ));
102         }
103 #endif
104         Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
105 
106     } _SEH2_FINALLY {
107 
108         if (bFcbAcquired) {
109             ExReleaseResourceLite(&Fcb->MainResource);
110         }
111 
112         if (!IrpContext->ExceptionInProgress) {
113 
114             if (!CompleteIrp) {
115                 IrpContext->Irp = NULL;
116             }
117 
118             if (CompleteContext) {
119                 Ext2CompleteIrpContext(IrpContext, Status);
120             }
121         }
122     } _SEH2_END;
123 
124     return Status;
125 }
126