aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2009-08-17 23:43:49 -0400
committerJoel Becker <joel.becker@oracle.com>2009-09-22 23:09:44 -0400
commit8b2c0dba5159570af5721d40490f6c529d721500 (patch)
treefaca76fab3c9a65ba8e7be3aa93d02e4ff53f0cf /fs/ocfs2/xattr.c
parent0129241e2b3b90ff83a8c774353e5612d84bd493 (diff)
ocfs2: Call refcount tree remove process properly.
Now with xattr refcount support, we need to check whether we have xattr refcounted before we remove the refcount tree. Now 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. 2) Check whether we have inline xattr stored outside, if yes, exit. 4) Remove the tree. Signed-off-by: Tao Ma <tao.ma@oracle.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 501539a733f4..6660f1c6149e 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -840,6 +840,23 @@ static int ocfs2_xattr_list_entries(struct inode *inode,
840 return result; 840 return result;
841} 841}
842 842
843int ocfs2_has_inline_xattr_value_outside(struct inode *inode,
844 struct ocfs2_dinode *di)
845{
846 struct ocfs2_xattr_header *xh;
847 int i;
848
849 xh = (struct ocfs2_xattr_header *)
850 ((void *)di + inode->i_sb->s_blocksize -
851 le16_to_cpu(di->i_xattr_inline_size));
852
853 for (i = 0; i < le16_to_cpu(xh->xh_count); i++)
854 if (!ocfs2_xattr_is_local(&xh->xh_entries[i]))
855 return 1;
856
857 return 0;
858}
859
843static int ocfs2_xattr_ibody_list(struct inode *inode, 860static int ocfs2_xattr_ibody_list(struct inode *inode,
844 struct ocfs2_dinode *di, 861 struct ocfs2_dinode *di,
845 char *buffer, 862 char *buffer,
@@ -2898,10 +2915,16 @@ int ocfs2_xattr_set(struct inode *inode,
2898 if (ocfs2_dealloc_has_cluster(&ctxt.dealloc)) 2915 if (ocfs2_dealloc_has_cluster(&ctxt.dealloc))
2899 ocfs2_schedule_truncate_log_flush(osb, 1); 2916 ocfs2_schedule_truncate_log_flush(osb, 1);
2900 ocfs2_run_deallocs(osb, &ctxt.dealloc); 2917 ocfs2_run_deallocs(osb, &ctxt.dealloc);
2918
2901cleanup: 2919cleanup:
2902 if (ref_tree) 2920 if (ref_tree)
2903 ocfs2_unlock_refcount_tree(osb, ref_tree, 1); 2921 ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
2904 up_write(&OCFS2_I(inode)->ip_xattr_sem); 2922 up_write(&OCFS2_I(inode)->ip_xattr_sem);
2923 if (!value && !ret) {
2924 ret = ocfs2_try_remove_refcount_tree(inode, di_bh);
2925 if (ret)
2926 mlog_errno(ret);
2927 }
2905 ocfs2_inode_unlock(inode, 1); 2928 ocfs2_inode_unlock(inode, 1);
2906cleanup_nolock: 2929cleanup_nolock:
2907 brelse(di_bh); 2930 brelse(di_bh);