aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/persistent-data/dm-block-manager.c5
-rw-r--r--drivers/md/persistent-data/dm-block-manager.h5
-rw-r--r--drivers/md/persistent-data/dm-btree.c26
3 files changed, 31 insertions, 5 deletions
diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c
index 81b513890e2b..a7e8bf296388 100644
--- a/drivers/md/persistent-data/dm-block-manager.c
+++ b/drivers/md/persistent-data/dm-block-manager.c
@@ -615,6 +615,11 @@ int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
615} 615}
616EXPORT_SYMBOL_GPL(dm_bm_flush_and_unlock); 616EXPORT_SYMBOL_GPL(dm_bm_flush_and_unlock);
617 617
618void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b)
619{
620 dm_bufio_prefetch(bm->bufio, b, 1);
621}
622
618void dm_bm_set_read_only(struct dm_block_manager *bm) 623void dm_bm_set_read_only(struct dm_block_manager *bm)
619{ 624{
620 bm->read_only = true; 625 bm->read_only = true;
diff --git a/drivers/md/persistent-data/dm-block-manager.h b/drivers/md/persistent-data/dm-block-manager.h
index be5bff61be28..9a82083a66b6 100644
--- a/drivers/md/persistent-data/dm-block-manager.h
+++ b/drivers/md/persistent-data/dm-block-manager.h
@@ -108,6 +108,11 @@ int dm_bm_unlock(struct dm_block *b);
108int dm_bm_flush_and_unlock(struct dm_block_manager *bm, 108int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
109 struct dm_block *superblock); 109 struct dm_block *superblock);
110 110
111 /*
112 * Request data be prefetched into the cache.
113 */
114void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b);
115
111/* 116/*
112 * Switches the bm to a read only mode. Once read-only mode 117 * Switches the bm to a read only mode. Once read-only mode
113 * has been entered the following functions will return -EPERM. 118 * has been entered the following functions will return -EPERM.
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c
index e872996e098d..468e371ee9b2 100644
--- a/drivers/md/persistent-data/dm-btree.c
+++ b/drivers/md/persistent-data/dm-btree.c
@@ -161,6 +161,7 @@ struct frame {
161}; 161};
162 162
163struct del_stack { 163struct del_stack {
164 struct dm_btree_info *info;
164 struct dm_transaction_manager *tm; 165 struct dm_transaction_manager *tm;
165 int top; 166 int top;
166 struct frame spine[MAX_SPINE_DEPTH]; 167 struct frame spine[MAX_SPINE_DEPTH];
@@ -183,6 +184,20 @@ static int unprocessed_frames(struct del_stack *s)
183 return s->top >= 0; 184 return s->top >= 0;
184} 185}
185 186
187static void prefetch_children(struct del_stack *s, struct frame *f)
188{
189 unsigned i;
190 struct dm_block_manager *bm = dm_tm_get_bm(s->tm);
191
192 for (i = 0; i < f->nr_children; i++)
193 dm_bm_prefetch(bm, value64(f->n, i));
194}
195
196static bool is_internal_level(struct dm_btree_info *info, struct frame *f)
197{
198 return f->level < (info->levels - 1);
199}
200
186static int push_frame(struct del_stack *s, dm_block_t b, unsigned level) 201static int push_frame(struct del_stack *s, dm_block_t b, unsigned level)
187{ 202{
188 int r; 203 int r;
@@ -205,6 +220,7 @@ static int push_frame(struct del_stack *s, dm_block_t b, unsigned level)
205 dm_tm_dec(s->tm, b); 220 dm_tm_dec(s->tm, b);
206 221
207 else { 222 else {
223 uint32_t flags;
208 struct frame *f = s->spine + ++s->top; 224 struct frame *f = s->spine + ++s->top;
209 225
210 r = dm_tm_read_lock(s->tm, b, &btree_node_validator, &f->b); 226 r = dm_tm_read_lock(s->tm, b, &btree_node_validator, &f->b);
@@ -217,6 +233,10 @@ static int push_frame(struct del_stack *s, dm_block_t b, unsigned level)
217 f->level = level; 233 f->level = level;
218 f->nr_children = le32_to_cpu(f->n->header.nr_entries); 234 f->nr_children = le32_to_cpu(f->n->header.nr_entries);
219 f->current_child = 0; 235 f->current_child = 0;
236
237 flags = le32_to_cpu(f->n->header.flags);
238 if (flags & INTERNAL_NODE || is_internal_level(s->info, f))
239 prefetch_children(s, f);
220 } 240 }
221 241
222 return 0; 242 return 0;
@@ -230,11 +250,6 @@ static void pop_frame(struct del_stack *s)
230 dm_tm_unlock(s->tm, f->b); 250 dm_tm_unlock(s->tm, f->b);
231} 251}
232 252
233static bool is_internal_level(struct dm_btree_info *info, struct frame *f)
234{
235 return f->level < (info->levels - 1);
236}
237
238int dm_btree_del(struct dm_btree_info *info, dm_block_t root) 253int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
239{ 254{
240 int r; 255 int r;
@@ -243,6 +258,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
243 s = kmalloc(sizeof(*s), GFP_KERNEL); 258 s = kmalloc(sizeof(*s), GFP_KERNEL);
244 if (!s) 259 if (!s)
245 return -ENOMEM; 260 return -ENOMEM;
261 s->info = info;
246 s->tm = info->tm; 262 s->tm = info->tm;
247 s->top = -1; 263 s->top = -1;
248 264