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