aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/uptodate.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2009-02-10 23:00:41 -0500
committerJoel Becker <joel.becker@oracle.com>2009-09-04 19:07:48 -0400
commit8cb471e8f82506937fe5e2e9fb0bf90f6b1f1170 (patch)
treee275a8f5db101a9990ba44931cfd116123112b11 /fs/ocfs2/uptodate.c
parent6e5a3d7538ad4e46a976862f593faf65750e37cc (diff)
ocfs2: Take the inode out of the metadata read/write paths.
We are really passing the inode into the ocfs2_read/write_blocks() functions to get at the metadata cache. This commit passes the cache directly into the metadata block functions, divorcing them from the inode. Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/uptodate.c')
-rw-r--r--fs/ocfs2/uptodate.c83
1 files changed, 38 insertions, 45 deletions
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c
index 226d0429fd7f..1c829e451019 100644
--- a/fs/ocfs2/uptodate.c
+++ b/fs/ocfs2/uptodate.c
@@ -75,13 +75,20 @@ struct ocfs2_meta_cache_item {
75 75
76static struct kmem_cache *ocfs2_uptodate_cachep = NULL; 76static struct kmem_cache *ocfs2_uptodate_cachep = NULL;
77 77
78static u64 ocfs2_metadata_cache_owner(struct ocfs2_caching_info *ci) 78u64 ocfs2_metadata_cache_owner(struct ocfs2_caching_info *ci)
79{ 79{
80 BUG_ON(!ci || !ci->ci_ops); 80 BUG_ON(!ci || !ci->ci_ops);
81 81
82 return ci->ci_ops->co_owner(ci); 82 return ci->ci_ops->co_owner(ci);
83} 83}
84 84
85struct super_block *ocfs2_metadata_cache_get_super(struct ocfs2_caching_info *ci)
86{
87 BUG_ON(!ci || !ci->ci_ops);
88
89 return ci->ci_ops->co_get_super(ci);
90}
91
85static void ocfs2_metadata_cache_lock(struct ocfs2_caching_info *ci) 92static void ocfs2_metadata_cache_lock(struct ocfs2_caching_info *ci)
86{ 93{
87 BUG_ON(!ci || !ci->ci_ops); 94 BUG_ON(!ci || !ci->ci_ops);
@@ -96,14 +103,14 @@ static void ocfs2_metadata_cache_unlock(struct ocfs2_caching_info *ci)
96 ci->ci_ops->co_cache_unlock(ci); 103 ci->ci_ops->co_cache_unlock(ci);
97} 104}
98 105
99static void ocfs2_metadata_cache_io_lock(struct ocfs2_caching_info *ci) 106void ocfs2_metadata_cache_io_lock(struct ocfs2_caching_info *ci)
100{ 107{
101 BUG_ON(!ci || !ci->ci_ops); 108 BUG_ON(!ci || !ci->ci_ops);
102 109
103 ci->ci_ops->co_io_lock(ci); 110 ci->ci_ops->co_io_lock(ci);
104} 111}
105 112
106static void ocfs2_metadata_cache_io_unlock(struct ocfs2_caching_info *ci) 113void ocfs2_metadata_cache_io_unlock(struct ocfs2_caching_info *ci)
107{ 114{
108 BUG_ON(!ci || !ci->ci_ops); 115 BUG_ON(!ci || !ci->ci_ops);
109 116
@@ -149,11 +156,9 @@ static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root)
149 * This function is a few more lines longer than necessary due to some 156 * This function is a few more lines longer than necessary due to some
150 * accounting done here, but I think it's worth tracking down those 157 * accounting done here, but I think it's worth tracking down those
151 * bugs sooner -- Mark */ 158 * bugs sooner -- Mark */
152void ocfs2_metadata_cache_purge(struct inode *inode) 159void ocfs2_metadata_cache_purge(struct ocfs2_caching_info *ci)
153{ 160{
154 struct ocfs2_inode_info *oi = OCFS2_I(inode);
155 unsigned int tree, to_purge, purged; 161 unsigned int tree, to_purge, purged;
156 struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
157 struct rb_root root = RB_ROOT; 162 struct rb_root root = RB_ROOT;
158 163
159 BUG_ON(!ci || !ci->ci_ops); 164 BUG_ON(!ci || !ci->ci_ops);
@@ -223,12 +228,11 @@ ocfs2_search_cache_tree(struct ocfs2_caching_info *ci,
223 return NULL; 228 return NULL;
224} 229}
225 230
226static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi, 231static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci,
227 struct buffer_head *bh) 232 struct buffer_head *bh)
228{ 233{
229 int index = -1; 234 int index = -1;
230 struct ocfs2_meta_cache_item *item = NULL; 235 struct ocfs2_meta_cache_item *item = NULL;
231 struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
232 236
233 ocfs2_metadata_cache_lock(ci); 237 ocfs2_metadata_cache_lock(ci);
234 238
@@ -238,11 +242,9 @@ static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi,
238 !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE)); 242 !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE));
239 243
240 if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) 244 if (ci->ci_flags & OCFS2_CACHE_FL_INLINE)
241 index = ocfs2_search_cache_array(&oi->ip_metadata_cache, 245 index = ocfs2_search_cache_array(ci, bh->b_blocknr);
242 bh->b_blocknr);
243 else 246 else
244 item = ocfs2_search_cache_tree(&oi->ip_metadata_cache, 247 item = ocfs2_search_cache_tree(ci, bh->b_blocknr);
245 bh->b_blocknr);
246 248
247 ocfs2_metadata_cache_unlock(ci); 249 ocfs2_metadata_cache_unlock(ci);
248 250
@@ -256,7 +258,7 @@ static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi,
256 * 258 *
257 * This can be called under lock_buffer() 259 * This can be called under lock_buffer()
258 */ 260 */
259int ocfs2_buffer_uptodate(struct inode *inode, 261int ocfs2_buffer_uptodate(struct ocfs2_caching_info *ci,
260 struct buffer_head *bh) 262 struct buffer_head *bh)
261{ 263{
262 /* Doesn't matter if the bh is in our cache or not -- if it's 264 /* Doesn't matter if the bh is in our cache or not -- if it's
@@ -272,17 +274,17 @@ int ocfs2_buffer_uptodate(struct inode *inode,
272 274
273 /* Ok, locally the buffer is marked as up to date, now search 275 /* Ok, locally the buffer is marked as up to date, now search
274 * our cache to see if we can trust that. */ 276 * our cache to see if we can trust that. */
275 return ocfs2_buffer_cached(OCFS2_I(inode), bh); 277 return ocfs2_buffer_cached(ci, bh);
276} 278}
277 279
278/* 280/*
279 * Determine whether a buffer is currently out on a read-ahead request. 281 * Determine whether a buffer is currently out on a read-ahead request.
280 * ci_io_sem should be held to serialize submitters with the logic here. 282 * ci_io_sem should be held to serialize submitters with the logic here.
281 */ 283 */
282int ocfs2_buffer_read_ahead(struct inode *inode, 284int ocfs2_buffer_read_ahead(struct ocfs2_caching_info *ci,
283 struct buffer_head *bh) 285 struct buffer_head *bh)
284{ 286{
285 return buffer_locked(bh) && ocfs2_buffer_cached(OCFS2_I(inode), bh); 287 return buffer_locked(bh) && ocfs2_buffer_cached(ci, bh);
286} 288}
287 289
288/* Requires ip_lock */ 290/* Requires ip_lock */
@@ -335,8 +337,7 @@ static void __ocfs2_insert_cache_tree(struct ocfs2_caching_info *ci,
335} 337}
336 338
337/* co_cache_lock() must be held */ 339/* co_cache_lock() must be held */
338static inline int ocfs2_insert_can_use_array(struct ocfs2_inode_info *oi, 340static inline int ocfs2_insert_can_use_array(struct ocfs2_caching_info *ci)
339 struct ocfs2_caching_info *ci)
340{ 341{
341 return (ci->ci_flags & OCFS2_CACHE_FL_INLINE) && 342 return (ci->ci_flags & OCFS2_CACHE_FL_INLINE) &&
342 (ci->ci_num_cached < OCFS2_CACHE_INFO_MAX_ARRAY); 343 (ci->ci_num_cached < OCFS2_CACHE_INFO_MAX_ARRAY);
@@ -347,11 +348,10 @@ static inline int ocfs2_insert_can_use_array(struct ocfs2_inode_info *oi,
347 * when to free in case of error. 348 * when to free in case of error.
348 * 349 *
349 * The co_cache_lock() must be held. */ 350 * The co_cache_lock() must be held. */
350static void ocfs2_expand_cache(struct ocfs2_inode_info *oi, 351static void ocfs2_expand_cache(struct ocfs2_caching_info *ci,
351 struct ocfs2_meta_cache_item **tree) 352 struct ocfs2_meta_cache_item **tree)
352{ 353{
353 int i; 354 int i;
354 struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
355 355
356 mlog_bug_on_msg(ci->ci_num_cached != OCFS2_CACHE_INFO_MAX_ARRAY, 356 mlog_bug_on_msg(ci->ci_num_cached != OCFS2_CACHE_INFO_MAX_ARRAY,
357 "Owner %llu, num cached = %u, should be %u\n", 357 "Owner %llu, num cached = %u, should be %u\n",
@@ -383,12 +383,11 @@ static void ocfs2_expand_cache(struct ocfs2_inode_info *oi,
383 383
384/* Slow path function - memory allocation is necessary. See the 384/* Slow path function - memory allocation is necessary. See the
385 * comment above ocfs2_set_buffer_uptodate for more information. */ 385 * comment above ocfs2_set_buffer_uptodate for more information. */
386static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi, 386static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
387 sector_t block, 387 sector_t block,
388 int expand_tree) 388 int expand_tree)
389{ 389{
390 int i; 390 int i;
391 struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
392 struct ocfs2_meta_cache_item *new = NULL; 391 struct ocfs2_meta_cache_item *new = NULL;
393 struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] = 392 struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] =
394 { NULL, }; 393 { NULL, };
@@ -420,7 +419,7 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi,
420 } 419 }
421 420
422 ocfs2_metadata_cache_lock(ci); 421 ocfs2_metadata_cache_lock(ci);
423 if (ocfs2_insert_can_use_array(oi, ci)) { 422 if (ocfs2_insert_can_use_array(ci)) {
424 mlog(0, "Someone cleared the tree underneath us\n"); 423 mlog(0, "Someone cleared the tree underneath us\n");
425 /* Ok, items were removed from the cache in between 424 /* Ok, items were removed from the cache in between
426 * locks. Detect this and revert back to the fast path */ 425 * locks. Detect this and revert back to the fast path */
@@ -430,7 +429,7 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi,
430 } 429 }
431 430
432 if (expand_tree) 431 if (expand_tree)
433 ocfs2_expand_cache(oi, tree); 432 ocfs2_expand_cache(ci, tree);
434 433
435 __ocfs2_insert_cache_tree(ci, new); 434 __ocfs2_insert_cache_tree(ci, new);
436 ocfs2_metadata_cache_unlock(ci); 435 ocfs2_metadata_cache_unlock(ci);
@@ -468,16 +467,14 @@ out_free:
468 * Readahead buffers can be passed in here before the I/O request is 467 * Readahead buffers can be passed in here before the I/O request is
469 * completed. 468 * completed.
470 */ 469 */
471void ocfs2_set_buffer_uptodate(struct inode *inode, 470void ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
472 struct buffer_head *bh) 471 struct buffer_head *bh)
473{ 472{
474 int expand; 473 int expand;
475 struct ocfs2_inode_info *oi = OCFS2_I(inode);
476 struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
477 474
478 /* The block may very well exist in our cache already, so avoid 475 /* The block may very well exist in our cache already, so avoid
479 * doing any more work in that case. */ 476 * doing any more work in that case. */
480 if (ocfs2_buffer_cached(oi, bh)) 477 if (ocfs2_buffer_cached(ci, bh))
481 return; 478 return;
482 479
483 mlog(0, "Owner %llu, inserting block %llu\n", 480 mlog(0, "Owner %llu, inserting block %llu\n",
@@ -487,7 +484,7 @@ void ocfs2_set_buffer_uptodate(struct inode *inode,
487 /* No need to recheck under spinlock - insertion is guarded by 484 /* No need to recheck under spinlock - insertion is guarded by
488 * co_io_lock() */ 485 * co_io_lock() */
489 ocfs2_metadata_cache_lock(ci); 486 ocfs2_metadata_cache_lock(ci);
490 if (ocfs2_insert_can_use_array(oi, ci)) { 487 if (ocfs2_insert_can_use_array(ci)) {
491 /* Fast case - it's an array and there's a free 488 /* Fast case - it's an array and there's a free
492 * spot. */ 489 * spot. */
493 ocfs2_append_cache_array(ci, bh->b_blocknr); 490 ocfs2_append_cache_array(ci, bh->b_blocknr);
@@ -502,25 +499,22 @@ void ocfs2_set_buffer_uptodate(struct inode *inode,
502 } 499 }
503 ocfs2_metadata_cache_unlock(ci); 500 ocfs2_metadata_cache_unlock(ci);
504 501
505 __ocfs2_set_buffer_uptodate(oi, bh->b_blocknr, expand); 502 __ocfs2_set_buffer_uptodate(ci, bh->b_blocknr, expand);
506} 503}
507 504
508/* Called against a newly allocated buffer. Most likely nobody should 505/* Called against a newly allocated buffer. Most likely nobody should
509 * be able to read this sort of metadata while it's still being 506 * be able to read this sort of metadata while it's still being
510 * allocated, but this is careful to take co_io_lock() anyway. */ 507 * allocated, but this is careful to take co_io_lock() anyway. */
511void ocfs2_set_new_buffer_uptodate(struct inode *inode, 508void ocfs2_set_new_buffer_uptodate(struct ocfs2_caching_info *ci,
512 struct buffer_head *bh) 509 struct buffer_head *bh)
513{ 510{
514 struct ocfs2_inode_info *oi = OCFS2_I(inode);
515 struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
516
517 /* This should definitely *not* exist in our cache */ 511 /* This should definitely *not* exist in our cache */
518 BUG_ON(ocfs2_buffer_cached(oi, bh)); 512 BUG_ON(ocfs2_buffer_cached(ci, bh));
519 513
520 set_buffer_uptodate(bh); 514 set_buffer_uptodate(bh);
521 515
522 ocfs2_metadata_cache_io_lock(ci); 516 ocfs2_metadata_cache_io_lock(ci);
523 ocfs2_set_buffer_uptodate(inode, bh); 517 ocfs2_set_buffer_uptodate(ci, bh);
524 ocfs2_metadata_cache_io_unlock(ci); 518 ocfs2_metadata_cache_io_unlock(ci);
525} 519}
526 520
@@ -559,13 +553,11 @@ static void ocfs2_remove_metadata_tree(struct ocfs2_caching_info *ci,
559 ci->ci_num_cached--; 553 ci->ci_num_cached--;
560} 554}
561 555
562static void ocfs2_remove_block_from_cache(struct inode *inode, 556static void ocfs2_remove_block_from_cache(struct ocfs2_caching_info *ci,
563 sector_t block) 557 sector_t block)
564{ 558{
565 int index; 559 int index;
566 struct ocfs2_meta_cache_item *item = NULL; 560 struct ocfs2_meta_cache_item *item = NULL;
567 struct ocfs2_inode_info *oi = OCFS2_I(inode);
568 struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
569 561
570 ocfs2_metadata_cache_lock(ci); 562 ocfs2_metadata_cache_lock(ci);
571 mlog(0, "Owner %llu, remove %llu, items = %u, array = %u\n", 563 mlog(0, "Owner %llu, remove %llu, items = %u, array = %u\n",
@@ -593,23 +585,24 @@ static void ocfs2_remove_block_from_cache(struct inode *inode,
593 * bother reverting things to an inlined array in the case of a remove 585 * bother reverting things to an inlined array in the case of a remove
594 * which moves us back under the limit. 586 * which moves us back under the limit.
595 */ 587 */
596void ocfs2_remove_from_cache(struct inode *inode, 588void ocfs2_remove_from_cache(struct ocfs2_caching_info *ci,
597 struct buffer_head *bh) 589 struct buffer_head *bh)
598{ 590{
599 sector_t block = bh->b_blocknr; 591 sector_t block = bh->b_blocknr;
600 592
601 ocfs2_remove_block_from_cache(inode, block); 593 ocfs2_remove_block_from_cache(ci, block);
602} 594}
603 595
604/* Called when we remove xattr clusters from an inode. */ 596/* Called when we remove xattr clusters from an inode. */
605void ocfs2_remove_xattr_clusters_from_cache(struct inode *inode, 597void ocfs2_remove_xattr_clusters_from_cache(struct ocfs2_caching_info *ci,
606 sector_t block, 598 sector_t block,
607 u32 c_len) 599 u32 c_len)
608{ 600{
609 unsigned int i, b_len = ocfs2_clusters_to_blocks(inode->i_sb, 1) * c_len; 601 struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
602 unsigned int i, b_len = ocfs2_clusters_to_blocks(sb, 1) * c_len;
610 603
611 for (i = 0; i < b_len; i++, block++) 604 for (i = 0; i < b_len; i++, block++)
612 ocfs2_remove_block_from_cache(inode, block); 605 ocfs2_remove_block_from_cache(ci, block);
613} 606}
614 607
615int __init init_ocfs2_uptodate_cache(void) 608int __init init_ocfs2_uptodate_cache(void)