Windrow14 opened a new pull request, #12615: URL: https://github.com/apache/nuttx/pull/12615
## Summary Unbinding `ff_currentcluster` and `f_pos`: 1. Added `ff_pos` in `struct fat_file_s`. 2. Added function `fat_zero_cluster` for doing zeroing for gap between EOF and new position beyond EOF. 3. Added function `fat_get_sectors` for getting the sector where `f_pos` is located, creating new cluster when `f_pos` is beyond EOF. 4. Modify function `fat_read`, and `fat_write` with above functions. 5. Remove redundant logics in `fat_seek` since now new cluster is allocated when writing instead of seeking. ## Impact Before this commit, `f_pos` has two uses, one is to record the current read and write position of the file, and the other is to avoid repeated traversal of the cluster chain when reading and writing files. So `f_pos` must point to the space where `ff_currentcluster` is located, which causes the following problems. 1. If the file is opened as writable and the file offset to be set beyond the end of the file, `lseek()` will extend the size. And the gap between the end of the file and the file offset is not zeroed. These are not POSIX compliant. 2. If the file is opened as readonly and the file size is aligned with the cluster size. `lseek(fd, 0, SEEK_END)` will return an error (ENOSPC). `f_pos` is left at [a wrong position](https://gist.github.com/Windrow14/06188b09a6c80275de8c3ce6c12d3cbd), one cluster size before EOF. 3. The performance of `lseek()` is very low. The reason is the traversal of the cluster chain in `fat_seek()`. To resolve these problems, this commit adds `ff_pos` to avoid repeated traversal of the cluster chain. So that `f_pos` is only used to record the current read and write position of the file, no longer bound to `ff_currentcluster`. The implementation of `fat_write`, `fat_read`, and `fat_fseek` is affected by this commit. ## Testing We tested with QEMU as following: ``` ./tools/configure.sh qemu-armv8a:netnsh make qemu-system-aarch64 \ -cpu cortex-a53 \ -smp 4 \ -nographic \ -machine virt,virtualization=on,gic-version=3 \ -chardev stdio,id=con,mux=on \ -serial chardev:con \ -global virtio-mmio.force-legacy=false \ -netdev user,id=u1,hostfwd=tcp:127.0.0.1:10023-10.0.2.15:23,\ hostfwd=tcp:127.0.0.1:15001-10.0.2.15:5001 \ -device virtio-net-device,netdev=u1,bus=virtio-mmio-bus.0 \ -drive file=/home/windrow/code/nuttx/2GB.img,format=raw,id=hd,if=none \ -device virtio-blk-device,bus=virtio-mmio-bus.1,drive=hd \ -mon chardev=con,mode=readline \ -kernel \ ./nuttx ``` We did tests with tools including: `sdbench`, `sdstress`, `fstest`, and `smarttest`. We also make a [tool](https://gist.github.com/Windrow14/780d200191d811a5909f461816348257) to help test reading, writing, seeking interfaces of file systems. It can do a series of these actions to a file, print return values of the interfaces, display the content of the file. We've verified modified fat file system with a long list of designed test cases which cover different file size, different seeking destination, reading or writing different size at different position. Please check full test [logs](https://gist.github.com/Windrow14/1d10917555f632a8e2432dc4dce0c146) here. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
