jblumsch / fuse-ufs2

GNU General Public License v2.0
1 stars 1 forks source link

Fix broken directory operations #4

Closed jblumsch closed 8 years ago

jblumsch commented 8 years ago

Bugs present in read-only mode, showing up in ls / op_readdir():

jblumsch commented 8 years ago
  • fuse-ufs ignores some content of large directories

ufs_dir_iterate() (in fuse-ufs-utils.c) starves after processing the first filesystem block (of fs_bsize bytes, usually 32k). Listings of long directories will be incomplete.

jblumsch commented 8 years ago
  • fuse-ufs happens to segfault or loop forever when reading small (or even empty) directories

ufs_dir_iterate() does not respect the actual directory size. When accessing directories not spanning entire fs_bsize blocks, uninitialized or zeroed memory will be read.

jblumsch commented 8 years ago

There is some confusion about block sizes throughout the code. UFS directories come in blocks of DIRBLKSIZ bytes (512 for most UFS variants, usually smaller than fs_fsize). No directory entry shall ever cross a DIRBLKSIZ block boundary.

jblumsch commented 8 years ago
  • fuse-ufs happens to segfault or loop forever when reading small (or even empty) directories
    ufs_dir_iterate() does not respect the actual directory size.

Fixed by 59e839d.

jblumsch commented 8 years ago
  • fuse-ufs ignores some content of large directories
    ufs_dir_iterate() (in fuse-ufs-utils.c) starves after processing the first filesystem block (of fs_bsize bytes, usually 32k). Listings of long directories will be incomplete.

Fixed by 36a4abd.

jblumsch commented 8 years ago
  • After properly (i.e. using a BSD mount) deleting some entry from a directory, fuse-ufs happens to overlook more directory entries that should still be there.

ufs_dir_iterate() skips the rest of the filesystem block when an unused directory entry (marked by d_ino=0) is encountered. (Directory entries with d_ino=0 should be the first in a directory block – but need not span all of that block, and may appear anywhere in the bigger filesystem block.)

jblumsch commented 8 years ago
  • After properly (i.e. using a BSD mount) deleting some entry from a directory, fuse-ufs happens to overlook more directory entries that should still be there.
    ufs_dir_iterate() skips the rest of the filesystem block when an unused directory entry (marked by d_ino=0) is encountered.

Basically done with cda9648: skip unused directory entries unless DIRENT_FLAG_INCLUDE_EMPTY is passed, but don't break loop.

Some cleanup done to make the code less confusing:

jblumsch commented 8 years ago

Done so far (for the bugs present in read-only mode, mentioned above).


There are more issues with directory modifications → New issue #5 .