aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/refcounttree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/refcounttree.c')
-rw-r--r--fs/ocfs2/refcounttree.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index a85c01c6629d..5656c68a2cae 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -927,6 +927,42 @@ out:
927} 927}
928 928
929/* 929/*
930 * Try to remove refcount tree. The mechanism is:
931 * 1) Check whether i_clusters == 0, if no, exit.
932 * 2) check whether we have i_xattr_loc in dinode. if yes, exit.
933 * 3) Check whether we have inline xattr stored outside, if yes, exit.
934 * 4) Remove the tree.
935 */
936int ocfs2_try_remove_refcount_tree(struct inode *inode,
937 struct buffer_head *di_bh)
938{
939 int ret;
940 struct ocfs2_inode_info *oi = OCFS2_I(inode);
941 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
942
943 down_write(&oi->ip_xattr_sem);
944 down_write(&oi->ip_alloc_sem);
945
946 if (oi->ip_clusters)
947 goto out;
948
949 if ((oi->ip_dyn_features & OCFS2_HAS_XATTR_FL) && di->i_xattr_loc)
950 goto out;
951
952 if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL &&
953 ocfs2_has_inline_xattr_value_outside(inode, di))
954 goto out;
955
956 ret = ocfs2_remove_refcount_tree(inode, di_bh);
957 if (ret)
958 mlog_errno(ret);
959out:
960 up_write(&oi->ip_alloc_sem);
961 up_write(&oi->ip_xattr_sem);
962 return 0;
963}
964
965/*
930 * Given a cpos and len, try to find the refcount record which contains cpos. 966 * Given a cpos and len, try to find the refcount record which contains cpos.
931 * 1. If cpos can be found in one refcount record, return the record. 967 * 1. If cpos can be found in one refcount record, return the record.
932 * 2. If cpos can't be found, return a fake record which start from cpos 968 * 2. If cpos can't be found, return a fake record which start from cpos