0

I have an IOBlockStorageDevice device created, which reports the blocksize, as set by the user. It creates a /dev/diskX entry for the disk. If reportBlockSize returns 4096, and an attempt to write a single block is made, it writes exactly 1 block.

If blocksize of 512 is used, a single block write request becomes 8 block read, followed by 8 block write. (as observed in doAsyncReadWrite).

I believe I have tracked this down to spec_vnops.c spec_write()

543                 devBlockSize = vp->v_specsize;
544                 if (devBlockSize > PAGE_SIZE)
545                         return(EINVAL);
546 
547                 bscale = PAGE_SIZE / devBlockSize;
548                 blkmask = bscale - 1;
549                 bsize = bscale * devBlockSize;

If a block is smaller than PAGE_SIZE(4096) then make bsize be 4096, and in a conditional statement below, it decides to call read first, then write.

Worse is if you try to set a blockSize larger than 4096, it just straight up fails.

This seems rather limited, and I am wondering if there is a way to avoid using specfs. Since I create my device using IOkit, I assume it sets the vnops to specfs somewhere deep inside. So even if I were to make my own specfs vnops, I have no way to set them?

Once a filesystem is mounted on the device, it will use different vnops and all is well. But it is hard to even partition the device, if for example, blocksize is 8192.

lundman
  • 1,616
  • 13
  • 25

1 Answers1

0

The bdevsw_add call deep in the devfs blob, called by iokit, will always attach the specfs vnops. Darwin does not let you change the vnops on a vnode. So it is unrealistic/undesirable to attempt to do this. The /dev/ nodes created by IOkit needs to remain as-is, and be used with the GUI and the blocksize restrictions.

What I will have to do instead, is create a second set of BLK and CHR devices (whether or not inside or outside /dev) and attach my own vnops, which can handle any blocksize. These nodes would be used for non-GUI related things. (application volumes which specific blocksize requirements).

lundman
  • 1,616
  • 13
  • 25