On Tue, 2008-08-12 at 12:54 +0200, Jens Axboe wrote: > The easy fix is would just be to > change init_request_from_bio() to do something ala: > > if (bio_barrier(bio)) { > if (bio_has_data(bio)) > req->cmd_flags |= REQ_HARDBARRIER; > else > req->cmd_flags |= REQ_SOFTBARRIER; > } > > since there's no real data dependency when you don't have data > attached. There's a check in __make_request() which will return -EOPNOTSUPP for bios with BIO_RW_BARRIER set, in some circumstances. Is that OK too? I was thinking of using the READ/WRITE bit for it -- just (1<<BIO_RW_DISCARD) (i.e. read) would imply a barrier, while having the WRITE bit also set would mean no barrier, and it gets scheduled like a normal write. Something like... diff --git a/block/blk-barrier.c b/block/blk-barrier.c index e544813..988b634 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c @@ -372,7 +372,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, nr_sects = 0; } bio_get(bio); - submit_bio(WRITE_DISCARD, bio); + submit_bio(DISCARD_BARRIER, bio); /* Check if it failed immediately */ if (bio_flagged(bio, BIO_EOPNOTSUPP)) diff --git a/block/blk-core.c b/block/blk-core.c index 0c8ed97..be2fe52 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1079,6 +1079,13 @@ void init_request_from_bio(struct request *req, struct bio *bio) req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE); if (unlikely(bio_discard(bio))) { req->cmd_flags |= REQ_DISCARD; + /* + * READ discard requests are soft barriers; WRITE + * indicates the file system will take care of that + * for itself. + */ + if (!bio_data_dir(bio)) + req->cmd_flags |= REQ_SOFTBARRIER; req->q->prepare_discard_fn(req->q, req); } diff --git a/include/linux/fs.h b/include/linux/fs.h index 88358ca..5cfacb3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -87,7 +87,8 @@ extern int dir_notify_enable; #define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC)) #define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNC)) #define WRITE_BARRIER (WRITE | (1 << BIO_RW_BARRIER)) -#define WRITE_DISCARD (WRITE | (1 << BIO_RW_DISCARD)) +#define DISCARD_NOBARRIER (WRITE | (1 << BIO_RW_DISCARD)) +#define DISCARD_BARRIER (1 << BIO_RW_DISCARD) #define SEL_IN 1 #define SEL_OUT 2 -- David Woodhouse Open Source Technology Centre David.Woodhouse@xxxxxxxxx Intel Corporation -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html