[U-Boot] Updating ZFS for U-boot

Hello list,
The ZFS support in U-boot is in need of updating, so I have done so now. Which enables support for feature pools, LZ4 and raidz.
One thing that raidz support does, is iterate all the devices looking for the other devices needed to read the raid set. Currently I put in the code:
debug("Iterating for devices\n"); for ( uclass_first_device(UCLASS_BLK, &dev); dev; uclass_next_device(&dev) ) { struct blk_desc *desc = dev_get_uclass_platdata(dev);
debug(" testing device %d: type 0x%x vendor '%s' product '%s'\n", desc->devnum, desc->if_type, desc->vendor, desc->product);
if (part_get_info_whole_disk(desc, &info) == 0) {
debug(" testing whole disk: %p\n", desc->bdev->ops->read); dev.part_info = &info; err = scan_disk(&dev, data, 0, &inserted);
But to my surprise, fs_devread() of any device other than the one given on command line, will fail. Most likely because blk_dread() ops->read is NULL? Maybe?
Am I using the API wrong, or do I simply need to call a probe function first?
Thanks,
Lund

for ( uclass_first_device(UCLASS_BLK, &dev); dev; uclass_next_device(&dev) ) { struct blk_desc *desc = dev_get_uclass_platdata(dev); if (part_get_info_whole_disk(desc, &info) == 0) { But to my surprise, fs_devread() of any device other than the one given on command line, will fail. Most likely because blk_dread() ops->read is NULL? Maybe?
That was not it at all. Turns out the problem is that os_read() would return a partition read request, and fs_devread() calling blk_dread() does not handle a partial read at all. But that is fine,
The issue is that when fs_devread() converts my 131072 byte_len, into 131072 block_len, because blk->log2blksz == 0.
Turns out that blk->log2blksz is only set in blk_get_device_part_str() so this function has to be called before using a device.
So I can change my code to call uclass_first_device() then;
1) Convert the device info to strings, and call blk_get_device_part_str(). 2) Set blk->log2blksz myself and hope there are no other surprises.
Lund

The draft update for ZFS is ready, and is available here: https://github.com/lundman/u-boot/commit/c2727e5004fe011d19156d728babdf96851...
I will refresh myself on U-boot commit procedures, and start the proper method soon.
I did a question though, to be able to test file reading, I had to add the code:
#ifdef CONFIG_SANDBOX char *bufx = map_sysmem((phys_addr_t)(uint64_t)buf, movesize);
memmove(bufx, data->file_buf + file->offset + red - data->file_start, movesize); unmap_sysmem(bufx); #else memmove(buf, data->file_buf + file->offset + red - data->file_start, movesize); #endif
Should I keep that as #ifdef SANDBOX, or is there a preferred method?
I have tried to follow checkcommit.pl rules, and changed a few things to "const" etc, to make it cleaner.
Example output:
Hit any key to stop autoboot: 0 => host bind 0 ./raid1.raw => host bind 1 ./raid2.raw => host bind 2 ./raid3.raw => zfsls host 0:0 /@/ zfs: adding device 'host' dev 0 zfs: couldn't find a necessary member device of multi-device filesystem zfs: couldn't find a necessary member device of multi-device filesystem zfs: looking for devices... zfs: adding device 'host' dev 1 zfs: adding device 'host' dev 2 zfs: device scan completed. zfs fsname = '/' snapname='<NULL>' filename = '/' <DIR> hello.world file.txt
The device scan function ended up looking like:
for ( uclass_first_device(UCLASS_BLK, &dev); dev; uclass_next_device(&dev) ) { struct blk_desc *desc = dev_get_uclass_platdata(dev); for (part = 0; part <= MAX_SEARCH_PARTITIONS; part++) { snprintf(dev_str, sizeof(dev_str), "%u:%u", desc->devnum, part); part = blk_get_device_part_str(blk_get_if_type_name(desc->if_type), dev_str, &dev.disk, &dev.part_info, 1); if (part < 0) continue;
Hopefully that is acceptable.
Any other cleanups requested in the ZFS area?
Lund
participants (1)
-
Jorgen Lundman