duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit eac0ad4b5e4ec27c53d6084ab12561c020ac7184
parent e7388dbd184971836e2c0a92173ca5d46280683a
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Mon, 18 Jul 2022 20:51:26 -0400

fs/fat: fix shady business with read/write pos increases

Diffstat:
Mfs/fs/fat.fs | 4++--
Mfs/fs/fatlo.fs | 51++++++++++++++++++++++++++++-----------------------
Mfs/tests/fs/fat.fs | 6+++---
3 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/fs/fs/fat.fs b/fs/fs/fat.fs @@ -100,7 +100,7 @@ current to fatflush \ Write c to fcursor and advance the position by one, growing the file if \ needed. : fatputc ( c fcursor -- ) - dup >r FCUR_pos 1+ dup 1+ r@ fatgrow ( c newpos R:fcursor ) + dup >r FCUR_pos dup 1+ r@ fatgrow ( c newpos R:fcursor ) r@ fatseek r@ FCUR_flags 2 or ( dirty ) r@ FCUR_flags! ( c R:fcursor ) - r> FCUR_bufpos c! ; + r@ FCUR_bufpos c! 1 r> FCUR_pos+ ; diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs @@ -146,27 +146,31 @@ here const )fnbuf \ b1 = buffer is dirty \ 4b current cluster in buf 0=nothing. the cluster is not actually read \ until the first position of the cluster is needed. +\ 4b current cluster index, -1=nothing. \ 4b offset, on disk, of direntry \ 4b cur pos (offset from beginning of file) \ 4b file size \ Xb current cluster X=ClusterSize 10 const FCURSORCNT \ maximum number of opened files -: FCursorSize ClusterSize 20 + ; +: FCursorSize ClusterSize 24 + ; : FCUR_flags ( fcur -- n ) @ ; : FCUR_free? ( fcur -- f ) FCUR_flags not ; : FCUR_dirty? ( fcur -- f ) FCUR_flags 2 and ; : FCUR_flags! ( n fcur -- ) ! ; : FCUR_cluster ( fcur -- n ) 4 + @ ; : FCUR_cluster! ( n fcur -- ) 4 + ! ; -: FCUR_pos ( fcur -- n ) 12 + @ ; -: FCUR_pos! ( n fcur -- n ) 12 + ! ; -: FCUR_size ( fcur -- n ) 16 + @ ; -: FCUR_size! ( n fcur -- ) 16 + ! ; -: FCUR_buf( ( fcur -- a ) 20 + ; +: FCUR_clusteridx ( fcur -- n ) 8 + @ ; +: FCUR_clusteridx! ( n fcur -- n ) 8 + ! ; +: FCUR_pos ( fcur -- n ) 16 + @ ; +: FCUR_pos! ( n fcur -- n ) 16 + ! ; +: FCUR_pos+ ( n fcur -- ) 16 + +! ; +: FCUR_size ( fcur -- n ) 20 + @ ; +: FCUR_size! ( n fcur -- ) 20 + ! ; +: FCUR_buf( ( fcur -- a ) 24 + ; : FCUR_)buf ( fcur -- a ) FCUR_buf( ClusterSize + ; : FCUR_bufpos ( fcur -- a ) dup FCUR_pos ClusterSize mod swap FCUR_buf( + ; : FCUR_dirent ( fcur -- dirent ) - 8 + @ BPB_BytsPerSec /mod ( offset sec ) 1 readsector ( off ) fatbuf( + ; + 12 + @ BPB_BytsPerSec /mod ( offset sec ) 1 readsector ( off ) fatbuf( + ; : FCUR_cluster0 ( fcur -- cl ) FCUR_dirent DIR_Cluster ; create fcursors( FCursorSize FCURSORCNT * allot0 @@ -190,8 +194,9 @@ create fcursors( FCursorSize FCURSORCNT * allot0 : openfile ( direntry -- fcursor ) findfreecursor >r 0 r@ FCUR_cluster! ( dirent ) 1 r@ FCUR_flags! - dup fatbuf( - bufsec BPB_BytsPerSec * + ( dirent doffset ) r@ 8 + ! - -1 r@ 12 + ! DIR_FileSize r@ 16 + ! ( ) r> ; + dup fatbuf( - bufsec BPB_BytsPerSec * + ( dirent doffset ) r@ 12 + ! + -1 r@ FCUR_clusteridx! 0 r@ FCUR_pos! + DIR_FileSize r@ FCUR_size! ( ) r> ; : fatopen ( path -- fcursor ) fatfindpath openfile ; @@ -205,22 +210,22 @@ alias drop fatflush ( fcursor -- ) \ pos, flush current buffer and read a new sector from disk. : fatseek ( pos fcursor -- ) over 0< if abort" can't seek to negative pos" then - over ClusterSize / over FCUR_pos ClusterSize / = not if \ cluster change! - dup fatflush ( pos fcursor ) - over ClusterSize / over FCUR_cluster0 ( pos fc clcnt cl ) - swap ?dup if >r begin ( pos fc cl ) FAT@ next then ( pos fc cl ) - 2dup swap FCUR_buf( readcluster ( pos fc cl ) - over FCUR_cluster! ( pos fc ) + over ClusterSize / over FCUR_clusteridx = not if + dup fatflush >r ( pos ) + dup ClusterSize / dup r@ FCUR_clusteridx! ( pos idx ) + r@ FCUR_cluster0 ( pos idx cl ) + swap ?dup if >r begin ( pos cl ) FAT@ next then ( pos cl ) + dup r@ FCUR_buf( readcluster ( pos cl ) + r@ FCUR_cluster! r> ( pos fc ) then ( pos fcursor ) FCUR_pos! ; -\ TODO: this whole business about advancing the cursor *before* reading is -\ shady. Fix this, read should happen at current cursor pos, post-inc. -\ Also, this is broken for n!=1 : fatreadbuf ( n fcursor -- a? n ) - dup FCUR_pos 1+ over FCUR_size over <= if \ EOF! - drop 2drop 0 exit then ( n fc pos ) - over fatseek ( n fcursor ) - dup FCUR_bufpos swap FCUR_)buf over - ( n pos nmax ) - rot min ( pos n ) ; + dup >r FCUR_size r@ FCUR_pos - ( n maxn ) + dup 1- 0< if ( EOF ) 2drop r~ 0 exit then + min ( n ) \ make sure that n doesn't go over size + r@ FCUR_pos r@ fatseek ( n ) + r@ FCUR_bufpos r@ FCUR_)buf over - ( n a nmax ) + rot min ( a n ) + dup r> FCUR_pos+ ( a n ) ; : fatclose ( fcursor ) dup fatflush 0 swap FCUR_flags! ; diff --git a/fs/tests/fs/fat.fs b/fs/tests/fs/fat.fs @@ -10,11 +10,11 @@ testbegin \ Tests for fs/fat S" tests/fattest" fatfindpath ( dirent ) openfile ( fcursor ) dup fatgetc 'T' #eq -$ff over fatseek \ TODO: make cursor post-inc. see fatlo.fs +$100 over fatseek dup fatgetc 'f' #eq dup fatgetc 'o' #eq dup fatgetc 'o' #eq -$1ff over fatseek +$200 over fatseek dup fatgetc 'b' #eq -$ffc over fatseek +$ffd over fatseek dup fatgetc 'E' #eq dup fatgetc 'O' #eq dup fatgetc 'F' #eq dup fatgetc -1 #eq fatclose