Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 362

kernel-2.6.18-238.el5.src.rpm

From: Jeff Moyer <jmoyer@redhat.com>
Date: Tue, 3 Nov 2009 11:36:39 -0500
Subject: [block] cfq-iosched: fix aliased req & cooperation detect
Message-id: 1257266206-24003-6-git-send-email-jmoyer@redhat.com
O-Subject: [PATCH 05/12] cfq-iosched: fix bug with aliased request and cooperation detection
Bugzilla: 456181 448130 427709
RH-Acked-by: Rik van Riel <riel@redhat.com>
RH-Acked-by: Josef Bacik <josef@redhat.com>
RH-Acked-by: Vivek Goyal <vgoyal@redhat.com>

commit 3ac6c9f8a66726745136e46f63600550c3eb6cec
Author: Jens Axboe <jens.axboe@oracle.com>
Date:   Thu Apr 23 12:14:56 2009 +0200

    cfq-iosched: fix bug with aliased request and cooperation detection

    cfq_prio_tree_lookup() should return the direct match, yet it always
    returns zero. Fix that.

    cfq_prio_tree_add() assumes that we don't get a direct match, while
    it is very possible that we do. Using O_DIRECT, you can have different
    cfqq with matching requests, since you don't have the page cache
    to serialize things for you. Fix this bug by only adding the cfqq if
    there isn't an existing match.

    Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Jeff Moyer <jmoyer@redhat.com>

diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index b20eba7..7f3674d 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -497,12 +497,13 @@ cfq_prio_tree_lookup(struct cfq_data *cfqd, int ioprio, sector_t sector,
 		else
 			break;
 		p = n;
+		cfqq = NULL;
 	}
 
 	*ret_parent = parent;
 	if (rb_link)
 		*rb_link = p;
-	return NULL;
+	return cfqq;
 }
 
 static void rb_erase_init(struct rb_node *n, struct rb_root *root)
@@ -528,10 +529,10 @@ static void cfq_prio_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 	__cfqq = cfq_prio_tree_lookup(cfqd, cfqq->ioprio,
 				      cfqq->next_crq->request->sector,
 				      &parent, &p);
-	BUG_ON(__cfqq);
-
-	rb_link_node(&cfqq->p_node, parent, p);
-	rb_insert_color(&cfqq->p_node, root);
+	if (!__cfqq) {
+		rb_link_node(&cfqq->p_node, parent, p);
+		rb_insert_color(&cfqq->p_node, root);
+	}
 }
 
 static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)