open-iscsi / tcmu-runner

A daemon that handles the userspace side of the LIO TCM-User backstore.
Apache License 2.0
189 stars 148 forks source link

file_zbc: punch hole on zone reset #660

Open kdave opened 3 years ago

kdave commented 3 years ago

Zone reset is simply rewriting the write pointer to the beginning without touching the actual zone data. It would be nice and easy to implement a hole punch, file operation freeing the metadata and data of the requested range. That way a backing file can be shrunk to only live zones. It's a bit like thin provisioning, the file starts sparsely allocated (using just the targetcli commands). I've measured the time of the hole punch on a moderately fragmented file on btrfs, with zone size 256M, the fallocate() call takes like 0.1s, ie. 100ms which is IMO acceptable.

Code change goes like

static void __zbc_reset_wp(struct zbc_dev *zdev, struct zbc_zone *zone)
{
        if (zbc_zone_conv(zone))
                return;

        if (zbc_zone_is_open(zone))
                __zbc_close_zone(zdev, zone);

        zone->wp = zone->start;
        zone->cond = ZBC_ZONE_COND_EMPTY;
        zone->non_seq = 0;
        zone->reset = 0;
        fallocate(zbc_dev->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, zone->start, zone->length);
}

Errors can be ignored, it's just best effort.

kdave commented 3 years ago

There's system command fallocate, with option --dig-holes it can detect zeroed blocks and punch the hole, but for the test image I had the previous non-zero data and as a result only 2G were removed from a 46G backing file.