Hi Tom,

thank you for the analysis that int 25/26 disk access
(and int 21.73 access) bypass the kernel BUFFERS cache.

Note that int21_fat32 (int 21.7305) would even get
disk area type flags (dir, fat, data) from the caller,
which would make it easier to "buffer" those calls.

I agree that you would get better performance when
raw writes just UPDATE buffer contents instead of
triggering full cache INVALIDATION. They would have
to loop over affected sectors and you would need a
new function similar to searchblock() but WITHOUT
the side effect of allocating new space in buffers:

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 would
keep the cache consistent, without flooding it.



Now for a much easier PARTIAL solution:

The problem is that int21_fat32 only calls setinvld
when dskxfer SUCCEEDS, while int2526_handler only
calls setinvld when dskxfer FAILED. Note that the
effect of setinvld is to invalidate ALL BUFFERS for
the affected drive. This is fast, but also throws
out cached data that may have helped performance.

We could just always call setinvld in dskxfer itself,
so neither int21_fat32 nor int2626_handler need to.



Thoughts about write-combining:

At the moment, dirty buffers can be created by: dos_mkdir,
extend_dir, dos_extend, dir_write_update etc., but also
link_fat, rwblock, write_fsinfo, and int21_fat32.
The rwblock call seems to be used only by DosRWSft?

MOST of those have in common that they end with calls
to flush_cache, writing back ALL dirty buffers for the
drive and making the functions file-system wise atomic.

You could postpone the flush_cache until the next
tick of some sort of "once per 2 seconds" timer or
until the next, say, app termination event, but you
will have to deal with reentrancy when using timers.

Regards, Eric

PS: reset_drive calls int 21.0d and 21.32, which do
1. flush() which calls flush1() in a loop and then
   network_redirector(REM_FLUSHALL) while flush_buffers()
   would ONLY call flush1() in a loop and NOT the redirector.
2. flush_buffers() which is redundant given the above,
   then mark disk as M_CHANGED, then call media_check()

The flush1() call simply flushes a single BUFFERS sector.
At least LBACACHE does not monitor int 21 calls, but it
will be fine with all the flushing activity, of course.



IMHO this is definitively a kernel bug, not a DOSLFN bug. Sure, ResetDrive 
works around the bug,
but the bug is still in the kernel.

I think the bug occurs because the (necessary) direct disk writes by DOSLFN, 
using INT 25/26,
are not synchronised to the internal BUFFERS cache.

The least the kernel should do is call internally the FlushCache when direct 
disk write (INT26) is
detected. This shouldn't be DOSLFNs job.

Better yet, it should flush the caches when direct disk access is detected.
>
Better yet, integrate disk reads/writes with it's own disk cache, providing 
HUGE speed improvements.
>
I have no idea how DOSLFN performs on MSDOS, but it certainly sucks on FreeDOS.

Of course the same applies for FAT32 partitions and int21/7305.




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

Reply via email to