aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/free-space-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
-rw-r--r--fs/btrfs/free-space-cache.c97
1 files changed, 96 insertions, 1 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index fcbdcef6ca28..7d8b6b643403 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -209,7 +209,8 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
209 return ret; 209 return ret;
210 } 210 }
211 211
212 return btrfs_update_inode(trans, root, inode); 212 ret = btrfs_update_inode(trans, root, inode);
213 return ret;
213} 214}
214 215
215static int readahead_cache(struct inode *inode) 216static int readahead_cache(struct inode *inode)
@@ -525,6 +526,7 @@ out:
525 spin_lock(&block_group->lock); 526 spin_lock(&block_group->lock);
526 block_group->disk_cache_state = BTRFS_DC_CLEAR; 527 block_group->disk_cache_state = BTRFS_DC_CLEAR;
527 spin_unlock(&block_group->lock); 528 spin_unlock(&block_group->lock);
529 ret = 0;
528 530
529 printk(KERN_ERR "btrfs: failed to load free space cache " 531 printk(KERN_ERR "btrfs: failed to load free space cache "
530 "for block group %llu\n", block_group->key.objectid); 532 "for block group %llu\n", block_group->key.objectid);
@@ -893,6 +895,7 @@ int btrfs_write_out_cache(struct btrfs_root *root,
893 spin_lock(&block_group->lock); 895 spin_lock(&block_group->lock);
894 block_group->disk_cache_state = BTRFS_DC_ERROR; 896 block_group->disk_cache_state = BTRFS_DC_ERROR;
895 spin_unlock(&block_group->lock); 897 spin_unlock(&block_group->lock);
898 ret = 0;
896 899
897 printk(KERN_ERR "btrfs: failed to write free space cace " 900 printk(KERN_ERR "btrfs: failed to write free space cace "
898 "for block group %llu\n", block_group->key.objectid); 901 "for block group %llu\n", block_group->key.objectid);
@@ -2458,3 +2461,95 @@ out:
2458 2461
2459 return ino; 2462 return ino;
2460} 2463}
2464
2465struct inode *lookup_free_ino_inode(struct btrfs_root *root,
2466 struct btrfs_path *path)
2467{
2468 struct inode *inode = NULL;
2469
2470 spin_lock(&root->cache_lock);
2471 if (root->cache_inode)
2472 inode = igrab(root->cache_inode);
2473 spin_unlock(&root->cache_lock);
2474 if (inode)
2475 return inode;
2476
2477 inode = __lookup_free_space_inode(root, path, 0);
2478 if (IS_ERR(inode))
2479 return inode;
2480
2481 spin_lock(&root->cache_lock);
2482 if (!root->fs_info->closing)
2483 root->cache_inode = igrab(inode);
2484 spin_unlock(&root->cache_lock);
2485
2486 return inode;
2487}
2488
2489int create_free_ino_inode(struct btrfs_root *root,
2490 struct btrfs_trans_handle *trans,
2491 struct btrfs_path *path)
2492{
2493 return __create_free_space_inode(root, trans, path,
2494 BTRFS_FREE_INO_OBJECTID, 0);
2495}
2496
2497int load_free_ino_cache(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
2498{
2499 struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
2500 struct btrfs_path *path;
2501 struct inode *inode;
2502 int ret = 0;
2503 u64 root_gen = btrfs_root_generation(&root->root_item);
2504
2505 /*
2506 * If we're unmounting then just return, since this does a search on the
2507 * normal root and not the commit root and we could deadlock.
2508 */
2509 smp_mb();
2510 if (fs_info->closing)
2511 return 0;
2512
2513 path = btrfs_alloc_path();
2514 if (!path)
2515 return 0;
2516
2517 inode = lookup_free_ino_inode(root, path);
2518 if (IS_ERR(inode))
2519 goto out;
2520
2521 if (root_gen != BTRFS_I(inode)->generation)
2522 goto out_put;
2523
2524 ret = __load_free_space_cache(root, inode, ctl, path, 0);
2525
2526 if (ret < 0)
2527 printk(KERN_ERR "btrfs: failed to load free ino cache for "
2528 "root %llu\n", root->root_key.objectid);
2529out_put:
2530 iput(inode);
2531out:
2532 btrfs_free_path(path);
2533 return ret;
2534}
2535
2536int btrfs_write_out_ino_cache(struct btrfs_root *root,
2537 struct btrfs_trans_handle *trans,
2538 struct btrfs_path *path)
2539{
2540 struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
2541 struct inode *inode;
2542 int ret;
2543
2544 inode = lookup_free_ino_inode(root, path);
2545 if (IS_ERR(inode))
2546 return 0;
2547
2548 ret = __btrfs_write_out_cache(root, inode, ctl, NULL, trans, path, 0);
2549 if (ret < 0)
2550 printk(KERN_ERR "btrfs: failed to write free ino cache "
2551 "for root %llu\n", root->root_key.objectid);
2552
2553 iput(inode);
2554 return ret;
2555}