diff options
Diffstat (limited to 'fs/ocfs2/refcounttree.c')
-rw-r--r-- | fs/ocfs2/refcounttree.c | 36 |
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 | */ | ||
936 | int 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); | ||
959 | out: | ||
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 |