what's wrong with cd9660 fs

Thomas Schmitt scdbackup at gmx.net
Sun Apr 22 17:10:35 UTC 2012


Hi,

there are problems in fs/cd9660 concerning multi-session, if the new
session was written to addresses above 4 GiB.

  $ fetch https://dev.haiku-os.org/raw-attachment/ticket/8473/reloc_dir.iso.bz2
  $ bunzip2 reloc_dir.iso.bz2

  # mdconfig -a -t vnode -f reloc_dir.iso
  md1
  # mount_cd9660 /dev/md1 /mnt
  # find /mnt
  /mnt
  # ls -ld /mnt
  -r-xr-xr-x  1 root  wheel  0 Jan  1  1970 /mnt

It must be related to Rock Ridge interpretation:

  # umount /mnt
  # mount_cd9660 -r /dev/md1 /mnt
  # find /mnt
  /mnt
  /mnt/deep_dir
  /mnt/deep_dir/1
  /mnt/deep_dir/1/2
  ...
  /mnt/7/file_7_1
  # ls -ld /mnt
  dr-xr-xr-x  1 root  wheel  2048 Apr 16 14:12 /mnt

The image shows no visible problems with Linux kernels.


The missing S_IFDIR property should get set by cd9660_rrip_attr() while
cd9660_rrip_loop() iterates over the SUSP entries of ithe directory record.
I see in /var/log/messages these two messages for each time i mount without
option -r:
  Apr 22 14:11:39 freebsd1 kernel: cd9660: RockRidge Extension
  Apr 22 14:11:39 freebsd1 kernel: RRIP without PX field?

My first candidate for the cause would be some 32 bit bottleneck in the
computation of byte addresses of directory records. All the directory
records which are pointed to by the PVDs of the images are stored above
4 GiB. (The PVDs are at block 16.)

E.g. this gesture in cd9660_vfsops.c looks prone to rollover at 1 TiB
(imp->im_bshift == 11 , DEV_BSHIFT == 9, sizeof(int) == 4)

                int lbn, off;
                [...]
                error = bread(imp->im_devvp,
                              lbn << (imp->im_bshift - DEV_BSHIFT),
                              imp->logical_block_size, NOCRED, &bp);

This is a computation from 2 KiB block address to 512 byte block address.
A similar lapse with byte addresses would already rollover at 4 GiB.


Have a nice day :)

Thomas



More information about the freebsd-hackers mailing list