I'm implementing the lean filesystem <http://freedos-32.sourceforge.net/lean/specification.php> for fun, and I've run into an issue with how the data is stored. The fs is broadly similar to ext2, however instead of having an inode table, it stores the inode in the first 176 octets of the first sector the file (in this fs, "sector" always refers to a block of 512 octets). The file data itself starts immediately after the inode. The helper functions generic_file_read_iter, mpage_readpages and friends assume that file data begins on block boundaries. I can partially get around this limitation by, for example, messing with iocb->ki_pos before calling generic_file_read_iter. However, the end of the file is then truncated because the file length is 176 bytes short. This is also an issue where the last page may not get mapped in mpage_readpages. The obvious (and hacky) solution is to modify these functions to add the size of the inode to their calls to i_size_read. This would require continually merging in upstream changes to these files. Alternatively, my implementation could lie about the actual length of files. The existing helper functions could be used here, with minor modification for offsets. This would probably not play well with userspace software, as it would yield surprising results for different system calls (stat(fd, statbuf); statbuf->st_size != lseek(fd, 0L, SEEK_END)). One other option would be to use the rest of the inode block for other information and always start the beginning of file data at the beginning of a block. The standard already allows this space to be used for xattrs. However, this would go mostly unused on many systems without SELinux. Other options could include inline duplicate file data, as in ext4 and btrfs or additional extent information. While this is probably the most pragmatic solution, it is also unsatisfying, as (to my knowledge) there is no technical reason this sort of filesystem cannot be implemented in linux. Are there any other approaches I have missed? I saw there was a proposed patch to introduce callbacks to mpage_readpage[s], but this doesn't seem appropriate for the problem at hand, as it isn't length-preserving. My current implementation is at <https://github.com/Forty-Bot/lean>. At the moment I have implemented part of the first option I discussed in src/file.c. I'll be happy to answer any questions you might have. --Sean Anderson
Attachment:
signature.asc
Description: OpenPGP digital signature