0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/fs.h>
0035 #include <linux/types.h>
0036 #include <linux/slab.h>
0037 #include <linux/highmem.h>
0038 #include <linux/buffer_head.h>
0039 #include <linux/rbtree.h>
0040
0041 #include <cluster/masklog.h>
0042
0043 #include "ocfs2.h"
0044
0045 #include "inode.h"
0046 #include "uptodate.h"
0047 #include "ocfs2_trace.h"
0048
0049 struct ocfs2_meta_cache_item {
0050 struct rb_node c_node;
0051 sector_t c_block;
0052 };
0053
0054 static struct kmem_cache *ocfs2_uptodate_cachep;
0055
0056 u64 ocfs2_metadata_cache_owner(struct ocfs2_caching_info *ci)
0057 {
0058 BUG_ON(!ci || !ci->ci_ops);
0059
0060 return ci->ci_ops->co_owner(ci);
0061 }
0062
0063 struct super_block *ocfs2_metadata_cache_get_super(struct ocfs2_caching_info *ci)
0064 {
0065 BUG_ON(!ci || !ci->ci_ops);
0066
0067 return ci->ci_ops->co_get_super(ci);
0068 }
0069
0070 static void ocfs2_metadata_cache_lock(struct ocfs2_caching_info *ci)
0071 {
0072 BUG_ON(!ci || !ci->ci_ops);
0073
0074 ci->ci_ops->co_cache_lock(ci);
0075 }
0076
0077 static void ocfs2_metadata_cache_unlock(struct ocfs2_caching_info *ci)
0078 {
0079 BUG_ON(!ci || !ci->ci_ops);
0080
0081 ci->ci_ops->co_cache_unlock(ci);
0082 }
0083
0084 void ocfs2_metadata_cache_io_lock(struct ocfs2_caching_info *ci)
0085 {
0086 BUG_ON(!ci || !ci->ci_ops);
0087
0088 ci->ci_ops->co_io_lock(ci);
0089 }
0090
0091 void ocfs2_metadata_cache_io_unlock(struct ocfs2_caching_info *ci)
0092 {
0093 BUG_ON(!ci || !ci->ci_ops);
0094
0095 ci->ci_ops->co_io_unlock(ci);
0096 }
0097
0098
0099 static void ocfs2_metadata_cache_reset(struct ocfs2_caching_info *ci,
0100 int clear)
0101 {
0102 ci->ci_flags |= OCFS2_CACHE_FL_INLINE;
0103 ci->ci_num_cached = 0;
0104
0105 if (clear) {
0106 ci->ci_created_trans = 0;
0107 ci->ci_last_trans = 0;
0108 }
0109 }
0110
0111 void ocfs2_metadata_cache_init(struct ocfs2_caching_info *ci,
0112 const struct ocfs2_caching_operations *ops)
0113 {
0114 BUG_ON(!ops);
0115
0116 ci->ci_ops = ops;
0117 ocfs2_metadata_cache_reset(ci, 1);
0118 }
0119
0120 void ocfs2_metadata_cache_exit(struct ocfs2_caching_info *ci)
0121 {
0122 ocfs2_metadata_cache_purge(ci);
0123 ocfs2_metadata_cache_reset(ci, 1);
0124 }
0125
0126
0127
0128
0129 static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root)
0130 {
0131 unsigned int purged = 0;
0132 struct rb_node *node;
0133 struct ocfs2_meta_cache_item *item;
0134
0135 while ((node = rb_last(root)) != NULL) {
0136 item = rb_entry(node, struct ocfs2_meta_cache_item, c_node);
0137
0138 trace_ocfs2_purge_copied_metadata_tree(
0139 (unsigned long long) item->c_block);
0140
0141 rb_erase(&item->c_node, root);
0142 kmem_cache_free(ocfs2_uptodate_cachep, item);
0143
0144 purged++;
0145 }
0146 return purged;
0147 }
0148
0149
0150
0151
0152
0153
0154
0155 void ocfs2_metadata_cache_purge(struct ocfs2_caching_info *ci)
0156 {
0157 unsigned int tree, to_purge, purged;
0158 struct rb_root root = RB_ROOT;
0159
0160 BUG_ON(!ci || !ci->ci_ops);
0161
0162 ocfs2_metadata_cache_lock(ci);
0163 tree = !(ci->ci_flags & OCFS2_CACHE_FL_INLINE);
0164 to_purge = ci->ci_num_cached;
0165
0166 trace_ocfs2_metadata_cache_purge(
0167 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0168 to_purge, tree);
0169
0170
0171
0172
0173 if (tree)
0174 root = ci->ci_cache.ci_tree;
0175
0176 ocfs2_metadata_cache_reset(ci, 0);
0177 ocfs2_metadata_cache_unlock(ci);
0178
0179 purged = ocfs2_purge_copied_metadata_tree(&root);
0180
0181
0182
0183 if (tree && purged != to_purge)
0184 mlog(ML_ERROR, "Owner %llu, count = %u, purged = %u\n",
0185 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0186 to_purge, purged);
0187 }
0188
0189
0190
0191 static int ocfs2_search_cache_array(struct ocfs2_caching_info *ci,
0192 sector_t item)
0193 {
0194 int i;
0195
0196 for (i = 0; i < ci->ci_num_cached; i++) {
0197 if (item == ci->ci_cache.ci_array[i])
0198 return i;
0199 }
0200
0201 return -1;
0202 }
0203
0204
0205
0206 static struct ocfs2_meta_cache_item *
0207 ocfs2_search_cache_tree(struct ocfs2_caching_info *ci,
0208 sector_t block)
0209 {
0210 struct rb_node * n = ci->ci_cache.ci_tree.rb_node;
0211 struct ocfs2_meta_cache_item *item = NULL;
0212
0213 while (n) {
0214 item = rb_entry(n, struct ocfs2_meta_cache_item, c_node);
0215
0216 if (block < item->c_block)
0217 n = n->rb_left;
0218 else if (block > item->c_block)
0219 n = n->rb_right;
0220 else
0221 return item;
0222 }
0223
0224 return NULL;
0225 }
0226
0227 static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci,
0228 struct buffer_head *bh)
0229 {
0230 int index = -1;
0231 struct ocfs2_meta_cache_item *item = NULL;
0232
0233 ocfs2_metadata_cache_lock(ci);
0234
0235 trace_ocfs2_buffer_cached_begin(
0236 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0237 (unsigned long long) bh->b_blocknr,
0238 !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE));
0239
0240 if (ci->ci_flags & OCFS2_CACHE_FL_INLINE)
0241 index = ocfs2_search_cache_array(ci, bh->b_blocknr);
0242 else
0243 item = ocfs2_search_cache_tree(ci, bh->b_blocknr);
0244
0245 ocfs2_metadata_cache_unlock(ci);
0246
0247 trace_ocfs2_buffer_cached_end(index, item);
0248
0249 return (index != -1) || (item != NULL);
0250 }
0251
0252
0253
0254
0255
0256
0257 int ocfs2_buffer_uptodate(struct ocfs2_caching_info *ci,
0258 struct buffer_head *bh)
0259 {
0260
0261
0262
0263 if (!buffer_uptodate(bh))
0264 return 0;
0265
0266
0267
0268 if (buffer_jbd(bh))
0269 return 1;
0270
0271
0272
0273 return ocfs2_buffer_cached(ci, bh);
0274 }
0275
0276
0277
0278
0279
0280 int ocfs2_buffer_read_ahead(struct ocfs2_caching_info *ci,
0281 struct buffer_head *bh)
0282 {
0283 return buffer_locked(bh) && ocfs2_buffer_cached(ci, bh);
0284 }
0285
0286
0287 static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci,
0288 sector_t block)
0289 {
0290 BUG_ON(ci->ci_num_cached >= OCFS2_CACHE_INFO_MAX_ARRAY);
0291
0292 trace_ocfs2_append_cache_array(
0293 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0294 (unsigned long long)block, ci->ci_num_cached);
0295
0296 ci->ci_cache.ci_array[ci->ci_num_cached] = block;
0297 ci->ci_num_cached++;
0298 }
0299
0300
0301
0302
0303 static void __ocfs2_insert_cache_tree(struct ocfs2_caching_info *ci,
0304 struct ocfs2_meta_cache_item *new)
0305 {
0306 sector_t block = new->c_block;
0307 struct rb_node *parent = NULL;
0308 struct rb_node **p = &ci->ci_cache.ci_tree.rb_node;
0309 struct ocfs2_meta_cache_item *tmp;
0310
0311 trace_ocfs2_insert_cache_tree(
0312 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0313 (unsigned long long)block, ci->ci_num_cached);
0314
0315 while(*p) {
0316 parent = *p;
0317
0318 tmp = rb_entry(parent, struct ocfs2_meta_cache_item, c_node);
0319
0320 if (block < tmp->c_block)
0321 p = &(*p)->rb_left;
0322 else if (block > tmp->c_block)
0323 p = &(*p)->rb_right;
0324 else {
0325
0326 mlog(ML_ERROR, "Duplicate block %llu cached!\n",
0327 (unsigned long long) block);
0328 BUG();
0329 }
0330 }
0331
0332 rb_link_node(&new->c_node, parent, p);
0333 rb_insert_color(&new->c_node, &ci->ci_cache.ci_tree);
0334 ci->ci_num_cached++;
0335 }
0336
0337
0338 static inline int ocfs2_insert_can_use_array(struct ocfs2_caching_info *ci)
0339 {
0340 return (ci->ci_flags & OCFS2_CACHE_FL_INLINE) &&
0341 (ci->ci_num_cached < OCFS2_CACHE_INFO_MAX_ARRAY);
0342 }
0343
0344
0345
0346
0347
0348
0349 static void ocfs2_expand_cache(struct ocfs2_caching_info *ci,
0350 struct ocfs2_meta_cache_item **tree)
0351 {
0352 int i;
0353
0354 mlog_bug_on_msg(ci->ci_num_cached != OCFS2_CACHE_INFO_MAX_ARRAY,
0355 "Owner %llu, num cached = %u, should be %u\n",
0356 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0357 ci->ci_num_cached, OCFS2_CACHE_INFO_MAX_ARRAY);
0358 mlog_bug_on_msg(!(ci->ci_flags & OCFS2_CACHE_FL_INLINE),
0359 "Owner %llu not marked as inline anymore!\n",
0360 (unsigned long long)ocfs2_metadata_cache_owner(ci));
0361
0362
0363
0364 for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++)
0365 tree[i]->c_block = ci->ci_cache.ci_array[i];
0366
0367 ci->ci_flags &= ~OCFS2_CACHE_FL_INLINE;
0368 ci->ci_cache.ci_tree = RB_ROOT;
0369
0370 ci->ci_num_cached = 0;
0371
0372 for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++) {
0373 __ocfs2_insert_cache_tree(ci, tree[i]);
0374 tree[i] = NULL;
0375 }
0376
0377 trace_ocfs2_expand_cache(
0378 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0379 ci->ci_flags, ci->ci_num_cached);
0380 }
0381
0382
0383
0384 static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
0385 sector_t block,
0386 int expand_tree)
0387 {
0388 int i;
0389 struct ocfs2_meta_cache_item *new = NULL;
0390 struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] =
0391 { NULL, };
0392
0393 trace_ocfs2_set_buffer_uptodate(
0394 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0395 (unsigned long long)block, expand_tree);
0396
0397 new = kmem_cache_alloc(ocfs2_uptodate_cachep, GFP_NOFS);
0398 if (!new) {
0399 mlog_errno(-ENOMEM);
0400 return;
0401 }
0402 new->c_block = block;
0403
0404 if (expand_tree) {
0405
0406
0407 for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++) {
0408 tree[i] = kmem_cache_alloc(ocfs2_uptodate_cachep,
0409 GFP_NOFS);
0410 if (!tree[i]) {
0411 mlog_errno(-ENOMEM);
0412 goto out_free;
0413 }
0414
0415
0416 }
0417 }
0418
0419 ocfs2_metadata_cache_lock(ci);
0420 if (ocfs2_insert_can_use_array(ci)) {
0421
0422
0423 ocfs2_append_cache_array(ci, block);
0424 ocfs2_metadata_cache_unlock(ci);
0425 goto out_free;
0426 }
0427
0428 if (expand_tree)
0429 ocfs2_expand_cache(ci, tree);
0430
0431 __ocfs2_insert_cache_tree(ci, new);
0432 ocfs2_metadata_cache_unlock(ci);
0433
0434 new = NULL;
0435 out_free:
0436 if (new)
0437 kmem_cache_free(ocfs2_uptodate_cachep, new);
0438
0439
0440
0441 if (tree[0]) {
0442 for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++)
0443 if (tree[i])
0444 kmem_cache_free(ocfs2_uptodate_cachep,
0445 tree[i]);
0446 }
0447 }
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467 void ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
0468 struct buffer_head *bh)
0469 {
0470 int expand;
0471
0472
0473
0474 if (ocfs2_buffer_cached(ci, bh))
0475 return;
0476
0477 trace_ocfs2_set_buffer_uptodate_begin(
0478 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0479 (unsigned long long)bh->b_blocknr);
0480
0481
0482
0483 ocfs2_metadata_cache_lock(ci);
0484 if (ocfs2_insert_can_use_array(ci)) {
0485
0486
0487 ocfs2_append_cache_array(ci, bh->b_blocknr);
0488 ocfs2_metadata_cache_unlock(ci);
0489 return;
0490 }
0491
0492 expand = 0;
0493 if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) {
0494
0495 expand = 1;
0496 }
0497 ocfs2_metadata_cache_unlock(ci);
0498
0499 __ocfs2_set_buffer_uptodate(ci, bh->b_blocknr, expand);
0500 }
0501
0502
0503
0504
0505 void ocfs2_set_new_buffer_uptodate(struct ocfs2_caching_info *ci,
0506 struct buffer_head *bh)
0507 {
0508
0509 BUG_ON(ocfs2_buffer_cached(ci, bh));
0510
0511 set_buffer_uptodate(bh);
0512
0513 ocfs2_metadata_cache_io_lock(ci);
0514 ocfs2_set_buffer_uptodate(ci, bh);
0515 ocfs2_metadata_cache_io_unlock(ci);
0516 }
0517
0518
0519 static void ocfs2_remove_metadata_array(struct ocfs2_caching_info *ci,
0520 int index)
0521 {
0522 sector_t *array = ci->ci_cache.ci_array;
0523 int bytes;
0524
0525 BUG_ON(index < 0 || index >= OCFS2_CACHE_INFO_MAX_ARRAY);
0526 BUG_ON(index >= ci->ci_num_cached);
0527 BUG_ON(!ci->ci_num_cached);
0528
0529 trace_ocfs2_remove_metadata_array(
0530 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0531 index, ci->ci_num_cached);
0532
0533 ci->ci_num_cached--;
0534
0535
0536
0537 if (ci->ci_num_cached && index < ci->ci_num_cached) {
0538 bytes = sizeof(sector_t) * (ci->ci_num_cached - index);
0539 memmove(&array[index], &array[index + 1], bytes);
0540 }
0541 }
0542
0543
0544 static void ocfs2_remove_metadata_tree(struct ocfs2_caching_info *ci,
0545 struct ocfs2_meta_cache_item *item)
0546 {
0547 trace_ocfs2_remove_metadata_tree(
0548 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0549 (unsigned long long)item->c_block);
0550
0551 rb_erase(&item->c_node, &ci->ci_cache.ci_tree);
0552 ci->ci_num_cached--;
0553 }
0554
0555 static void ocfs2_remove_block_from_cache(struct ocfs2_caching_info *ci,
0556 sector_t block)
0557 {
0558 int index;
0559 struct ocfs2_meta_cache_item *item = NULL;
0560
0561 ocfs2_metadata_cache_lock(ci);
0562 trace_ocfs2_remove_block_from_cache(
0563 (unsigned long long)ocfs2_metadata_cache_owner(ci),
0564 (unsigned long long) block, ci->ci_num_cached,
0565 ci->ci_flags);
0566
0567 if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) {
0568 index = ocfs2_search_cache_array(ci, block);
0569 if (index != -1)
0570 ocfs2_remove_metadata_array(ci, index);
0571 } else {
0572 item = ocfs2_search_cache_tree(ci, block);
0573 if (item)
0574 ocfs2_remove_metadata_tree(ci, item);
0575 }
0576 ocfs2_metadata_cache_unlock(ci);
0577
0578 if (item)
0579 kmem_cache_free(ocfs2_uptodate_cachep, item);
0580 }
0581
0582
0583
0584
0585
0586
0587 void ocfs2_remove_from_cache(struct ocfs2_caching_info *ci,
0588 struct buffer_head *bh)
0589 {
0590 sector_t block = bh->b_blocknr;
0591
0592 ocfs2_remove_block_from_cache(ci, block);
0593 }
0594
0595
0596 void ocfs2_remove_xattr_clusters_from_cache(struct ocfs2_caching_info *ci,
0597 sector_t block,
0598 u32 c_len)
0599 {
0600 struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
0601 unsigned int i, b_len = ocfs2_clusters_to_blocks(sb, 1) * c_len;
0602
0603 for (i = 0; i < b_len; i++, block++)
0604 ocfs2_remove_block_from_cache(ci, block);
0605 }
0606
0607 int __init init_ocfs2_uptodate_cache(void)
0608 {
0609 ocfs2_uptodate_cachep = kmem_cache_create("ocfs2_uptodate",
0610 sizeof(struct ocfs2_meta_cache_item),
0611 0, SLAB_HWCACHE_ALIGN, NULL);
0612 if (!ocfs2_uptodate_cachep)
0613 return -ENOMEM;
0614
0615 return 0;
0616 }
0617
0618 void exit_ocfs2_uptodate_cache(void)
0619 {
0620 kmem_cache_destroy(ocfs2_uptodate_cachep);
0621 }