Tony is correct as usual.
The only thing I can add to this discussion is that kernel components
will frequently *not* assert that their callers are in error. To do so
would add unnecessary overhead to the retail (debugged) system, and is
why the checked system is provided. Ommision of the safety net is in no
way a bug, we assume correctness. This is the kernel.
This is an excellent example of where a kernel verifier layer for Cc
would be useful.
-----Original Message-----
From: Hrdina Pavel [mailto:xxxxx@COMPELSON.COM]
Sent: Tuesday, October 10, 2000 7:22 AM
To: File Systems Developers
Subject: [ntfsd] RE: Assertion failed in cachesub.c
Importance: High
I agree with your explanation but some things are then unclear to me.
Why the CcInitializeCacheMap could then accept parameter where
AllocationSize < FileSize in FileSizes structure ?
This implies later page fault in MmMapViewInSystemCache in the following
scenario.
Let the
ValidDataLength = FileSize
and
ALIGN_UP(AllocationSize, VACB_MAPPING_GRANULARITY) <
ALIGN_UP(FileSize, VACB_MAPPING_GRANULARITY)
Then if you try to access the region in cache whose any part is
remaining
above the aligned AllocationSize (which is correct because there must be
valid data in the cache because this offset is still less than or equal
to FileSize
and ValidDataLength) the page fault in MmMapViewInSystemCache occurs.
Explanation:
The cache manager tries to map tve VACB for this region to the system
cache address space and thus calls the MmMapViewInSystemSpace.
This routine performs some checks (but unfortunately not SectionOffset
- ViewSize must be less than SectionSize) and then tries to reach the
SUBSECTION, mapping the region, starting in CONTROL_AREA.
But the last subsection has the next subsection pointer NULL and
thus the next iteration of the search loop will try to access offset
in the range 0 to sizeof(SUBSECTION). And this must always be below
MM_LOWEST_USER_ADDRESS, thus generating page fault.
So missing of the lines in code I have already shown in the previous
mail
(or at least check and raise some invalid status) I must call
programmer’s error
and thus BUG.
Paul
-----Original Message-----
From: xxxxx@lists.osr.com [
mailto:xxxxx@lists.osr.com]On Behalf Of Tony Mason
Sent: Tuesday, October 10, 2000 3:32 PM
To: File Systems Developers
Subject: [ntfsd] RE: Assertion failed in cachesub.c
The VM system has worked this way since (at least) 3.1. I know that I
talk
about this behavior (the allocation size, file size, and valid data
length)
in my file systems class.
When the VM system creates a section (and this is the Memory Manager) it
relies upon the Allocation Size to establish the size of the section.
The
file size then defines the end of the defined data region (so anything
beyond that file size is zeroed before the page is mapped into an
application’s address space.) Thus, you could start out with a file
that
has a LARGE “allocation size” but no data. The VM system would then
allow
the application to write into the mapped region, all the way up to the
full
size of the section.
The “bug” here is that you are relying upon the English meaning of the
word
“Allocation Size”. As is frequently the case in programming, we choose
mnemonic names for variables but later the use of those variables
becomes
inconsistent with the mnemonic name. Witness my favorite victim for
this
particular point: Fast I/O (which, may not be fast and frequently has
NOTHING whatsoever to do with I/O.) It is unfortunate, and it makes
programming file systems more difficult, but relying upon the name of a
variable as a form of documentation about how the variable is used is
unreliable.
Or, I suppose one could argue that your interpretation of
“AllocationSize”
is incorrect - that this has to do with the amount of section space that
must be allocated to contain the file, not the file system’s allocation
of
space. I think that’s a fairly poor alternative, but to call it a “bug”
simply because it doesn’t work the way you think it works is also quite
harsh.
In Windows 2000 there is an API that allows application programs to
query
the amount of on-disk storage allocated for a file; this is unrelated to
the
value stored in the AllocationSize field of the common header.
So, the rule I use is:
AllocationSize >= FileSize >= ValidDataLength
You can “get away” with ValidDataLength > FileSize, but it causes
unnecessary page fault behavior. You cannot, however, “get away” with
AllocationSize < FileSize. That eventually leads to problems, as you
have a
section (a container of information in the VM system) that is smaller
than
the amount of data stored within it (the FileSize.) It is like trying
to
put 10 kilos of rocks in a 5 kilo bag…
Regards,
Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com < http://www.osr.com>
You are currently subscribed to ntfsd as: xxxxx@compelson.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)