[PATCH] fix the exclusion for ioprio_set()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 63bfe4b..3bacf4b 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -47,6 +47,8 @@
  */
 static const int cfq_max_depth = 2;
 
+static DEFINE_RWLOCK(cfq_exit_lock);
+
 /*
  * for the hash of cfqq inside the cfqd
  */
@@ -1354,13 +1356,19 @@
  */
 static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
 {
-	struct cfq_io_context *cic = ioc->cic;
+	struct cfq_io_context *cic;
+
+	write_lock(&cfq_exit_lock);
+
+	cic = ioc->cic;
 
 	changed_ioprio(cic);
 
 	list_for_each_entry(cic, &cic->list, list)
 		changed_ioprio(cic);
 
+	write_unlock(&cfq_exit_lock);
+
 	return 0;
 }
 
@@ -1450,8 +1458,10 @@
 		 */
 		cic->ioc = ioc;
 		cic->key = cfqd;
+		read_lock(&cfq_exit_lock);
 		ioc->set_ioprio = cfq_ioc_set_ioprio;
 		ioc->cic = cic;
+		read_unlock(&cfq_exit_lock);
 	} else {
 		struct cfq_io_context *__cic;
 
@@ -1487,7 +1497,9 @@
 
 		__cic->ioc = ioc;
 		__cic->key = cfqd;
+		read_lock(&cfq_exit_lock);
 		list_add(&__cic->list, &cic->list);
+		read_unlock(&cfq_exit_lock);
 		cic = __cic;
 	}