From: Milan Broz <mbroz@redhat.com>
To: Alasdair G Kergon <agk@redhat.com>
Cc: device-mapper development <dm-devel@redhat.com>
Subject: [RFC PATCH 4/4] dm core: wait for barrier in process in suspend
Date: Tue, 08 Jul 2008 18:49:14 +0200 [thread overview]
Message-ID: <48739A8A.6070005@redhat.com> (raw)
Implement waiting for barrier in dm_suspend request.
suspend_lock cannot be used inside barrier processing,
because there can be generated new barrier request during suspend
process (e.g. in lock_fs() call).
Add wait for for ongoing barrier to finish before suspending.
There are two status bits used:
DMF_BLOCK_IO -> all ios are queued
DMF_BARRIER -> device is processing barrier (always include BLOCK_IO too).
Suspend call simply waits till DMF_BARRIER disappear and immediatelly
and switch to BLOCK_IO to prevent another barrier to start.
Signed-off-by: Milan Broz <mbroz@redhat.com>
---
drivers/md/dm.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 1a65389..d7b2a17 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1452,6 +1452,13 @@ static void __flush_deferred_io(struct mapped_device *md, int barrier_flag)
while ((c = bio_list_pop(&md->deferred))) {
barrier = bio_barrier(c);
+ /* FIXME: is this possible here? */
+ /* New barrier and no flag */
+ if (barrier && !test_bit(DMF_BARRIER, &md->flags)) {
+ __submit_barrier(md, c);
+ return;
+ }
+
if (__split_bio(md, c))
bio_io_error(c);
@@ -1591,6 +1598,47 @@ static void unlock_fs(struct mapped_device *md)
clear_bit(DMF_FROZEN, &md->flags);
}
+static int _blockio_if_not_in_barrier(struct mapped_device *md)
+{
+ int in_barrier;
+
+ down_write(&md->io_lock);
+ smp_mb();
+ in_barrier = test_bit(DMF_BARRIER, &md->flags);
+ if (!in_barrier)
+ set_bit(DMF_BLOCK_IO, &md->flags);
+ up_write(&md->io_lock);
+
+ return !in_barrier;
+}
+
+static int dm_wait_blockio(struct mapped_device *md)
+{
+ int r = 0;
+
+ while (1) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (_blockio_if_not_in_barrier(md))
+ break;
+
+ if (signal_pending(current)) {
+ r = -EINTR;
+ break;
+ }
+
+ /*
+ * We cannot use io_schedule here
+ * all io can be already processed.
+ * FIXME: starvation here?
+ */
+ schedule_timeout(HZ/100);
+ }
+ set_current_state(TASK_RUNNING);
+
+ return r;
+}
+
/*
* We need to be able to change a mapping table under a mounted
* filesystem. For example we might want to move some data in
@@ -1613,12 +1661,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
goto out_unlock;
}
- /* FIXME: temporary, it must not fail here */
- if (test_bit(DMF_BARRIER, &md->flags)) {
- r = -EBUSY;
- goto out_unlock;
- }
-
map = dm_get_table(md);
/*
@@ -1653,10 +1695,13 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
/*
* First we set the BLOCK_IO flag so no more ios will be mapped.
+ * But wait for possible ongoing barrier to finish first.
*/
- down_write(&md->io_lock);
- set_bit(DMF_BLOCK_IO, &md->flags);
+ r = dm_wait_blockio(md);
+ if (r)
+ goto out;
+ down_write(&md->io_lock);
add_wait_queue(&md->wait, &wait);
up_write(&md->io_lock);
reply other threads:[~2008-07-08 16:49 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48739A8A.6070005@redhat.com \
--to=mbroz@redhat.com \
--cc=agk@redhat.com \
--cc=dm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.