Okay. Looking around I've found cluster size in struct FATFS. Which _vfs_open_fat_handle() creates and passes to f_mount(). The user program calls _vfs_open_fat_handle() during mounting, so access to cluster size is only just below. I'm not sure of C foo to reach it though.
There's a way to grab the internal FATFS struct from the VFS. I think I used it once to proof-of-concept converting paths between long and short names - you'd need that if you had some kind of file explorer application with LFN support and want to launch e.g. MegaYume (no LFN support) with a given file through FC000 ARGv).
@ersmith said:
Worst case I suppose you could always read sector 0 (the BPB) and get it from there. Out of curiosity, why do you want the cluster size?
From observation, I'm of the opinion that the file speed testing performs highest when the read/write chunk size (The tester's buffer size) matches the cluster size. Above that level seems to be slightly reduced speed even.
And how does a program read partition blocks?
something like fopen("/sd/.","rb"); ??
EDIT: Nope, errno = 4: No such file or directory
@ersmith said:
Worst case I suppose you could always read sector 0 (the BPB) and get it from there. Out of curiosity, why do you want the cluster size?
And how does a program read partition blocks?
something like fopen("/sd/.","rb"); ??
EDIT: Nope, errno = 4: No such file or directory
The handle you pass to _vfs_open_fat_handle(h) (e.g. the result of _sdmm_open is a FILE *, so you can use fread or fwrite on it. This may not be obvious in the headers, which tend to use the name struct vfs_file_t * for this pointer, but FILE is an alias for struct vfs_file_t.
@evanh said:
Uh-oh, can't fseek(). It just doesn't do anything. I have to read every block sequentially to reach start of partition to then fetch the cluster size.
I forgot to warn you, fseek() on the SDMM device only works to seek to sector boundaries; it's also possible (probable) that fread() and fwrite() will only work on sector sized chunks.
PS: If it were to function, it'd make sense to use LBA block numbering rather than bytes.
You can actually open a FAT file image that's contained on another device (e.g. a FAT file on the host PC using the 9P file system). So not all underlying devices only work on block boundaries, just the kind of hacky SDMM one. Someday it would be nice to remove the SDMM restrictions, but that's a pretty niche case.
Actually I see the stat() function has an st_blksize field, which we can fill in with the cluster size (at least for regular files). I've just pushed a change to do that. The patch looks like:
Ah, stat() needs a path specified, would that be "/sd" this time?
fstat() can presumably use the same file handle I already have. However fstat() is not implemented? It has a header entry declared but no source definition that I can see.
Ah, stat() needs a path specified, would that be "/sd" this time?
No, it would be the name of the file you plan to read from. The code I posted won't work on the root directory (e.g. "/sd", if that's where you mounted the fatfs) . However, I've pushed an update that will work, so that's always an option.
fstat() can presumably use the same file handle I already have. However fstat() is not implemented? It has a header entry declared but no source definition that I can see.
Yes, fstat() never got implemented, because not all file systems can do it easily (FATFS being one of them).
Updated to the latest include/filesys/fatfs/ files.
Okay, making progress. I correctly get buff->st_blksize == 32768 when I stat() one of the written files. But not the case for stat("/sd", buff);. It's just a zero value for all attempts at stat()ing the mounted volume directly.
I am just blindly examining st_blksize without knowing anything else about what stat() has filled out. Don't know how it's normally used.
EDIT: Turning on -D_DEBUG_FATFS and using a file gives me:
Comments
Okay. Looking around I've found cluster size in struct FATFS. Which _vfs_open_fat_handle() creates and passes to f_mount(). The user program calls _vfs_open_fat_handle() during mounting, so access to cluster size is only just below. I'm not sure of C foo to reach it though.
Worst case I suppose you could always read sector 0 (the BPB) and get it from there. Out of curiosity, why do you want the cluster size?
There's a way to grab the internal FATFS struct from the VFS. I think I used it once to proof-of-concept converting paths between long and short names - you'd need that if you had some kind of file explorer application with LFN support and want to launch e.g. MegaYume (no LFN support) with a given file through FC000 ARGv).
From observation, I'm of the opinion that the file speed testing performs highest when the read/write chunk size (The tester's buffer size) matches the cluster size. Above that level seems to be slightly reduced speed even.
And how does a program read partition blocks?
something like
fopen("/sd/.","rb");
??EDIT: Nope,
errno = 4: No such file or directory
The handle you pass to
_vfs_open_fat_handle(h)
(e.g. the result of_sdmm_open
is aFILE *
, so you can usefread
orfwrite
on it. This may not be obvious in the headers, which tend to use the namestruct vfs_file_t *
for this pointer, butFILE
is an alias forstruct vfs_file_t
.huh, cool. Too easy.
Uh-oh, can't fseek(). It just doesn't do anything. I have to read every block sequentially to reach start of partition to then fetch the cluster size.
PS: If it were to function, it'd make sense to use LBA block numbering rather than bytes.
I forgot to warn you, fseek() on the SDMM device only works to seek to sector boundaries; it's also possible (probable) that fread() and fwrite() will only work on sector sized chunks.
You can actually open a FAT file image that's contained on another device (e.g. a FAT file on the host PC using the 9P file system). So not all underlying devices only work on block boundaries, just the kind of hacky SDMM one. Someday it would be nice to remove the SDMM restrictions, but that's a pretty niche case.
Actually I see the
stat()
function has anst_blksize
field, which we can fill in with the cluster size (at least for regular files). I've just pushed a change to do that. The patch looks like:Sounds good.
Ah, stat() needs a path specified, would that be "/sd" this time?
fstat() can presumably use the same file handle I already have. However fstat() is not implemented? It has a header entry declared but no source definition that I can see.
No, it would be the name of the file you plan to read from. The code I posted won't work on the root directory (e.g. "/sd", if that's where you mounted the fatfs)
. However, I've pushed an update that will work, so that's always an option.
Yes, fstat() never got implemented, because not all file systems can do it easily (FATFS being one of them).
Updated to the latest include/filesys/fatfs/ files.
Okay, making progress. I correctly get buff->st_blksize == 32768 when I stat() one of the written files. But not the case for
stat("/sd", buff);
. It's just a zero value for all attempts at stat()ing the mounted volume directly.I am just blindly examining st_blksize without knowing anything else about what stat() has filled out. Don't know how it's normally used.
EDIT: Turning on -D_DEBUG_FATFS and using a file gives me:
And "/sd" gives me:
Looks like it ignores and returns without error.
Here's the relevant source code:
@evanh Aargh, there was another problem where stat() itself was just ignoring the root directory. That should be fixed now.
All good!
Thanks.