Cc VDL Contract

Hi all,

I gave in and am implementing full Cc support using shadow file objects.

I have a question regarding the contract that is shared between the FSD and Cc regarding VDL in the common header.

I have been studying the FAT sources, and from my reading, FAT never updates VDL on behalf of the lazy writer, even when the lazy writer sets the new file size (set information w/ advance only set to true). I assume this is why FAT keeps both VDL and ValidDataToDisk.

So, my Q: Why wouldn’t the set information call with advance only update VDL? (That data is valid to disk). When does VDL get updated from a lazy write? I see some code in cleanup where ValidDataToDisk is reconciled with VDL but I would assume it would happen prior to that.

Thanks,
Matt

When you move EOF, you don’t need to move VDL. NTFS certainly does not
(and it records VDL persistently on disk.)

If Cc asks the file system to move the EOF (which, as I recall, was
still ignored by FAT last I looked - FAT knows what the right size is,
Cc does not until the FSD reports the sizes to Cc) there is no reason
for the FSD to move the VDL - after all, the cache manager isn’t “making
up” data to put into that region - that’s the FSD’s job.

In other words, a user application writes data; the FSD copies that data
into the Cache (CcCopyWrite.) The FSD knows what the VDL is at that
point. If Cc writes beyond VDL, it cannot be writing real data.

Here’s the code from the WLH FAT sample in the 6001 WDK (fileinfo.c):

//
// Do a special case here for the lazy write of file sizes.
//

if
(IoGetCurrentIrpStackLocation(Irp)->Parameters.SetFile.AdvanceOnly) {

//
// Only attempt this if the file hasn’t been “deleted on
close” and
// this is a good FCB.
//

if (!IsFileDeleted( IrpContext, Fcb ) && (Fcb->FcbCondition
== FcbGood)) {

PDIRENT Dirent = NULL;
PBCB DirentBcb;

//
// Never have the dirent filesize larger than the fcb
filesize
//

if (NewFileSize >= Fcb->Header.FileSize.LowPart) {

NewFileSize = Fcb->Header.FileSize.LowPart;
}

Note that FAT ignores the move of EOF in this case anyway. The way I
remember triggering this was to have an application (at the time it was
the MS-DOS “edit” utility) that did: open, write, close. This triggered
IRP_MJ_CREATE, IRP_MJ_WRITE, IRP_MJ_CLEANUP, IRP_MJ_SET_INFORMATION
(advance only, set eof), IRP_MJ_WRITE (paging)…

That set information would arrive with an EOF value of 4KB. If you
don’t ignore it, you end up moving EOF to 4KB. If your file system
doesn’t have persistent VDL (e.g., you move VDL out to EOF) you end up
with a 4KB file. In my case the file was only supposed to be 54 bytes
long.

It turns out that if we report the file sizes to Cc immediately.

So, at any rate, there’s no reason to move VDL in response to a lazy
write.

Tony
OSR

Thanks that all makes sense. I realized that my main confusion was from not reading the write case in FAT carefully enough. After a cached write, VDL is updated in the header, but only in non-cached is CcSetFileSizes called. Makes sense now. I had though from a quick read that VDL was only extended during write for non-cached.