|
@@ -23,6 +23,7 @@
|
|
|
#define DEFERRED_SET_SIZE 64
|
|
|
#define MAPPING_POOL_SIZE 1024
|
|
|
#define PRISON_CELLS 1024
|
|
|
+#define COMMIT_PERIOD HZ
|
|
|
|
|
|
/*
|
|
|
* The block size of the device holding pool data must be
|
|
@@ -520,8 +521,10 @@ struct pool {
|
|
|
|
|
|
struct workqueue_struct *wq;
|
|
|
struct work_struct worker;
|
|
|
+ struct delayed_work waker;
|
|
|
|
|
|
unsigned ref_count;
|
|
|
+ unsigned long last_commit_jiffies;
|
|
|
|
|
|
spinlock_t lock;
|
|
|
struct bio_list deferred_bios;
|
|
@@ -1271,6 +1274,12 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static int need_commit_due_to_time(struct pool *pool)
|
|
|
+{
|
|
|
+ return jiffies < pool->last_commit_jiffies ||
|
|
|
+ jiffies > pool->last_commit_jiffies + COMMIT_PERIOD;
|
|
|
+}
|
|
|
+
|
|
|
static void process_deferred_bios(struct pool *pool)
|
|
|
{
|
|
|
unsigned long flags;
|
|
@@ -1312,7 +1321,7 @@ static void process_deferred_bios(struct pool *pool)
|
|
|
bio_list_init(&pool->deferred_flush_bios);
|
|
|
spin_unlock_irqrestore(&pool->lock, flags);
|
|
|
|
|
|
- if (bio_list_empty(&bios))
|
|
|
+ if (bio_list_empty(&bios) && !need_commit_due_to_time(pool))
|
|
|
return;
|
|
|
|
|
|
r = dm_pool_commit_metadata(pool->pmd);
|
|
@@ -1323,6 +1332,7 @@ static void process_deferred_bios(struct pool *pool)
|
|
|
bio_io_error(bio);
|
|
|
return;
|
|
|
}
|
|
|
+ pool->last_commit_jiffies = jiffies;
|
|
|
|
|
|
while ((bio = bio_list_pop(&bios)))
|
|
|
generic_make_request(bio);
|
|
@@ -1336,6 +1346,17 @@ static void do_worker(struct work_struct *ws)
|
|
|
process_deferred_bios(pool);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * We want to commit periodically so that not too much
|
|
|
+ * unwritten data builds up.
|
|
|
+ */
|
|
|
+static void do_waker(struct work_struct *ws)
|
|
|
+{
|
|
|
+ struct pool *pool = container_of(to_delayed_work(ws), struct pool, waker);
|
|
|
+ wake_worker(pool);
|
|
|
+ queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD);
|
|
|
+}
|
|
|
+
|
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
/*
|
|
@@ -1545,6 +1566,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
|
|
|
}
|
|
|
|
|
|
INIT_WORK(&pool->worker, do_worker);
|
|
|
+ INIT_DELAYED_WORK(&pool->waker, do_waker);
|
|
|
spin_lock_init(&pool->lock);
|
|
|
bio_list_init(&pool->deferred_bios);
|
|
|
bio_list_init(&pool->deferred_flush_bios);
|
|
@@ -1571,6 +1593,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
|
|
|
goto bad_endio_hook_pool;
|
|
|
}
|
|
|
pool->ref_count = 1;
|
|
|
+ pool->last_commit_jiffies = jiffies;
|
|
|
pool->pool_md = pool_md;
|
|
|
pool->md_dev = metadata_dev;
|
|
|
__pool_table_insert(pool);
|
|
@@ -1900,7 +1923,7 @@ static void pool_resume(struct dm_target *ti)
|
|
|
__requeue_bios(pool);
|
|
|
spin_unlock_irqrestore(&pool->lock, flags);
|
|
|
|
|
|
- wake_worker(pool);
|
|
|
+ do_waker(&pool->waker.work);
|
|
|
}
|
|
|
|
|
|
static void pool_postsuspend(struct dm_target *ti)
|
|
@@ -1909,6 +1932,7 @@ static void pool_postsuspend(struct dm_target *ti)
|
|
|
struct pool_c *pt = ti->private;
|
|
|
struct pool *pool = pt->pool;
|
|
|
|
|
|
+ cancel_delayed_work(&pool->waker);
|
|
|
flush_workqueue(pool->wq);
|
|
|
|
|
|
r = dm_pool_commit_metadata(pool->pmd);
|