diff mbox

fat-files: Fix access to FAT32 dir/files when cluster >16-bits

Message ID 1465364612.3263.56.camel@kernel.crashing.org
State Superseded
Headers show

Commit Message

Benjamin Herrenschmidt June 8, 2016, 5:43 a.m. UTC
On FAT32, the directory entry contains a new field providing the
top 16-bits of the cluster number. We didn't use it, thus reading
the wrong sectors when trying to access files or directories
beyond block 0x10000.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 slof/fs/packages/fat-files.fs | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

Comments

Segher Boessenkool June 8, 2016, 5:57 a.m. UTC | #1
On Wed, Jun 08, 2016 at 03:43:32PM +1000, Benjamin Herrenschmidt wrote:
> On FAT32, the directory entry contains a new field providing the
> top 16-bits of the cluster number. We didn't use it, thus reading
> the wrong sectors when trying to access files or directories
> beyond block 0x10000.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

That looks good.  Why move the cr in .dir-entry though?


Segher
Benjamin Herrenschmidt June 8, 2016, 8:13 a.m. UTC | #2
On Wed, 2016-06-08 at 00:57 -0500, Segher Boessenkool wrote:
> That looks good.  Why move the cr in .dir-entry though?]

Ah that's related to my work on "dir" ... probably doesn't belong
there but it won't hurt either as ".dir" is currently unused.

Ben.
diff mbox

Patch

diff --git a/slof/fs/packages/fat-files.fs b/slof/fs/packages/fat-files.fs
index d919452..d2a55a1 100644
--- a/slof/fs/packages/fat-files.fs
+++ b/slof/fs/packages/fat-files.fs
@@ -73,6 +73,14 @@  INSTANCE VARIABLE next-cluster
     THEN
 ;
 
+\ Read cluster# from directory entry (handle FAT32 extension)
+: get-cluster ( direntry -- cluster# )
+  fat-type @ 20 = IF
+    dup 14 + 2c@ bwjoin 10 lshift
+  ELSE 0 THEN
+  swap 1a + 2c@ bwjoin +
+;
+
 : .time ( x -- )
   base @ >r decimal
   b #split 2 0.r [char] : emit  5 #split 2 0.r [char] : emit  2* 2 0.r
@@ -86,8 +94,7 @@  INSTANCE VARIABLE next-cluster
 : .dir-entry ( adr -- )
   dup 0b + c@ 8 and IF drop EXIT THEN \ volume label, not a file
   dup c@ e5 = IF drop EXIT THEN \ deleted file
-  cr
-  dup 1a + 2c@ bwjoin [char] # emit 4 0.r space \ starting cluster
+  dup get-cluster [char] # emit 8 0.r space \ starting cluster
   dup 18 + 2c@ bwjoin .date space
   dup 16 + 2c@ bwjoin .time space
   dup 1c + 4c@ bljoin base @ decimal swap a .r base ! space \ size in bytes
@@ -95,9 +102,11 @@  INSTANCE VARIABLE next-cluster
   dup 8 BEGIN 2dup 1- + c@ 20 = over and WHILE 1- REPEAT type
   dup 8 + 3 BEGIN 2dup 1- + c@ 20 = over and WHILE 1- REPEAT dup IF
   [char] . emit type ELSE 2drop THEN
-  drop ;
+  cr drop
+  ;
 : .dir-entries ( adr n -- )
   0 ?DO dup i 20 * + dup c@ 0= IF drop LEAVE THEN .dir-entry LOOP drop ;
+
 : .dir ( cluster# -- )
   read-dir BEGIN data @ #data @ 20 / .dir-entries next-cluster @ WHILE
   next-cluster @ read-cluster REPEAT ;
@@ -114,8 +123,10 @@  CREATE dos-name b allot
 : (find-file) ( -- cluster file-len is-dir? true | false )
   data @ BEGIN dup data @ #data @ + < WHILE
   dup dos-name b comp WHILE 20 + REPEAT
-  dup 1a + 2c@ bwjoin swap dup 1c + 4c@ bljoin swap 0b + c@ 10 and 0<> true
+  dup get-cluster
+  swap dup 1c + 4c@ bljoin swap 0b + c@ 10 and 0<> true
   ELSE drop false THEN ;
+
 : find-file ( dir-cluster name len -- cluster file-len is-dir? true | false )
   make-dos-name read-dir BEGIN (find-file) 0= WHILE next-cluster @ WHILE
   next-cluster @ read-cluster REPEAT false ELSE true THEN ;