ocfs2: Call refcount tree remove process properly.
[deliverable/linux.git] / fs / ocfs2 / refcounttree.c
index a85c01c6629d7ceaadad8c3c261cddb644b9e205..5656c68a2cae9e353f712bf75f04b2a0346f7408 100644 (file)
@@ -926,6 +926,42 @@ out:
        *index = i;
 }
 
+/*
+ * Try to remove refcount tree. The mechanism is:
+ * 1) Check whether i_clusters == 0, if no, exit.
+ * 2) check whether we have i_xattr_loc in dinode. if yes, exit.
+ * 3) Check whether we have inline xattr stored outside, if yes, exit.
+ * 4) Remove the tree.
+ */
+int ocfs2_try_remove_refcount_tree(struct inode *inode,
+                                  struct buffer_head *di_bh)
+{
+       int ret;
+       struct ocfs2_inode_info *oi = OCFS2_I(inode);
+       struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+
+       down_write(&oi->ip_xattr_sem);
+       down_write(&oi->ip_alloc_sem);
+
+       if (oi->ip_clusters)
+               goto out;
+
+       if ((oi->ip_dyn_features & OCFS2_HAS_XATTR_FL) && di->i_xattr_loc)
+               goto out;
+
+       if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL &&
+           ocfs2_has_inline_xattr_value_outside(inode, di))
+               goto out;
+
+       ret = ocfs2_remove_refcount_tree(inode, di_bh);
+       if (ret)
+               mlog_errno(ret);
+out:
+       up_write(&oi->ip_alloc_sem);
+       up_write(&oi->ip_xattr_sem);
+       return 0;
+}
+
 /*
  * Given a cpos and len, try to find the refcount record which contains cpos.
  * 1. If cpos can be found in one refcount record, return the record.
This page took 0.027368 seconds and 5 git commands to generate.