1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50#include <linux/fs.h>
51#include <linux/types.h>
52#include <linux/slab.h>
53#include <linux/highmem.h>
54#include <linux/buffer_head.h>
55#include <linux/rbtree.h>
56
57#define MLOG_MASK_PREFIX ML_UPTODATE
58
59#include <cluster/masklog.h>
60
61#include "ocfs2.h"
62
63#include "inode.h"
64#include "uptodate.h"
65
66struct ocfs2_meta_cache_item {
67 struct rb_node c_node;
68 sector_t c_block;
69};
70
71static struct kmem_cache *ocfs2_uptodate_cachep = NULL;
72
73u64 ocfs2_metadata_cache_owner(struct ocfs2_caching_info *ci)
74{
75 BUG_ON(!ci || !ci->ci_ops);
76
77 return ci->ci_ops->co_owner(ci);
78}
79
80struct super_block *ocfs2_metadata_cache_get_super(struct ocfs2_caching_info *ci)
81{
82 BUG_ON(!ci || !ci->ci_ops);
83
84 return ci->ci_ops->co_get_super(ci);
85}
86
87static void ocfs2_metadata_cache_lock(struct ocfs2_caching_info *ci)
88{
89 BUG_ON(!ci || !ci->ci_ops);
90
91 ci->ci_ops->co_cache_lock(ci);
92}
93
94static void ocfs2_metadata_cache_unlock(struct ocfs2_caching_info *ci)
95{
96 BUG_ON(!ci || !ci->ci_ops);
97
98 ci->ci_ops->co_cache_unlock(ci);
99}
100
101void ocfs2_metadata_cache_io_lock(struct ocfs2_caching_info *ci)
102{
103 BUG_ON(!ci || !ci->ci_ops);
104
105 ci->ci_ops->co_io_lock(ci);
106}
107
108void ocfs2_metadata_cache_io_unlock(struct ocfs2_caching_info *ci)
109{
110 BUG_ON(!ci || !ci->ci_ops);
111
112 ci->ci_ops->co_io_unlock(ci);
113}
114
115
116static void ocfs2_metadata_cache_reset(struct ocfs2_caching_info *ci,
117 int clear)
118{
119 ci->ci_flags |= OCFS2_CACHE_FL_INLINE;
120 ci->ci_num_cached = 0;
121
122 if (clear) {
123 ci->ci_created_trans = 0;
124 ci->ci_last_trans = 0;
125 }
126}
127
128void ocfs2_metadata_cache_init(struct ocfs2_caching_info *ci,
129 const struct ocfs2_caching_operations *ops)
130{
131 BUG_ON(!ops);
132
133 ci->ci_ops = ops;
134 ocfs2_metadata_cache_reset(ci, 1);
135}
136
137void ocfs2_metadata_cache_exit(struct ocfs2_caching_info *ci)
138{
139 ocfs2_metadata_cache_purge(ci);
140 ocfs2_metadata_cache_reset(ci, 1);
141}
142
143
144
145
146static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root)
147{
148 unsigned int purged = 0;
149 struct rb_node *node;
150 struct ocfs2_meta_cache_item *item;
151
152 while ((node = rb_last(root)) != NULL) {
153 item = rb_entry(node, struct ocfs2_meta_cache_item, c_node);
154
155 mlog(0, "Purge item %llu\n",
156 (unsigned long long) item->c_block);
157
158 rb_erase(&item->c_node, root);
159 kmem_cache_free(ocfs2_uptodate_cachep, item);
160
161 purged++;
162 }
163 return purged;
164}
165
166
167
168
169
170
171
172void ocfs2_metadata_cache_purge(struct ocfs2_caching_info *ci)
173{
174 unsigned int tree, to_purge, purged;
175 struct rb_root root = RB_ROOT;
176
177 BUG_ON(!ci || !ci->ci_ops);
178
179 ocfs2_metadata_cache_lock(ci);
180 tree = !(ci->ci_flags & OCFS2_CACHE_FL_INLINE);
181 to_purge = ci->ci_num_cached;
182
183 mlog(0, "Purge %u %s items from Owner %llu\n", to_purge,
184 tree ? "array" : "tree",
185 (unsigned long long)ocfs2_metadata_cache_owner(ci));
186
187
188
189
190 if (tree)
191 root = ci->ci_cache.ci_tree;
192
193 ocfs2_metadata_cache_reset(ci, 0);
194 ocfs2_metadata_cache_unlock(ci);
195
196 purged = ocfs2_purge_copied_metadata_tree(&root);
197
198
199
200 if (tree && purged != to_purge)
201 mlog(ML_ERROR, "Owner %llu, count = %u, purged = %u\n",
202 (unsigned long long)ocfs2_metadata_cache_owner(ci),
203 to_purge, purged);
204}
205
206
207
208static int ocfs2_search_cache_array(struct ocfs2_caching_info *ci,
209 sector_t item)
210{
211 int i;
212
213 for (i = 0; i < ci->ci_num_cached; i++) {
214 if (item == ci->ci_cache.ci_array[i])
215 return i;
216 }
217
218 return -1;
219}
220
221
222
223static struct ocfs2_meta_cache_item *
224ocfs2_search_cache_tree(struct ocfs2_caching_info *ci,
225 sector_t block)
226{
227 struct rb_node * n = ci->ci_cache.ci_tree.rb_node;
228 struct ocfs2_meta_cache_item *item = NULL;
229
230 while (n) {
231 item = rb_entry(n, struct ocfs2_meta_cache_item, c_node);
232
233 if (block < item->c_block)
234 n = n->rb_left;
235 else if (block > item->c_block)
236 n = n->rb_right;
237 else
238 return item;
239 }
240
241 return NULL;
242}
243
244static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci,
245 struct buffer_head *bh)
246{
247 int index = -1;
248 struct ocfs2_meta_cache_item *item = NULL;
249
250 ocfs2_metadata_cache_lock(ci);
251
252 mlog(0, "Owner %llu, query block %llu (inline = %u)\n",
253 (unsigned long long)ocfs2_metadata_cache_owner(ci),
254 (unsigned long long) bh->b_blocknr,
255 !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE));
256
257 if (ci->ci_flags & OCFS2_CACHE_FL_INLINE)
258 index = ocfs2_search_cache_array(ci, bh->b_blocknr);
259 else
260 item = ocfs2_search_cache_tree(ci, bh->b_blocknr);
261
262 ocfs2_metadata_cache_unlock(ci);
263
264 mlog(0, "index = %d, item = %p\n", index, item);
265
266 return (index != -1) || (item != NULL);
267}
268
269
270
271
272
273
274int ocfs2_buffer_uptodate(struct ocfs2_caching_info *ci,
275 struct buffer_head *bh)
276{
277
278
279
280 if (!buffer_uptodate(bh))
281 return 0;
282
283
284
285 if (buffer_jbd(bh))
286 return 1;
287
288
289
290 return ocfs2_buffer_cached(ci, bh);
291}
292
293
294
295
296
297int ocfs2_buffer_read_ahead(struct ocfs2_caching_info *ci,
298 struct buffer_head *bh)
299{
300 return buffer_locked(bh) && ocfs2_buffer_cached(ci, bh);
301}
302
303
304static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci,
305 sector_t block)
306{
307 BUG_ON(ci->ci_num_cached >= OCFS2_CACHE_INFO_MAX_ARRAY);
308
309 mlog(0, "block %llu takes position %u\n", (unsigned long long) block,
310 ci->ci_num_cached);
311
312 ci->ci_cache.ci_array[ci->ci_num_cached] = block;
313 ci->ci_num_cached++;
314}
315
316
317
318
319static void __ocfs2_insert_cache_tree(struct ocfs2_caching_info *ci,
320 struct ocfs2_meta_cache_item *new)
321{
322 sector_t block = new->c_block;
323 struct rb_node *parent = NULL;
324 struct rb_node **p = &ci->ci_cache.ci_tree.rb_node;
325 struct ocfs2_meta_cache_item *tmp;
326
327 mlog(0, "Insert block %llu num = %u\n", (unsigned long long) block,
328 ci->ci_num_cached);
329
330 while(*p) {
331 parent = *p;
332
333 tmp = rb_entry(parent, struct ocfs2_meta_cache_item, c_node);
334
335 if (block < tmp->c_block)
336 p = &(*p)->rb_left;
337 else if (block > tmp->c_block)
338 p = &(*p)->rb_right;
339 else {
340
341 mlog(ML_ERROR, "Duplicate block %llu cached!\n",
342 (unsigned long long) block);
343 BUG();
344 }
345 }
346
347 rb_link_node(&new->c_node, parent, p);
348 rb_insert_color(&new->c_node, &ci->ci_cache.ci_tree);
349 ci->ci_num_cached++;
350}
351
352
353static inline int ocfs2_insert_can_use_array(struct ocfs2_caching_info *ci)
354{
355 return (ci->ci_flags & OCFS2_CACHE_FL_INLINE) &&
356 (ci->ci_num_cached < OCFS2_CACHE_INFO_MAX_ARRAY);
357}
358
359
360
361
362
363
364static void ocfs2_expand_cache(struct ocfs2_caching_info *ci,
365 struct ocfs2_meta_cache_item **tree)
366{
367 int i;
368
369 mlog_bug_on_msg(ci->ci_num_cached != OCFS2_CACHE_INFO_MAX_ARRAY,
370 "Owner %llu, num cached = %u, should be %u\n",
371 (unsigned long long)ocfs2_metadata_cache_owner(ci),
372 ci->ci_num_cached, OCFS2_CACHE_INFO_MAX_ARRAY);
373 mlog_bug_on_msg(!(ci->ci_flags & OCFS2_CACHE_FL_INLINE),
374 "Owner %llu not marked as inline anymore!\n",
375 (unsigned long long)ocfs2_metadata_cache_owner(ci));
376
377
378
379 for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++)
380 tree[i]->c_block = ci->ci_cache.ci_array[i];
381
382 ci->ci_flags &= ~OCFS2_CACHE_FL_INLINE;
383 ci->ci_cache.ci_tree = RB_ROOT;
384
385 ci->ci_num_cached = 0;
386
387 for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++) {
388 __ocfs2_insert_cache_tree(ci, tree[i]);
389 tree[i] = NULL;
390 }
391
392 mlog(0, "Expanded %llu to a tree cache: flags 0x%x, num = %u\n",
393 (unsigned long long)ocfs2_metadata_cache_owner(ci),
394 ci->ci_flags, ci->ci_num_cached);
395}
396
397
398
399static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
400 sector_t block,
401 int expand_tree)
402{
403 int i;
404 struct ocfs2_meta_cache_item *new = NULL;
405 struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] =
406 { NULL, };
407
408 mlog(0, "Owner %llu, block %llu, expand = %d\n",
409 (unsigned long long)ocfs2_metadata_cache_owner(ci),
410 (unsigned long long)block, expand_tree);
411
412 new = kmem_cache_alloc(ocfs2_uptodate_cachep, GFP_NOFS);
413 if (!new) {
414 mlog_errno(-ENOMEM);
415 return;
416 }
417 new->c_block = block;
418
419 if (expand_tree) {
420
421
422 for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++) {
423 tree[i] = kmem_cache_alloc(ocfs2_uptodate_cachep,
424 GFP_NOFS);
425 if (!tree[i]) {
426 mlog_errno(-ENOMEM);
427 goto out_free;
428 }
429
430
431 }
432 }
433
434 ocfs2_metadata_cache_lock(ci);
435 if (ocfs2_insert_can_use_array(ci)) {
436 mlog(0, "Someone cleared the tree underneath us\n");
437
438
439 ocfs2_append_cache_array(ci, block);
440 ocfs2_metadata_cache_unlock(ci);
441 goto out_free;
442 }
443
444 if (expand_tree)
445 ocfs2_expand_cache(ci, tree);
446
447 __ocfs2_insert_cache_tree(ci, new);
448 ocfs2_metadata_cache_unlock(ci);
449
450 new = NULL;
451out_free:
452 if (new)
453 kmem_cache_free(ocfs2_uptodate_cachep, new);
454
455
456
457 if (tree[0]) {
458 for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++)
459 if (tree[i])
460 kmem_cache_free(ocfs2_uptodate_cachep,
461 tree[i]);
462 }
463}
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483void ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
484 struct buffer_head *bh)
485{
486 int expand;
487
488
489
490 if (ocfs2_buffer_cached(ci, bh))
491 return;
492
493 mlog(0, "Owner %llu, inserting block %llu\n",
494 (unsigned long long)ocfs2_metadata_cache_owner(ci),
495 (unsigned long long)bh->b_blocknr);
496
497
498
499 ocfs2_metadata_cache_lock(ci);
500 if (ocfs2_insert_can_use_array(ci)) {
501
502
503 ocfs2_append_cache_array(ci, bh->b_blocknr);
504 ocfs2_metadata_cache_unlock(ci);
505 return;
506 }
507
508 expand = 0;
509 if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) {
510
511 expand = 1;
512 }
513 ocfs2_metadata_cache_unlock(ci);
514
515 __ocfs2_set_buffer_uptodate(ci, bh->b_blocknr, expand);
516}
517
518
519
520
521void ocfs2_set_new_buffer_uptodate(struct ocfs2_caching_info *ci,
522 struct buffer_head *bh)
523{
524
525 BUG_ON(ocfs2_buffer_cached(ci, bh));
526
527 set_buffer_uptodate(bh);
528
529 ocfs2_metadata_cache_io_lock(ci);
530 ocfs2_set_buffer_uptodate(ci, bh);
531 ocfs2_metadata_cache_io_unlock(ci);
532}
533
534
535static void ocfs2_remove_metadata_array(struct ocfs2_caching_info *ci,
536 int index)
537{
538 sector_t *array = ci->ci_cache.ci_array;
539 int bytes;
540
541 BUG_ON(index < 0 || index >= OCFS2_CACHE_INFO_MAX_ARRAY);
542 BUG_ON(index >= ci->ci_num_cached);
543 BUG_ON(!ci->ci_num_cached);
544
545 mlog(0, "remove index %d (num_cached = %u\n", index,
546 ci->ci_num_cached);
547
548 ci->ci_num_cached--;
549
550
551
552 if (ci->ci_num_cached && index < ci->ci_num_cached) {
553 bytes = sizeof(sector_t) * (ci->ci_num_cached - index);
554 memmove(&array[index], &array[index + 1], bytes);
555 }
556}
557
558
559static void ocfs2_remove_metadata_tree(struct ocfs2_caching_info *ci,
560 struct ocfs2_meta_cache_item *item)
561{
562 mlog(0, "remove block %llu from tree\n",
563 (unsigned long long) item->c_block);
564
565 rb_erase(&item->c_node, &ci->ci_cache.ci_tree);
566 ci->ci_num_cached--;
567}
568
569static void ocfs2_remove_block_from_cache(struct ocfs2_caching_info *ci,
570 sector_t block)
571{
572 int index;
573 struct ocfs2_meta_cache_item *item = NULL;
574
575 ocfs2_metadata_cache_lock(ci);
576 mlog(0, "Owner %llu, remove %llu, items = %u, array = %u\n",
577 (unsigned long long)ocfs2_metadata_cache_owner(ci),
578 (unsigned long long) block, ci->ci_num_cached,
579 ci->ci_flags & OCFS2_CACHE_FL_INLINE);
580
581 if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) {
582 index = ocfs2_search_cache_array(ci, block);
583 if (index != -1)
584 ocfs2_remove_metadata_array(ci, index);
585 } else {
586 item = ocfs2_search_cache_tree(ci, block);
587 if (item)
588 ocfs2_remove_metadata_tree(ci, item);
589 }
590 ocfs2_metadata_cache_unlock(ci);
591
592 if (item)
593 kmem_cache_free(ocfs2_uptodate_cachep, item);
594}
595
596
597
598
599
600
601void ocfs2_remove_from_cache(struct ocfs2_caching_info *ci,
602 struct buffer_head *bh)
603{
604 sector_t block = bh->b_blocknr;
605
606 ocfs2_remove_block_from_cache(ci, block);
607}
608
609
610void ocfs2_remove_xattr_clusters_from_cache(struct ocfs2_caching_info *ci,
611 sector_t block,
612 u32 c_len)
613{
614 struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
615 unsigned int i, b_len = ocfs2_clusters_to_blocks(sb, 1) * c_len;
616
617 for (i = 0; i < b_len; i++, block++)
618 ocfs2_remove_block_from_cache(ci, block);
619}
620
621int __init init_ocfs2_uptodate_cache(void)
622{
623 ocfs2_uptodate_cachep = kmem_cache_create("ocfs2_uptodate",
624 sizeof(struct ocfs2_meta_cache_item),
625 0, SLAB_HWCACHE_ALIGN, NULL);
626 if (!ocfs2_uptodate_cachep)
627 return -ENOMEM;
628
629 mlog(0, "%u inlined cache items per inode.\n",
630 OCFS2_CACHE_INFO_MAX_ARRAY);
631
632 return 0;
633}
634
635void exit_ocfs2_uptodate_cache(void)
636{
637 if (ocfs2_uptodate_cachep)
638 kmem_cache_destroy(ocfs2_uptodate_cachep);
639}
640