This is the series of 14 patches for barriers. This is the "correct"
implementation --- i.e. enabling barriers for any targets.
These patches address the upper layer only (providing barriers to
filesystem), they don't send barrier request (there will be more patches
for that, but they are not yet finalized).
The patches are sorted from the simples to the more complicated.
The first 11 patches shouldn't have effect on anything, they just move
code around. So you can start slowly applying them.
Patch 11 changes generic block layer code, other patches change only dm.
Mikulas
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
02-23-2009, 06:19 PM
Mikulas Patocka
barriers
Introduce a function that adds a bio to the head of the list.
@@ -1590,7 +1579,7 @@ int dm_suspend(struct mapped_device *md,
/* were we interrupted ? */
if (r < 0) {
- dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+ dm_queue_flush(md, NULL);
unlock_fs(md);
goto out; /* pushback list is already flushed, so skip flush */
@@ -1625,7 +1614,7 @@ int dm_resume(struct mapped_device *md)
if (r)
goto out;
@@ -1579,7 +1576,7 @@ int dm_suspend(struct mapped_device *md,
/* were we interrupted ? */
if (r < 0) {
- dm_queue_flush(md, NULL);
+ dm_queue_flush(md);
unlock_fs(md);
goto out; /* pushback list is already flushed, so skip flush */
@@ -1614,7 +1611,7 @@ int dm_resume(struct mapped_device *md)
if (r)
goto out;
- dm_queue_flush(md, NULL);
+ dm_queue_flush(md);
unlock_fs(md);
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
02-23-2009, 06:20 PM
Mikulas Patocka
barriers
Remove struct dm_wq_req and move "work" directly to struct mapped_device.
In the new implementation, the thread will do just one type of work (processing
the queue), there is no need for separate work requests for it.
/*
- * Split the bio into several clones.
+ * Split the bio into several clones and submit it to targets.
*/
-static int __split_bio(struct mapped_device *md, struct bio *bio)
+static int __process_bio(struct mapped_device *md, struct bio *bio)
{
struct clone_info ci;
int error = 0;
@@ -945,7 +945,7 @@ static int dm_request(struct request_que
down_read(&md->io_lock);
}
- r = __split_bio(md, bio);
+ r = __process_bio(md, bio);
up_read(&md->io_lock);
out_req:
@@ -1402,7 +1402,7 @@ static void __flush_deferred_io(struct m
struct bio *c;
while ((c = bio_list_pop(&md->deferred))) {
- if (__split_bio(md, c))
+ if (__process_bio(md, c))
bio_io_error(c);
}
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
02-23-2009, 06:21 PM
Mikulas Patocka
barriers
Move bio_io_error directly to __process_bio, from its caller.
This saves some code duplication in further patches.
Index: linux-2.6.29-rc3-devel/drivers/md/dm.c
================================================== =================
--- linux-2.6.29-rc3-devel.orig/drivers/md/dm.c 2009-02-05 05:39:45.000000000 +0100
+++ linux-2.6.29-rc3-devel/drivers/md/dm.c 2009-02-05 05:40:54.000000000 +0100
@@ -822,18 +822,20 @@ static int __clone_and_map(struct clone_
/*
* Split the bio into several clones and submit it to targets.
*/
-static int __process_bio(struct mapped_device *md, struct bio *bio)
+static void __process_bio(struct mapped_device *md, struct bio *bio)
{
struct clone_info ci;
int error = 0;
ci.map = dm_get_table(md);
- if (unlikely(!ci.map))
- return -EIO;
+ if (unlikely(!ci.map)) {
+ bio_io_error(bio);
+ return;
+ }
if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
dm_table_put(ci.map);
bio_endio(bio, -EOPNOTSUPP);
- return 0;
+ return;
}
ci.md = md;
ci.bio = bio;
@@ -853,8 +855,6 @@ static int __process_bio(struct mapped_d
/* drop the extra reference count */
dec_pending(ci.io, error);
dm_table_put(ci.map);
-
- return 0;
}
/*-----------------------------------------------------------------
* CRUD END
@@ -945,8 +945,9 @@ static int dm_request(struct request_que
down_read(&md->io_lock);
}
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
02-23-2009, 06:21 PM
Mikulas Patocka
barriers
Move wait queue declaration and unplug to dm_wait_for_completion.
The purpose is to minimize duplicate code in the further patches.
The patch reorders functions a little bit. It doesn't change any
functionality. For proper non-deadlock operation, it is required
hat add_wait_queue happens before set_current_state(interruptible)
and before the test for !atomic_read(&md->pending) --- and this
patch follows that.
-static int dm_wait_for_completion(struct mapped_device *md)
+static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
{
int r = 0;
DECLARE_WAITQUEUE(wait, current);
@@ -1382,13 +1382,13 @@ static int dm_wait_for_completion(struct
add_wait_queue(&md->wait, &wait);
while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
+ set_current_state(interruptible);
smp_mb();
if (!atomic_read(&md->pending))
break;
- if (signal_pending(current)) {
+ if (interruptible == TASK_INTERRUPTIBLE && signal_pending(current)) {
r = -EINTR;
break;
}
@@ -1551,7 +1551,7 @@ int dm_suspend(struct mapped_device *md,
/*
* Wait for the already-mapped ios to complete.
*/
- r = dm_wait_for_completion(md);
+ r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE);
down_write(&md->io_lock);
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel