Re: Hot-grow bcache backing device.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 1/7/22 8:12 AM, Eric Wheeler wrote:
Hi Coli an Mingzhe:

Since Mingzhe brought up full_dirty_stripes in the other thread: some time
ago I was looking into hot-resize of bcache devices.  Usually I resize by
unregister/re-register but it would be nice to do hot.

While reviewing the code for feasibility the only snag I found was safely
resizing full_dirty_stripes allocation before updating d->nr_stripes and
calling set_capacity(d->disk, bdev_nr_sectors(dc->bdev)).

I think hot resize of a bdev should be simple and I have a few questions:

It is simple but not very simple. The size information has to be updated atomically in both cached device and bcache device.

I guess/feel we need to freeze the bcache device during the resize operation. Freeze means holding all new coming external or internal I/Os and waiting for all flying I/Os to finish.


1. Should the newly resized bits of full_dirty_stripes just be zeroed?

I feel zeroing all new growing bits of full_dirty_stripes is good.



2. Besides d->nr_stripes and full_dirty_stripes, does anything else need
    to change size?  Long ago Kent confirmed that the cachedev structures
    are bdev-size agnostic.

struct gendisk *disk from struct bcache_device should be updated to for the grown size.



3. Are there any bcache locks to hold when resizing?

I can see dc->writeback_lock, maybe some other implicit locking dependence but I cannot tell immediately.


4. Is there something like "realloc()" to grow the allocation (I didn't
    see kvzrealloc())---or would we need to kvzalloc into a new buffer,
    copy in, and free the old one?

Any method is fine to me, just handle the failure condition properly.


For reference, from bcache_device_init():
         n = DIV_ROUND_UP_ULL(sectors, d->stripe_size);
         [...]
         d->nr_stripes = n;

         n = d->nr_stripes * sizeof(atomic_t);
         d->stripe_sectors_dirty = kvzalloc(n, GFP_KERNEL);
         if (!d->stripe_sectors_dirty)
                 return -ENOMEM;

         n = BITS_TO_LONGS(d->nr_stripes) * sizeof(unsigned long);
    d->full_dirty_stripes = kvzalloc(n, GFP_KERNEL);

The bcache device should be froze during size extend operation, I am not sure whether the whole cache set should be froze too.

And I don't see obvious blocking challenge to implement the backing device resize, at my first glance :-)

Coly Li




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux ARM Kernel]     [Linux Filesystem Development]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux