diff options
author | Tao Ma <tao.ma@oracle.com> | 2009-08-17 23:43:49 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2009-09-22 23:09:44 -0400 |
commit | 8b2c0dba5159570af5721d40490f6c529d721500 (patch) | |
tree | faca76fab3c9a65ba8e7be3aa93d02e4ff53f0cf /fs/ocfs2/xattr.c | |
parent | 0129241e2b3b90ff83a8c774353e5612d84bd493 (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.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 501539a733f..6660f1c6149 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 | ||
843 | int 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 | |||
843 | static int ocfs2_xattr_ibody_list(struct inode *inode, | 860 | static 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 | |||
2901 | cleanup: | 2919 | cleanup: |
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); |
2906 | cleanup_nolock: | 2929 | cleanup_nolock: |
2907 | brelse(di_bh); | 2930 | brelse(di_bh); |