Writing to file having Locks

Hi,
We have a HSM product and archives data to low cost storage. When user
access the data we recall the data from storage. We do this when we get
FIRST data reads in filter driver. Since the application already has a
handle, we use kernel handle to write the data back to local disk after
recalling from backend. This work fine but the problem occurs when file is
locked by the application. In that case, we are able to get the kernel
handle but when we write to file using that handle we get error 33 in user
mode which is *ERROR_LOCK_VIOLATION*. Is there any way we can write the
data to file which is locked. We use FltCreateFileEx()
with IO_IGNORE_SHARE_ACCESS_CHECK flag. Also, if user opens the file in
APPEND mode then also do we get READ request before WRITE request.

Ash

Byte range locks are not enforced for paging I/O. This means you can either use a mapping of the file (which will only do paging I/O operations) or you can explicitly request paging I/O operations from filter manager.

Tony
OSR

Hi Tony,
I did some research on your advice but I found from the documentation of
LockFileEx at
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx

“Locking a region of a file does not prevent reading from a mapped file
view.” So does that mean I cannot still write to locked byte region ?

Can we handle IRP_MJ_LOCK_CONTROL and recall the file from backend ? Do you
see any issues with that as file recalls from backend are synchronous?

Thanks
Ash

On Fri, Oct 25, 2013 at 6:01 AM, Tony Mason wrote:

> Byte range locks are not enforced for paging I/O. This means you can
> either use a mapping of the file (which will only do paging I/O operations)
> or you can explicitly request paging I/O operations from filter manager.
>

>
> ****
>
> Tony
>
> OSR

>
> ****
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Actually, there is no enforcement of byte range locks for read or write in the paging I/O path. You can see this in the FastFat code example. Here is the relevant piece from the write path:

if (!PagingIo && TypeOfOpen == UserFileOpen) {

Status = FsRtlCheckOplock( FatGetFcbOplock(FcbOrDcb),
Irp,
IrpContext,
FatOplockComplete,
FatPrePostIrp );

if (Status != STATUS_SUCCESS) {

OplockPostIrp = TRUE;
PostIrp = TRUE;
try_return( NOTHING );
}

//
// This oplock call can affect whether fast IO is possible.
// We may have broken an oplock to no oplock held. If the
// current state of the file is FastIoIsNotPossible then
// recheck the fast IO state.
//

if (FcbOrDcb->Header.IsFastIoPossible == FastIoIsNotPossible) {

FcbOrDcb->Header.IsFastIoPossible = FatIsFastIoPossible( FcbOrDcb );
}

//
// And finally check the regular file locks.
//

if (!FsRtlCheckLockForWriteAccess( &FcbOrDcb->Specific.Fcb.FileLock, Irp )) {

try_return( Status = STATUS_FILE_LOCK_CONFLICT );
}

Note that the call to FsRtlCheckLockForWriteAccess is only made if this is NOT paging I/O.

Tony
OSR

Thanks Tony,
I will give this a try. Using MappedView looks less complicated then
handling IRP_MJ_LOCK_CONTROL

On Sat, Oct 26, 2013 at 5:43 PM, Tony Mason wrote:

> Actually, there is no enforcement of byte range locks for read or write in
> the paging I/O path. You can see this in the FastFat code example. Here
> is the relevant piece from the write path:
>
>
**
>
> if (!PagingIo && TypeOfOpen == UserFileOpen) {

>
> ****
>
> Status = FsRtlCheckOplock( FatGetFcbOplock(FcbOrDcb),
>
> Irp,

>
> IrpContext,
>
> FatOplockComplete,

>
> FatPrePostIrp );
>
>
**
>
> if (Status != STATUS_SUCCESS) {

>
> ****
>
> OplockPostIrp = TRUE;
>
> PostIrp = TRUE;

>
> try_return( NOTHING );
>
> }

>
> ****
>
> //
>
> // This oplock call can affect whether fast IO is
> possible.

>
> // We may have broken an oplock to no oplock held. If the
>
>
> // current state of the file is FastIoIsNotPossible then

>

>
> // recheck the fast IO state.
>
> //

>
> ****
>
> if (FcbOrDcb->Header.IsFastIoPossible ==
> FastIoIsNotPossible) {
>
>
**
>
> FcbOrDcb->Header.IsFastIoPossible =
> FatIsFastIoPossible( FcbOrDcb );

>
> }
>
>

>
> //

>
> // And finally check the regular file locks.
>
> //

>
> ****
>
> if (!FsRtlCheckLockForWriteAccess(
> &FcbOrDcb->Specific.Fcb.FileLock, Irp )) {
>
>
**
>
> try_return( Status = STATUS_FILE_LOCK_CONFLICT );

>
> }
>
>

>
> Note that the call to FsRtlCheckLockForWriteAccess is only made if this is
> NOT paging I/O.

>
> ****
>
> Tony
>
> OSR

>
> ****
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>