[dm-devel] [RFC PATCH 2/2] dm: add support for splitting discard requests

Mike Snitzer snitzer at redhat.com
Sun Jun 27 13:59:00 UTC 2010


On Sun, Jun 27 2010 at  5:47am -0400,
Christoph Hellwig <hch at lst.de> wrote:

> On Sat, Jun 26, 2010 at 04:31:25PM -0400, Mike Snitzer wrote:
> > Enable the striped target to support discard requests by splitting a
> > single discard into N discards on a stripe chunk size boundary.
> > 
> > Follow on core block layer work to merge discards would be helpful.
> > 
> > This work relies on DM's clone_bio() always having BIO_RW_BARRIER set
> > for discard requests.  Without BIO_RW_BARRIER the block layer will spew
> > "blk: request botched" warnings for discards that were split by DM.
> > - this clearly needs further investigation!
> 
> Btw, you can get discard requests from the upper layer that do not
> have BIO_RW_BARRIER set, currently from the BLKDISCARD ioctl used by
> various mkfs tools, and also from the not yet merged xfs discard
> support.

Yes, I'm aware of the BLKDISCARD ioctl.  I added the 'else if' clause
which adds the BIO_RW_BARRIER flag specifically for that case.  Testing
showed the mkfs.ext4 uses the BLKDISCARD ioctl and it would result in
"blk: request botched" when operated against a striped DM target (that
was performing the discrad splitting).

> Can I assume it works fine with those?

Yes it works, with or without DM adding the BIO_RW_BARRIER flag, but
without the flag it'll spew "blk: request botched" and the block layer
will fix things up with this at the end of blk_update_request():

        /*
         * If total number of sectors is less than the first segment
         * size, something has gone terribly wrong.
         */
        if (blk_rq_bytes(req) < blk_rq_cur_bytes(req)) {
                printk(KERN_ERR "blk: request botched\n");
                req->__data_len = blk_rq_cur_bytes(req);
        }

Additional tracing showed blk_rq_bytes(req) was always 0 if DM didn't
set BIO_RW_BARRIER for split discard requests.  It could be that if
BIO_RW_BARRIER is set we'll exit early from blk_update_request to
avoid its "blk: request botched"?  I'll look closer.

> > -	clone->bi_rw &= ~(1 << BIO_RW_BARRIER);
> > +	if (!bio_rw_flagged(bio, BIO_RW_DISCARD))
> > +		clone->bi_rw &= ~(1 << BIO_RW_BARRIER);
> > +	else if (!bio_rw_flagged(bio, BIO_RW_BARRIER)) {
> > +		/* discard w/o barrier results in "blk: request botched" */
> > +		clone->bi_rw |= (1 << BIO_RW_BARRIER);
> > +	}
> 
> So previously we unconditionally cleared the BIO_RW_BARRIER bit in the clone. 

Yes.  I'd like to understand why from Mikulas.

> Maybe to make it clear reorder the if a bit and also just set the
> barrier bit unconditionally for discards, similar to how we
> unconditionally clear it otherwise:
> 
> 	if (bio_rw_flagged(bio, BIO_RW_DISCARD)) {
> 		/* discard w/o barrier results in "blk: request botched" */
> 		clone->bi_rw |= (1 << BIO_RW_BARRIER);
> 	} else {
> 		clone->bi_rw &= ~(1 << BIO_RW_BARRIER);
> 	}
> 
> maybe even with a slightly longer comment explaining what's actually
> going on here, and a FIXME.

OK, your reorder is clearer.  As for a FIXME describing what's going on
here: I'll work to sort that out.. it is still unclear to me why the
BIO_RW_BARRIER flag silences the "blk: request botched" spew from
blk_update_request().

Thanks,
Mike




More information about the dm-devel mailing list