[PATCH] md - 1 of 1 - Register mergeable function for linear so requests don't cross device boundries

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

 




### Comments for ChangeSet

We abstract out "which_dev" which finds which device a sector is on
and us it to make sure both ends of a to-be-merged request will
be on the same device.



 ----------- Diffstat output ------------
 ./drivers/md/linear.c |   69 +++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 17 deletions(-)

--- ./drivers/md/linear.c	2002/10/16 04:48:24	1.1
+++ ./drivers/md/linear.c	2002/10/16 04:49:22	1.2
@@ -28,6 +28,45 @@
 #define MD_PERSONALITY
 #define DEVICE_NR(device) (minor(device))
 
+/*
+ * find which device holds a particular offset 
+ */
+static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
+{
+	struct linear_hash *hash;
+	linear_conf_t *conf = mddev_to_conf(mddev);
+	sector_t block = sector >> 1;
+
+	hash = conf->hash_table + sector_div(block, conf->smallest->size);
+
+	if ((sector>>1) >= (hash->dev0->size + hash->dev0->offset))
+		return hash->dev1;
+	else
+		return hash->dev0;
+}
+
+
+/**
+ *	linear_mergeable_bvec -- tell bio layer if a two requests can be merged
+ *	@q: request queue
+ *	@bio: the buffer head that's been built up so far
+ *	@biovec: the request that could be merged to it.
+ *
+ *	Return 1 if the merge is not permitted (because the
+ *	result would cross a device boundary), 0 otherwise.
+ */
+static int linear_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec)
+{
+	mddev_t *mddev = q->queuedata;
+	dev_info_t *dev0, *dev1;
+
+	dev0 = which_dev(mddev, bio->bi_sector);
+	dev1 = which_dev(mddev, bio->bi_sector +
+			        ((bio->bi_size + biovec->bv_len - 1) >> 9));
+
+	return dev0 != dev1;
+}
+
 static int linear_run (mddev_t *mddev)
 {
 	linear_conf_t *conf;
@@ -110,6 +149,7 @@ static int linear_run (mddev_t *mddev)
 	if (table-conf->hash_table != nb_zone)
 		BUG();
 
+	blk_queue_merge_bvec(&mddev->queue, linear_mergeable_bvec);
 	return 0;
 
 out:
@@ -134,28 +174,23 @@ static int linear_stop (mddev_t *mddev)
 static int linear_make_request (request_queue_t *q, struct bio *bio)
 {
 	mddev_t *mddev = q->queuedata;
-	linear_conf_t *conf = mddev_to_conf(mddev);
-	struct linear_hash *hash;
 	dev_info_t *tmp_dev;
-	long block;
+	sector_t block;
 
+	tmp_dev = which_dev(mddev, bio->bi_sector);
 	block = bio->bi_sector >> 1;
-	hash = conf->hash_table + (block / conf->smallest->size);
   
-	if (block >= (hash->dev0->size + hash->dev0->offset)) {
-		if (!hash->dev1) {
-			printk ("linear_make_request : hash->dev1==NULL for block %ld\n",
-						block);
-			bio_io_error(bio, bio->bi_size);
-			return 0;
-		}
-		tmp_dev = hash->dev1;
-	} else
-		tmp_dev = hash->dev0;
+	if (unlikely(!tmp_dev)) {
+		printk ("linear_make_request : hash->dev1==NULL for block %llu\n",
+			(unsigned long long)block);
+		bio_io_error(bio, bio->bi_size);
+		return 0;
+	}
     
-	if (block >= (tmp_dev->size + tmp_dev->offset)
-				|| block < tmp_dev->offset) {
-		printk ("linear_make_request: Block %ld out of bounds on dev %s size %ld offset %ld\n", block, bdevname(tmp_dev->rdev->bdev), tmp_dev->size, tmp_dev->offset);
+	if (unlikely(block >= (tmp_dev->size + tmp_dev->offset)
+		     || block < tmp_dev->offset)) {
+		printk ("linear_make_request: Block %llu out of bounds on dev %s size %ld offset %ld\n",
+			(unsigned long long)block, bdevname(tmp_dev->rdev->bdev), tmp_dev->size, tmp_dev->offset);
 		bio_io_error(bio, bio->bi_size);
 		return 0;
 	}
-
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux