aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorYan <zheng.yan@oracle.com>2008-07-30 16:29:20 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commitbcc63abbf3e9bf948a1b0129b3e6120ec7d7f698 (patch)
tree1c66dc210f948f79c86786368d2c75b57482875d /fs/btrfs/inode.c
parent33958dc6d38fb4ca7e62273855fcb2db7e616263 (diff)
Btrfs: implement memory reclaim for leaf reference cache
The memory reclaiming issue happens when snapshot exists. In that case, some cache entries may not be used during old snapshot dropping, so they will remain in the cache until umount. The patch adds a field to struct btrfs_leaf_ref to record create time. Besides, the patch makes all dead roots of a given snapshot linked together in order of create time. After a old snapshot was completely dropped, we check the dead root list and remove all cache entries created before the oldest dead root in the list. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3aa82cec6bf7..7af8be076ee5 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -835,17 +835,17 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
835 struct btrfs_root *root = BTRFS_I(inode)->root; 835 struct btrfs_root *root = BTRFS_I(inode)->root;
836 int ret = 0; 836 int ret = 0;
837 837
838 spin_lock(&root->orphan_lock); 838 spin_lock(&root->list_lock);
839 839
840 /* already on the orphan list, we're good */ 840 /* already on the orphan list, we're good */
841 if (!list_empty(&BTRFS_I(inode)->i_orphan)) { 841 if (!list_empty(&BTRFS_I(inode)->i_orphan)) {
842 spin_unlock(&root->orphan_lock); 842 spin_unlock(&root->list_lock);
843 return 0; 843 return 0;
844 } 844 }
845 845
846 list_add(&BTRFS_I(inode)->i_orphan, &root->orphan_list); 846 list_add(&BTRFS_I(inode)->i_orphan, &root->orphan_list);
847 847
848 spin_unlock(&root->orphan_lock); 848 spin_unlock(&root->list_lock);
849 849
850 /* 850 /*
851 * insert an orphan item to track this unlinked/truncated file 851 * insert an orphan item to track this unlinked/truncated file
@@ -864,20 +864,20 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode)
864 struct btrfs_root *root = BTRFS_I(inode)->root; 864 struct btrfs_root *root = BTRFS_I(inode)->root;
865 int ret = 0; 865 int ret = 0;
866 866
867 spin_lock(&root->orphan_lock); 867 spin_lock(&root->list_lock);
868 868
869 if (list_empty(&BTRFS_I(inode)->i_orphan)) { 869 if (list_empty(&BTRFS_I(inode)->i_orphan)) {
870 spin_unlock(&root->orphan_lock); 870 spin_unlock(&root->list_lock);
871 return 0; 871 return 0;
872 } 872 }
873 873
874 list_del_init(&BTRFS_I(inode)->i_orphan); 874 list_del_init(&BTRFS_I(inode)->i_orphan);
875 if (!trans) { 875 if (!trans) {
876 spin_unlock(&root->orphan_lock); 876 spin_unlock(&root->list_lock);
877 return 0; 877 return 0;
878 } 878 }
879 879
880 spin_unlock(&root->orphan_lock); 880 spin_unlock(&root->list_lock);
881 881
882 ret = btrfs_del_orphan_item(trans, root, inode->i_ino); 882 ret = btrfs_del_orphan_item(trans, root, inode->i_ino);
883 883
@@ -973,9 +973,9 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
973 * add this inode to the orphan list so btrfs_orphan_del does 973 * add this inode to the orphan list so btrfs_orphan_del does
974 * the proper thing when we hit it 974 * the proper thing when we hit it
975 */ 975 */
976 spin_lock(&root->orphan_lock); 976 spin_lock(&root->list_lock);
977 list_add(&BTRFS_I(inode)->i_orphan, &root->orphan_list); 977 list_add(&BTRFS_I(inode)->i_orphan, &root->orphan_list);
978 spin_unlock(&root->orphan_lock); 978 spin_unlock(&root->list_lock);
979 979
980 /* 980 /*
981 * if this is a bad inode, means we actually succeeded in 981 * if this is a bad inode, means we actually succeeded in
@@ -3269,13 +3269,13 @@ void btrfs_destroy_inode(struct inode *inode)
3269 BTRFS_I(inode)->i_default_acl != BTRFS_ACL_NOT_CACHED) 3269 BTRFS_I(inode)->i_default_acl != BTRFS_ACL_NOT_CACHED)
3270 posix_acl_release(BTRFS_I(inode)->i_default_acl); 3270 posix_acl_release(BTRFS_I(inode)->i_default_acl);
3271 3271
3272 spin_lock(&BTRFS_I(inode)->root->orphan_lock); 3272 spin_lock(&BTRFS_I(inode)->root->list_lock);
3273 if (!list_empty(&BTRFS_I(inode)->i_orphan)) { 3273 if (!list_empty(&BTRFS_I(inode)->i_orphan)) {
3274 printk(KERN_ERR "BTRFS: inode %lu: inode still on the orphan" 3274 printk(KERN_ERR "BTRFS: inode %lu: inode still on the orphan"
3275 " list\n", inode->i_ino); 3275 " list\n", inode->i_ino);
3276 dump_stack(); 3276 dump_stack();
3277 } 3277 }
3278 spin_unlock(&BTRFS_I(inode)->root->orphan_lock); 3278 spin_unlock(&BTRFS_I(inode)->root->list_lock);
3279 3279
3280 while(1) { 3280 while(1) {
3281 ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1); 3281 ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1);