Hi all,
I have the NT4 FS filter driver which filters all of the on-disk
filesystems.
I have a nasty bug - opening My Computer window just after the first logon
(without waiting for a disk activity to finish) - leads to
DEVICE_REFERENCE_COUNT_NOT_ZERO bugcheck.
The investigation have shown the following:
- this occurs when the Cdfs recognizer in Fs_Rec.sys loads the Cdfs
filesystem.
- the recognizer calls IoUnregisterFileSystem twice for its own recognizer
device object during loading of Cdfs.
- surely, each IoUnregisterFileSystem call leads to FsNotification callback
in my filter. First time it is called with DeviceObject->ReferenceCount ==
2, second time it is called with DeviceObject->ReferenceCount == 0 - which
is a source of the bug. This is because after calling FsNotification
callbacks, IoUnregisterFileSystem decrements the reference count for the
device - this time - from 0 to -1 (a bug).
- then Fs_Rec unloads (having FAT+NTFS+CDFS - all recognized FSDs - loaded)
and calls IoDeleteDevice for all its device objects. Since the Cdfs
recognizer has ReferenceCount == -1 at this moment - a bugcheck occurs.
- I have tried SFilter sample from MS in the same scenario. Yes, Fs_Rec
still calls IoUnregisterFileSystem twice on Cdfs load. But - first time
with ReferenceCount == 3, second time with ReferenceCount == 1, which is
absolulely OK (on more reference is dropped in IopLoadFileSystemDriver
function in the kernel) and leads to ReferenceCount == 0 at the end of the
scenario.
- currently, I have a workaround by incrementing the reference count in my
FsNotification routine (unload path) to 1 if it is 0 using
InterlockedCompareExchange. I don’t like this dirty way.
Have anybody meet this problem? My IRP_MN_LOAD_FILE_SYSTEM paths are the
same as in SFilter.
regards,
Max
>I have tried SFilter sample from MS in the same scenario. Yes, Fs_Rec
still calls IoUnregisterFileSystem twice on Cdfs load. But - first
time with ReferenceCount == 3, second time with ReferenceCount == 1,
which is absolulely OK
why is it called twice on CDFS load decrementing the Ref count to 1 ?
i don’t understand this…
regds
RB
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Maxim S. Shatskih
Sent: Tuesday, July 25, 2000 11:04 AM
To: File Systems Developers
Subject: [ntfsd] Filter driver problem with the Cdfs recognizer
Hi all,
I have the NT4 FS filter driver which filters all of the on-disk
filesystems.
I have a nasty bug - opening My Computer window just after the first logon
(without waiting for a disk activity to finish) - leads to
DEVICE_REFERENCE_COUNT_NOT_ZERO bugcheck.
The investigation have shown the following:
- this occurs when the Cdfs recognizer in Fs_Rec.sys loads the Cdfs
filesystem.
- the recognizer calls IoUnregisterFileSystem twice for its own recognizer
device object during loading of Cdfs.
- surely, each IoUnregisterFileSystem call leads to FsNotification callback
in my filter. First time it is called with DeviceObject->ReferenceCount ==
2, second time it is called with DeviceObject->ReferenceCount == 0 - which
is a source of the bug. This is because after calling FsNotification
callbacks, IoUnregisterFileSystem decrements the reference count for the
device - this time - from 0 to -1 (a bug).
- then Fs_Rec unloads (having FAT+NTFS+CDFS - all recognized FSDs - loaded)
and calls IoDeleteDevice for all its device objects. Since the Cdfs
recognizer has ReferenceCount == -1 at this moment - a bugcheck occurs.
- I have tried SFilter sample from MS in the same scenario. Yes, Fs_Rec
still calls IoUnregisterFileSystem twice on Cdfs load. But - first time
with ReferenceCount == 3, second time with ReferenceCount == 1, which is
absolulely OK (on more reference is dropped in IopLoadFileSystemDriver
function in the kernel) and leads to ReferenceCount == 0 at the end of the
scenario.
- currently, I have a workaround by incrementing the reference count in my
FsNotification routine (unload path) to 1 if it is 0 using
InterlockedCompareExchange. I don’t like this dirty way.
Have anybody meet this problem? My IRP_MN_LOAD_FILE_SYSTEM paths are the
same as in SFilter.
regards,
Max
You are currently subscribed to ntfsd as: xxxxx@softhome.net
To unsubscribe send a blank email to $subst(‘Email.Unsub’)
> >I have tried SFilter sample from MS in the same scenario. Yes, Fs_Rec
>still calls IoUnregisterFileSystem twice on Cdfs load. But - first
>time with ReferenceCount == 3, second time with ReferenceCount == 1,
>which is absolulely OK
why is it called twice on CDFS load decrementing the Ref count to 1 ?
First decrement is in IoUnregisterFileSystem itself, the second one is in
the mount path of the IO manager.
I have found the cause. This seems to be the bug in NT4. IopMountVolume
sometimes manipulates the top-of-stack device reference count instead of
base device. This looks very strange - what is the need of ever
adjusting the reference count for the device other than the base one of the
attachment stack?
Patch in my MountCompletion routine have solved the problem.
The patch is (add this to “mount failed” path):
if( Irp->IoStatus.Status == STATUS_FS_DRIVER_REQUIRED )
InterlockedIncrement(&(DeviceExtension->TargetDeviceObject->ReferenceCount))
;
Max
Hi Maxim!
I have reached the same problem you have, but I don’t have solved
it yet. If you have some new informations about it please let me know.
The same thing you may expect from me.
Thanks
Paul
-----P?vodn? zpr?va-----
Od: Maxim S. Shatskih [SMTP:xxxxx@storagecraft.com]
Odesl?no: 25. ?ervence 2000 7:34
Komu: File Systems Developers
P?edm?t: [ntfsd] Filter driver problem with the Cdfs recognizer
Hi all,
I have the NT4 FS filter driver which filters all of the on-disk
filesystems.
I have a nasty bug - opening My Computer window just after the first logon
(without waiting for a disk activity to finish) - leads to
DEVICE_REFERENCE_COUNT_NOT_ZERO bugcheck.
The investigation have shown the following:
- this occurs when the Cdfs recognizer in Fs_Rec.sys loads the Cdfs
filesystem.
- the recognizer calls IoUnregisterFileSystem twice for its own
recognizer
device object during loading of Cdfs.
- surely, each IoUnregisterFileSystem call leads to FsNotification
callback
in my filter. First time it is called with DeviceObject->ReferenceCount ==
2, second time it is called with DeviceObject->ReferenceCount == 0 - which
is a source of the bug. This is because after calling FsNotification
callbacks, IoUnregisterFileSystem decrements the reference count for the
device - this time - from 0 to -1 (a bug).
- then Fs_Rec unloads (having FAT+NTFS+CDFS - all recognized FSDs -
loaded)
and calls IoDeleteDevice for all its device objects. Since the Cdfs
recognizer has ReferenceCount == -1 at this moment - a bugcheck occurs.
- I have tried SFilter sample from MS in the same scenario. Yes, Fs_Rec
still calls IoUnregisterFileSystem twice on Cdfs load. But - first time
with ReferenceCount == 3, second time with ReferenceCount == 1, which is
absolulely OK (on more reference is dropped in IopLoadFileSystemDriver
function in the kernel) and leads to ReferenceCount == 0 at the end of the
scenario.
- currently, I have a workaround by incrementing the reference count in my
FsNotification routine (unload path) to 1 if it is 0 using
InterlockedCompareExchange. I don’t like this dirty way.
Have anybody meet this problem? My IRP_MN_LOAD_FILE_SYSTEM paths are the
same as in SFilter.
regards,
Max
You are currently subscribed to ntfsd as: xxxxx@sodatsw.cz
To unsubscribe send a blank email to $subst(‘Email.Unsub’)
I have found the cause of the problem. IopMountVolume bug.
They are dealing with the refcount of the TOP DO (for which IoCallDriver) is
called - which is IMHO contra-logical. I’m sure the intention was to deal
with the BASE DO refcount. In this case, all would be OK.
The workaround:
- in your mount completion routine, use the following code in case if the
Irp->IoStatus.Status is error:
if( Irp->IoStatus.Status == STATUS_FS_DRIVER_REQUIRED )
{
PVFP_FS_FILTER_DEVICE_EXTENSION DeviceExtension;
// Extract the device extension
DeviceExtension =
(PVFP_FS_FILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
// NOTE: NT bug
// IopMountVolume incorrectly addrefs the top attached device object
// instead of base one which will be then dereferenced
// Addref the recognizer’s device object here to work around the bug
InterlockedIncrement(&(DeviceExtension->TargetDeviceObject->ReferenceCount))
;
So, you addref the device object below you. The bug ceases.
BTW - I saw this bug in our another FS filter which was derived from SFilter
as close as possible. So, SFilter possibly has it too.
Max
----- Original Message -----
From: Pavel Hrdina
To: File Systems Developers
Sent: Tuesday, August 01, 2000 11:20 PM
Subject: [ntfsd] RE: Filter driver problem with the Cdfs recognizer
> Hi Maxim!
>
> I have reached the same problem you have, but I don’t have solved
> it yet. If you have some new informations about it please let me know.
> The same thing you may expect from me.
>
> Thanks
> Paul
>
> > -----Pùvodní zpráva-----
> > Od: Maxim S. Shatskih [SMTP:xxxxx@storagecraft.com]
> > Odesláno: 25. èervence 2000 7:34
> > Komu: File Systems Developers
> > Pøedmìt: [ntfsd] Filter driver problem with the Cdfs recognizer
> >
> > Hi all,
> >
> > I have the NT4 FS filter driver which filters all of the on-disk
> > filesystems.
> > I have a nasty bug - opening My Computer window just after the first
logon
> > (without waiting for a disk activity to finish) - leads to
> > DEVICE_REFERENCE_COUNT_NOT_ZERO bugcheck.
> >
> > The investigation have shown the following:
> > - this occurs when the Cdfs recognizer in Fs_Rec.sys loads the Cdfs
> > filesystem.
> > - the recognizer calls IoUnregisterFileSystem twice for its own
> > recognizer
> > device object during loading of Cdfs.
> > - surely, each IoUnregisterFileSystem call leads to FsNotification
> > callback
> > in my filter. First time it is called with DeviceObject->ReferenceCount
==
> > 2, second time it is called with DeviceObject->ReferenceCount == 0 -
which
> > is a source of the bug. This is because after calling FsNotification
> > callbacks, IoUnregisterFileSystem decrements the reference count for the
> > device - this time - from 0 to -1 (a bug).
> > - then Fs_Rec unloads (having FAT+NTFS+CDFS - all recognized FSDs -
> > loaded)
> > and calls IoDeleteDevice for all its device objects. Since the Cdfs
> > recognizer has ReferenceCount == -1 at this moment - a bugcheck occurs.
> > - I have tried SFilter sample from MS in the same scenario. Yes, Fs_Rec
> > still calls IoUnregisterFileSystem twice on Cdfs load. But - first
time
> > with ReferenceCount == 3, second time with ReferenceCount == 1, which is
> > absolulely OK (on more reference is dropped in IopLoadFileSystemDriver
> > function in the kernel) and leads to ReferenceCount == 0 at the end of
the
> > scenario.
> > - currently, I have a workaround by incrementing the reference count in
my
> > FsNotification routine (unload path) to 1 if it is 0 using
> > InterlockedCompareExchange. I don’t like this dirty way.
> >
> > Have anybody meet this problem? My IRP_MN_LOAD_FILE_SYSTEM paths are the
> > same as in SFilter.
> >
> > regards,
> > Max
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@sodatsw.cz
> > To unsubscribe send a blank email to $subst(‘Email.Unsub’)
>
> —
> You are currently subscribed to ntfsd as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to $subst(‘Email.Unsub’)
>
Thaks, Max !
But I think you should also decrement the reference count on the
top attached device object. If you don’t this there will be a bugcheck
in the IoDeleteDevice on this device object deletion. Or am I wrong ?
Paul
PS: And you should interlock the DO->ReferenceCount operations
by IopDatabseLock (KSPIN_LOCK) if you want to be absolutely
safe. But there is not a dirty-less method to obtain this pointer.
-----P?vodn? zpr?va-----
Od: Maxim S. Shatskih [SMTP:xxxxx@storagecraft.com]
Odesl?no: 1. srpna 2000 22:20
Komu: File Systems Developers
P?edm?t: [ntfsd] RE: Filter driver problem with the Cdfs recognizer
I have found the cause of the problem. IopMountVolume bug.
They are dealing with the refcount of the TOP DO (for which IoCallDriver)
is
called - which is IMHO contra-logical. I’m sure the intention was to deal
with the BASE DO refcount. In this case, all would be OK.
The workaround:
- in your mount completion routine, use the following code in case if the
Irp->IoStatus.Status is error:
if( Irp->IoStatus.Status == STATUS_FS_DRIVER_REQUIRED )
{
PVFP_FS_FILTER_DEVICE_EXTENSION DeviceExtension;
// Extract the device extension
DeviceExtension =
(PVFP_FS_FILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
// NOTE: NT bug
// IopMountVolume incorrectly addrefs the top attached device object
// instead of base one which will be then dereferenced
// Addref the recognizer’s device object here to work around the bug
InterlockedIncrement(&(DeviceExtension->TargetDeviceObject->ReferenceCount
))
;
So, you addref the device object below you. The bug ceases.
BTW - I saw this bug in our another FS filter which was derived from
SFilter
as close as possible. So, SFilter possibly has it too.
Max
----- Original Message -----
From: Pavel Hrdina
> To: File Systems Developers
> Sent: Tuesday, August 01, 2000 11:20 PM
> Subject: [ntfsd] RE: Filter driver problem with the Cdfs recognizer
>
>
> > Hi Maxim!
> >
> > I have reached the same problem you have, but I don’t have solved
> > it yet. If you have some new informations about it please let me know.
> > The same thing you may expect from me.
> >
> > Thanks
> > Paul
> >
> > > -----P?vodn? zpr?va-----
> > > Od: Maxim S. Shatskih [SMTP:xxxxx@storagecraft.com]
> > > Odesl?no: 25. ?ervence 2000 7:34
> > > Komu: File Systems Developers
> > > P?edm?t: [ntfsd] Filter driver problem with the Cdfs recognizer
> > >
> > > Hi all,
> > >
> > > I have the NT4 FS filter driver which filters all of the on-disk
> > > filesystems.
> > > I have a nasty bug - opening My Computer window just after the first
> logon
> > > (without waiting for a disk activity to finish) - leads to
> > > DEVICE_REFERENCE_COUNT_NOT_ZERO bugcheck.
> > >
> > > The investigation have shown the following:
> > > - this occurs when the Cdfs recognizer in Fs_Rec.sys loads the Cdfs
> > > filesystem.
> > > - the recognizer calls IoUnregisterFileSystem twice for its own
> > > recognizer
> > > device object during loading of Cdfs.
> > > - surely, each IoUnregisterFileSystem call leads to FsNotification
> > > callback
> > > in my filter. First time it is called with
> DeviceObject->ReferenceCount
> ==
> > > 2, second time it is called with DeviceObject->ReferenceCount == 0 -
> which
> > > is a source of the bug. This is because after calling FsNotification
> > > callbacks, IoUnregisterFileSystem decrements the reference count for
> the
> > > device - this time - from 0 to -1 (a bug).
> > > - then Fs_Rec unloads (having FAT+NTFS+CDFS - all recognized FSDs -
> > > loaded)
> > > and calls IoDeleteDevice for all its device objects. Since the Cdfs
> > > recognizer has ReferenceCount == -1 at this moment - a bugcheck
> occurs.
> > > - I have tried SFilter sample from MS in the same scenario. Yes,
> Fs_Rec
> > > still calls IoUnregisterFileSystem twice on Cdfs load. But - first
> time
> > > with ReferenceCount == 3, second time with ReferenceCount == 1, which
> is
> > > absolulely OK (on more reference is dropped in IopLoadFileSystemDriver
> > > function in the kernel) and leads to ReferenceCount == 0 at the end of
> the
> > > scenario.
> > > - currently, I have a workaround by incrementing the reference count
> in
> my
> > > FsNotification routine (unload path) to 1 if it is 0 using
> > > InterlockedCompareExchange. I don’t like this dirty way.
> > >
> > > Have anybody meet this problem? My IRP_MN_LOAD_FILE_SYSTEM paths are
> the
> > > same as in SFilter.
> > >
> > > regards,
> > > Max
> > >
> > >
> > > —
> > > You are currently subscribed to ntfsd as: xxxxx@sodatsw.cz
> > > To unsubscribe send a blank email to $subst(‘Email.Unsub’)
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@storagecraft.com
> > To unsubscribe send a blank email to $subst(‘Email.Unsub’)
> >
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@sodatsw.cz
> To unsubscribe send a blank email to $subst(‘Email.Unsub’)
> But I think you should also decrement the reference count on the
top attached device object. If you don’t this there will be a bugcheck
in the IoDeleteDevice on this device object deletion. Or am I wrong ?
No - it is decremented somewhere by the IO manager.
PS: And you should interlock the DO->ReferenceCount operations
by IopDatabseLock (KSPIN_LOCK) if you want to be absolutely
safe. But there is not a dirty-less method to obtain this pointer.
Surely. No chances of accessing this spinlock.
Max