Hi Tom,

cache INVALIDATION is only needed because the BUFFERS cache
might have stale data that are not yet on disk.
It's a brute force clutch, not a real solution.

Scary. How about triggering a kernel panic if a dirty
buffer is detected to contain one of the sectors which
was about to be written by int26 or int 21.7305?

Because if you let DOSLFN and similar tools overwrite
sectors you were ABOUT to write but they did not KNOW
were going to be modified by the kernel once, it is
likely that MANY sectors will be affected over time
if you do not "notice the hard way" when something is
doing concurrent writes.

The solution should be to use the same BUFFERS cache for both
internal mk_dir etc. operations, and external lfn_mkdir operations.

Yes and no...

You could let all int25 and 21.7305 raw disk reads trigger
a forced write-back of all dirty buffers BEFORE allowing
the raw disk READ to happen, to enforce consistency.

You could also check WHICH raw sectors are going to be
read and only ensure pending writes of THOSE are going
to be written to disk before the raw disk read happens.

I would NOT pipeline all raw disk reads and writes through
our tiny set of BUFFERS. They are not meant to handle that
amount of data and performance could get disappointing.

I suggest that raw writes should not FILL buffers,
but only UPDATE buffers for those sectors which
already happen to be in the buffers.

This happens automagically in the current context as DOSLFN newer
writes sector data, but always read/modify/writes data.
So data written to are already in the cache, read microseconds before.

That is exactly what I suggested to avoid:

My suggestion was to only UPDATE buffer contents if DOS
finds out that a raw int26 or int21.7305 disk write will
write to one of the sectors currently present in BUFFERS.

However, if a raw write will write to a sector which is
NOT present in the buffers, then that sector should NOT
be added to the buffers, because this would needlessly
push out typically more useful data previously held by
that buffer.

Also, if a raw READ happens, as explained above, the ONLY
thing I would do is to ensure that the read sees the state
after a possibly dirty buffer for exactly that sector got
written to disk, to ensure consistency.

If a raw read will read a sector which is NOT present in
the buffers, then that sector should NOT be loaded into
a buffer, for the same reasons as in the raw write case.

i.e. treat external int2526_handler reads/writes like internal mk_dir
reads/writes, while observing the int21_fat32 (dir, fat, data)
destination. basically cache dir and fat calls, don't cache data or unknown.

While limiting the "forced pipelining through BUFFERS" to
dir and fat data reduces the side-effects discussed above,
it has the problem that int 26 does not actually KNOW what
type (dir, fat, data) a sector is and int 21.7305 has to
BELIEVE the type indication provided by the caller, which
may or may not be correct. Actually computing the type can
be quite a bit of overhead. And, again, I do not think that
int 25/26 and int 21.7305 raw sector reads and writes should
be pipelined through the entire BUFFERS system. I suggest to
limit the interaction to a minimum required for consistency.

To be on the safe side, it would already be enough to do the
full cache invalidation for the affected drive for each raw
disk read AND write, both failed and successful ones. This
will of course hurt performance, but at least it makes sure
that there will be no filesystem corruption.

So this is what I suggested in my earlier mail.

A better solution would be the one described above, based
on your warning about unwritten dirty buffers colliding
with raw writes of data based on raw reads which should
have seen the state AFTER writing those dirty buffers to
disk instead of the state BEFORE, to avoid "change loss".

Thoughts about write-combining:

leave write_combining for another day.

I totally agree.

Given that most kernel activities which create dirty
buffers end with writing all dirty buffers back to disk,
which scenarios currently trigger DOSLFN risks where
DOSLFN reads OLD data from disk, making it accidentally
rollback pending changes when it later writes updated
data to disk without having used the pending changes?

I still think that a big part of the solution would be
changing int2526_handler and int21_fat32 to ALWAYS
call setinvld instead of letting it depend on whether
the disk access has failed or succeeded.

A more elegant solution could be to call setinvld in
dskxfer itself, instead of the current implementation
where two functions call it after THEY called dskxfer.

Regards, Eric




_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to