- Convert all blkdev_issue_xxx function to common set of flags - move common functions to block/blk-lib.c - Add generic zeroout helper changes from V1 Christoph is about to change discard memory payload allocation logic so discard cleanups are no longer necessary. --
The patch just convert all blkdev_issue_xxx function to common
flags. Wait/allocation semantics not changed.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
block/blk-barrier.c | 10 +++++-----
block/ioctl.c | 2 +-
fs/btrfs/extent-tree.c | 2 +-
fs/gfs2/rgrp.c | 5 +++--
include/linux/blkdev.h | 8 +++-----
mm/swapfile.c | 8 +++++---
6 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 7e6e810..56254b1 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -368,17 +368,17 @@ static void blkdev_discard_end_io(struct bio *bio, int err)
* @sector: start sector
* @nr_sects: number of sectors to discard
* @gfp_mask: memory allocation flags (for bio_alloc)
- * @flags: DISCARD_FL_* flags to control behaviour
+ * @flags: BLKDEV_IFL_* flags to control behaviour
*
* Description:
* Issue a discard request for the sectors in question.
*/
int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
- sector_t nr_sects, gfp_t gfp_mask, int flags)
+ sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
{
DECLARE_COMPLETION_ONSTACK(wait);
struct request_queue *q = bdev_get_queue(bdev);
- int type = flags & DISCARD_FL_BARRIER ?
+ int type = flags & BLKDEV_IFL_BARRIER ?
DISCARD_BARRIER : DISCARD_NOBARRIER;
struct bio *bio;
struct page *page;
@@ -401,7 +401,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
bio->bi_sector = sector;
bio->bi_end_io = blkdev_discard_end_io;
bio->bi_bdev = bdev;
- if (flags & DISCARD_FL_WAIT)
+ if (flags & BLKDEV_IFL_BARRIER)
bio->bi_private = &wait;
/*
@@ -432,7 +432,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
bio_get(bio);
submit_bio(type, bio);
- if (flags & DISCARD_FL_WAIT)
+ if (flags & BLKDEV_IFL_BARRIER)
wait_for_completion(&wait);
if (bio_flagged(bio, BIO_EOPNOTSUPP))
diff --git ...Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
block/blk-lib.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/blkdev.h | 3 +-
2 files changed, 120 insertions(+), 1 deletions(-)
diff --git a/block/blk-lib.c b/block/blk-lib.c
index d7827e5..fa36030 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -112,3 +112,121 @@ out:
return -ENOMEM;
}
EXPORT_SYMBOL(blkdev_issue_discard);
+
+struct bio_batch
+{
+ atomic_t done;
+ unsigned long flags;
+ struct completion *wait;
+ bio_end_io_t *end_io;
+};
+
+static void bio_batch_end_io(struct bio *bio, int err)
+{
+ struct bio_batch *bb = bio->bi_private;
+ if (err) {
+ if (err == -EOPNOTSUPP)
+ set_bit(BIO_EOPNOTSUPP, &bb->flags);
+ else
+ clear_bit(BIO_UPTODATE, &bb->flags);
+ }
+ if (bb) {
+ if (bb->end_io)
+ bb->end_io(bio, err);
+ atomic_inc(&bb->done);
+ complete(bb->wait);
+ }
+ bio_put(bio);
+}
+
+/**
+ * __blkdev_issue_zeroout generate number of zero filed write bios
+ * @bdev: blockdev to issue
+ * @sector: start sector
+ * @nr_sects: number of sectors to write
+ * @gfp_mask: memory allocation flags (for bio_alloc)
+ * @flags: BLKDEV_IFL_* flags to control behaviour
+ *
+ * Description:
+ * Generate and issue number of bios with zerofiled pages.
+ * Send barrier at the beginning and at the end if requested. This guarantie
+ * correct request ordering. Empty barrier allow us to avoid post queue flush.
+ */
+
+int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
+ sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
+{
+ int ret = 0;
+ struct bio *bio;
+ struct bio_batch bb;
+ unsigned int sz, issued = 0;
+ DECLARE_COMPLETION_ONSTACK(wait);
+
+ atomic_set(&bb.done, 0);
+ bb.flags = 1 << BIO_UPTODATE;
+ bb.wait = &wait;
+ bb.end_io = NULL;
+
+ if (flags & BLKDEV_IFL_BARRIER) {
+ /* issue async barrier before the data */
+ ret = blkdev_issue_flush(bdev, gfp_mask, NULL, 0);
+ if (ret)
+ return ...Looks okayish to me, but it really needs: a) a useful patch description b) patches that introduce actual users Also why does the function have a __ prefix in the name? --
Move blkdev_issue_discard from blk-barrier.c because it is not barrier
related.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
block/Makefile | 2 +-
block/blk-barrier.c | 103 ----------------------------------------------
block/blk-lib.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 104 deletions(-)
create mode 100644 block/blk-lib.c
diff --git a/block/Makefile b/block/Makefile
index cb2d515..0bb499a 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -5,7 +5,7 @@
obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \
blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \
blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
- blk-iopoll.o ioctl.o genhd.o scsi_ioctl.o
+ blk-iopoll.o blk-lib.o ioctl.o genhd.o scsi_ioctl.o
obj-$(CONFIG_BLK_DEV_BSG) += bsg.o
obj-$(CONFIG_BLK_CGROUP) += blk-cgroup.o
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 56254b1..1242bdd 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -347,106 +347,3 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
}
EXPORT_SYMBOL(blkdev_issue_flush);
-static void blkdev_discard_end_io(struct bio *bio, int err)
-{
- if (err) {
- if (err == -EOPNOTSUPP)
- set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
- clear_bit(BIO_UPTODATE, &bio->bi_flags);
- }
-
- if (bio->bi_private)
- complete(bio->bi_private);
- __free_page(bio_page(bio));
-
- bio_put(bio);
-}
-
-/**
- * blkdev_issue_discard - queue a discard
- * @bdev: blockdev to issue discard for
- * @sector: start sector
- * @nr_sects: number of sectors to discard
- * @gfp_mask: memory allocation flags (for bio_alloc)
- * @flags: BLKDEV_IFL_* flags to control behaviour
- *
- * Description:
- * Issue a discard request for the sectors in question.
- */
-int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
- sector_t nr_sects, gfp_t gfp_mask, unsigned long ...If you create a new file just for discard I would call it blk-discard.c. But I can't really be bothered too much about the placement of this two functions, so do whatever is fine with you and Jens. --
Looks good in general. But I would re-order this to be patch 1 so you can avoid introducing flags for blkdev_issue_flush just to replace them in the next one. --
In some places caller don't want to wait a request to complete. Flags make blkdev_issue_flush() more flexible. This patch just convert existing callers to new interface without chaining existing allocation/wait behavior. Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> --- block/blk-barrier.c | 43 +++++++++++++++++++++--------------- drivers/block/drbd/drbd_int.h | 3 +- drivers/block/drbd/drbd_receiver.c | 3 +- fs/block_dev.c | 3 +- fs/ext3/fsync.c | 3 +- fs/ext4/fsync.c | 6 +++- fs/jbd2/checkpoint.c | 3 +- fs/jbd2/commit.c | 6 +++- fs/reiserfs/file.c | 3 +- fs/xfs/linux-2.6/xfs_super.c | 3 +- include/linux/blkdev.h | 10 ++++++- 11 files changed, 55 insertions(+), 31 deletions(-) diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 8618d89..7e6e810 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c @@ -285,26 +285,31 @@ static void bio_end_empty_barrier(struct bio *bio, int err) set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); clear_bit(BIO_UPTODATE, &bio->bi_flags); } - - complete(bio->bi_private); + if (bio->bi_private) + complete(bio->bi_private); + bio_put(bio); } /** * blkdev_issue_flush - queue a flush * @bdev: blockdev to issue flush for + * @gfp_mask: memory allocation flags (for bio_alloc) * @error_sector: error sector + * @flags: BLKDEV_IFL_* flags to control behaviour * * Description: * Issue a flush for the block device in question. Caller can supply * room for storing the error offset in case of a flush error, if they - * wish to. + * wish to. If WAIT flag is not passed then caller may check only what + * request was pushed in some internal queue for later handling. */ -int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) +int blkdev_issue_flush(struct block_device *bdev, gfp_t ...
Looks okay to me, but as mention in the other review I would introduce the comment flags first and then add the flags to blkdev_issue_flush, not the other way around. --
This is a very awkward stayle to define flags. There really should be no need for the __-prefixed version. While you're using them for test/set_bit and co there's no reason to use these atomic bitops here. --
I need both bit_num(used inside function) and flag (1<<bit_num)
which is used by function caller.
No problem, i'll change it whenever you like
do you like following?
enum{
IFN_BLKDEV_WAIT, /* wait for completion */
IFN_BLKDEV_BARRIER, /*issue request with barrier */
};
#define BLKDEV_WAIT (1 << IFN_BLKDEV_WAIT)
#define BLKDEV_BARRIER (1 << IFN_BLKDEV_BARRIER)
--
Jens, are you planning on picking up a version of this? ---end quoted text--- --
Ok, will appear in several hours. I have to repeat full testing --
Take your time, I would appreciate it if lvm didn't get broken again :-) -- Jens Axboe --
- Convert all blkdev_issue_xxx function to common set of flags - move common helper functions to block/blk-lib.c - Add generic zeroout helper Tested configuration: ext4 w -odiscard over raw_bdisk and dm-linear changes from V2 Fix flag names, and rearange patches according to Christoph's comments. Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> --- Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile b/Makefile index fa1db90..285a0fa 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 34 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc5- NAME = Sheep on Meth # *DOCUMENTATION* -- 1.6.6.1 --
- Add bio_batch helper primitive. This is rather generic primitive
for submitting/waiting a complex request which consists of several
bios.
- blkdev_issue_zeroout() generate number of zero filed write bios.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
block/blk-lib.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/blkdev.h | 3 +-
2 files changed, 120 insertions(+), 1 deletions(-)
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 0dc4388..886c3f9 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -112,3 +112,121 @@ out:
return -ENOMEM;
}
EXPORT_SYMBOL(blkdev_issue_discard);
+
+struct bio_batch
+{
+ atomic_t done;
+ unsigned long flags;
+ struct completion *wait;
+ bio_end_io_t *end_io;
+};
+
+static void bio_batch_end_io(struct bio *bio, int err)
+{
+ struct bio_batch *bb = bio->bi_private;
+ if (err) {
+ if (err == -EOPNOTSUPP)
+ set_bit(BIO_EOPNOTSUPP, &bb->flags);
+ else
+ clear_bit(BIO_UPTODATE, &bb->flags);
+ }
+ if (bb) {
+ if (bb->end_io)
+ bb->end_io(bio, err);
+ atomic_inc(&bb->done);
+ complete(bb->wait);
+ }
+ bio_put(bio);
+}
+
+/**
+ * blkdev_issue_zeroout generate number of zero filed write bios
+ * @bdev: blockdev to issue
+ * @sector: start sector
+ * @nr_sects: number of sectors to write
+ * @gfp_mask: memory allocation flags (for bio_alloc)
+ * @flags: BLKDEV_IFL_* flags to control behaviour
+ *
+ * Description:
+ * Generate and issue number of bios with zerofiled pages.
+ * Send barrier at the beginning and at the end if requested. This guarantie
+ * correct request ordering. Empty barrier allow us to avoid post queue flush.
+ */
+
+int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
+ sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
+{
+ int ret = 0;
+ struct bio *bio;
+ struct bio_batch bb;
+ unsigned int sz, issued = 0;
+ DECLARE_COMPLETION_ONSTACK(wait);
+
+ atomic_set(&bb.done, 0);
+ bb.flags = 1 << ...Move blkdev_issue_discard from blk-barrier.c because it is
not barrier related.
Later the file will be populated by other helpers.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
block/Makefile | 2 +-
block/blk-barrier.c | 104 ----------------------------------------------
block/blk-lib.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 105 deletions(-)
create mode 100644 block/blk-lib.c
diff --git a/block/Makefile b/block/Makefile
index cb2d515..0bb499a 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -5,7 +5,7 @@
obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \
blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \
blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
- blk-iopoll.o ioctl.o genhd.o scsi_ioctl.o
+ blk-iopoll.o blk-lib.o ioctl.o genhd.o scsi_ioctl.o
obj-$(CONFIG_BLK_DEV_BSG) += bsg.o
obj-$(CONFIG_BLK_CGROUP) += blk-cgroup.o
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index f11eec9..0d710c9 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -347,107 +347,3 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
return ret;
}
EXPORT_SYMBOL(blkdev_issue_flush);
-
-static void blkdev_discard_end_io(struct bio *bio, int err)
-{
- if (err) {
- if (err == -EOPNOTSUPP)
- set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
- clear_bit(BIO_UPTODATE, &bio->bi_flags);
- }
-
- if (bio->bi_private)
- complete(bio->bi_private);
- __free_page(bio_page(bio));
-
- bio_put(bio);
-}
-
-/**
- * blkdev_issue_discard - queue a discard
- * @bdev: blockdev to issue discard for
- * @sector: start sector
- * @nr_sects: number of sectors to discard
- * @gfp_mask: memory allocation flags (for bio_alloc)
- * @flags: BLKDEV_IFL_* flags to control behaviour
- *
- * Description:
- * Issue a discard request for the sectors in question.
- */
-int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
- sector_t ...In some places caller don't want to wait a request to complete.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
block/blk-barrier.c | 33 +++++++++++++++++++--------------
1 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index cf14311..f11eec9 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -286,8 +286,9 @@ static void bio_end_empty_barrier(struct bio *bio, int err)
set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
clear_bit(BIO_UPTODATE, &bio->bi_flags);
}
-
- complete(bio->bi_private);
+ if (bio->bi_private)
+ complete(bio->bi_private);
+ bio_put(bio);
}
/**
@@ -300,7 +301,8 @@ static void bio_end_empty_barrier(struct bio *bio, int err)
* Description:
* Issue a flush for the block device in question. Caller can supply
* room for storing the error offset in case of a flush error, if they
- * wish to.
+ * wish to. If WAIT flag is not passed then caller may check only what
+ * request was pushed in some internal queue for later handling.
*/
int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
sector_t *error_sector, unsigned long flags)
@@ -319,19 +321,22 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
bio = bio_alloc(gfp_mask, 0);
bio->bi_end_io = bio_end_empty_barrier;
- bio->bi_private = &wait;
bio->bi_bdev = bdev;
- submit_bio(WRITE_BARRIER, bio);
-
- wait_for_completion(&wait);
+ if (test_bit(BLKDEV_WAIT, &flags))
+ bio->bi_private = &wait;
- /*
- * The driver must store the error location in ->bi_sector, if
- * it supports it. For non-stacked drivers, this should be copied
- * from blk_rq_pos(rq).
- */
- if (error_sector)
- *error_sector = bio->bi_sector;
+ bio_get(bio);
+ submit_bio(WRITE_BARRIER, bio);
+ if (test_bit(BLKDEV_WAIT, &flags)) {
+ wait_for_completion(&wait);
+ /*
+ * The driver must store the error location in ->bi_sector, if
+ * it supports it. For non-stacked ...The patch just convert all blkdev_issue_xxx function to common
set of flags. Wait/allocation semantics preserved.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
block/blk-barrier.c | 20 +++++++++++---------
block/ioctl.c | 2 +-
drivers/block/drbd/drbd_int.h | 3 ++-
drivers/block/drbd/drbd_receiver.c | 3 ++-
fs/block_dev.c | 3 ++-
fs/btrfs/extent-tree.c | 2 +-
fs/ext3/fsync.c | 3 ++-
fs/ext4/fsync.c | 6 ++++--
fs/gfs2/rgrp.c | 5 +++--
fs/jbd2/checkpoint.c | 3 ++-
fs/jbd2/commit.c | 6 ++++--
fs/reiserfs/file.c | 3 ++-
fs/xfs/linux-2.6/xfs_super.c | 3 ++-
include/linux/blkdev.h | 18 +++++++++++-------
mm/swapfile.c | 9 ++++++---
15 files changed, 55 insertions(+), 34 deletions(-)
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 6d88544..cf14311 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -293,19 +293,22 @@ static void bio_end_empty_barrier(struct bio *bio, int err)
/**
* blkdev_issue_flush - queue a flush
* @bdev: blockdev to issue flush for
+ * @gfp_mask: memory allocation flags (for bio_alloc)
* @error_sector: error sector
+ * @flags: BLKDEV_IFL_* flags to control behaviour
*
* Description:
* Issue a flush for the block device in question. Caller can supply
* room for storing the error offset in case of a flush error, if they
* wish to.
*/
-int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
+int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
+ sector_t *error_sector, unsigned long flags)
{
DECLARE_COMPLETION_ONSTACK(wait);
struct request_queue *q;
struct bio *bio;
- int ret;
+ int ret = 0;
if (bdev->bd_disk == NULL)
return -ENXIO;
@@ -314,7 +317,7 @@ int ...Thanks, I've applied the series. -- Jens Axboe --
