aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/xattr.c190
1 files changed, 154 insertions, 36 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 661ed9b85dbf..8d1a0abc105c 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -199,6 +199,11 @@ static int ocfs2_prepare_refcount_xattr(struct inode *inode,
199 struct ocfs2_refcount_tree **ref_tree, 199 struct ocfs2_refcount_tree **ref_tree,
200 int *meta_need, 200 int *meta_need,
201 int *credits); 201 int *credits);
202static int ocfs2_get_xattr_tree_value_root(struct super_block *sb,
203 struct ocfs2_xattr_bucket *bucket,
204 int offset,
205 struct ocfs2_xattr_value_root **xv,
206 struct buffer_head **bh);
202 207
203static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb) 208static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb)
204{ 209{
@@ -1752,51 +1757,112 @@ out:
1752 return ret; 1757 return ret;
1753} 1758}
1754 1759
1760/*
1761 * In xattr remove, if it is stored outside and refcounted, we may have
1762 * the chance to split the refcount tree. So need the allocators.
1763 */
1764static int ocfs2_lock_xattr_remove_allocators(struct inode *inode,
1765 struct ocfs2_xattr_value_root *xv,
1766 struct ocfs2_caching_info *ref_ci,
1767 struct buffer_head *ref_root_bh,
1768 struct ocfs2_alloc_context **meta_ac,
1769 int *ref_credits)
1770{
1771 int ret, meta_add = 0;
1772 u32 p_cluster, num_clusters;
1773 unsigned int ext_flags;
1774
1775 *ref_credits = 0;
1776 ret = ocfs2_xattr_get_clusters(inode, 0, &p_cluster,
1777 &num_clusters,
1778 &xv->xr_list,
1779 &ext_flags);
1780 if (ret) {
1781 mlog_errno(ret);
1782 goto out;
1783 }
1784
1785 if (!(ext_flags & OCFS2_EXT_REFCOUNTED))
1786 goto out;
1787
1788 ret = ocfs2_refcounted_xattr_delete_need(inode, ref_ci,
1789 ref_root_bh, xv,
1790 &meta_add, ref_credits);
1791 if (ret) {
1792 mlog_errno(ret);
1793 goto out;
1794 }
1795
1796 ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(inode->i_sb),
1797 meta_add, meta_ac);
1798 if (ret)
1799 mlog_errno(ret);
1800
1801out:
1802 return ret;
1803}
1804
1755static int ocfs2_remove_value_outside(struct inode*inode, 1805static int ocfs2_remove_value_outside(struct inode*inode,
1756 struct ocfs2_xattr_value_buf *vb, 1806 struct ocfs2_xattr_value_buf *vb,
1757 struct ocfs2_xattr_header *header) 1807 struct ocfs2_xattr_header *header,
1808 struct ocfs2_caching_info *ref_ci,
1809 struct buffer_head *ref_root_bh)
1758{ 1810{
1759 int ret = 0, i; 1811 int ret = 0, i, ref_credits;
1760 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 1812 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1761 struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, }; 1813 struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, };
1814 void *val;
1762 1815
1763 ocfs2_init_dealloc_ctxt(&ctxt.dealloc); 1816 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
1764 1817
1765 ctxt.handle = ocfs2_start_trans(osb,
1766 ocfs2_remove_extent_credits(osb->sb));
1767 if (IS_ERR(ctxt.handle)) {
1768 ret = PTR_ERR(ctxt.handle);
1769 mlog_errno(ret);
1770 goto out;
1771 }
1772
1773 for (i = 0; i < le16_to_cpu(header->xh_count); i++) { 1818 for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
1774 struct ocfs2_xattr_entry *entry = &header->xh_entries[i]; 1819 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
1775 1820
1776 if (!ocfs2_xattr_is_local(entry)) { 1821 if (ocfs2_xattr_is_local(entry))
1777 void *val; 1822 continue;
1778 1823
1779 val = (void *)header + 1824 val = (void *)header +
1780 le16_to_cpu(entry->xe_name_offset); 1825 le16_to_cpu(entry->xe_name_offset);
1781 vb->vb_xv = (struct ocfs2_xattr_value_root *) 1826 vb->vb_xv = (struct ocfs2_xattr_value_root *)
1782 (val + OCFS2_XATTR_SIZE(entry->xe_name_len)); 1827 (val + OCFS2_XATTR_SIZE(entry->xe_name_len));
1783 ret = ocfs2_xattr_value_truncate(inode, vb, 0, &ctxt); 1828
1784 if (ret < 0) { 1829 ret = ocfs2_lock_xattr_remove_allocators(inode, vb->vb_xv,
1785 mlog_errno(ret); 1830 ref_ci, ref_root_bh,
1786 break; 1831 &ctxt.meta_ac,
1787 } 1832 &ref_credits);
1833
1834 ctxt.handle = ocfs2_start_trans(osb, ref_credits +
1835 ocfs2_remove_extent_credits(osb->sb));
1836 if (IS_ERR(ctxt.handle)) {
1837 ret = PTR_ERR(ctxt.handle);
1838 mlog_errno(ret);
1839 break;
1840 }
1841
1842 ret = ocfs2_xattr_value_truncate(inode, vb, 0, &ctxt);
1843 if (ret < 0) {
1844 mlog_errno(ret);
1845 break;
1846 }
1847
1848 ocfs2_commit_trans(osb, ctxt.handle);
1849 if (ctxt.meta_ac) {
1850 ocfs2_free_alloc_context(ctxt.meta_ac);
1851 ctxt.meta_ac = NULL;
1788 } 1852 }
1789 } 1853 }
1790 1854
1791 ocfs2_commit_trans(osb, ctxt.handle); 1855 if (ctxt.meta_ac)
1856 ocfs2_free_alloc_context(ctxt.meta_ac);
1792 ocfs2_schedule_truncate_log_flush(osb, 1); 1857 ocfs2_schedule_truncate_log_flush(osb, 1);
1793 ocfs2_run_deallocs(osb, &ctxt.dealloc); 1858 ocfs2_run_deallocs(osb, &ctxt.dealloc);
1794out:
1795 return ret; 1859 return ret;
1796} 1860}
1797 1861
1798static int ocfs2_xattr_ibody_remove(struct inode *inode, 1862static int ocfs2_xattr_ibody_remove(struct inode *inode,
1799 struct buffer_head *di_bh) 1863 struct buffer_head *di_bh,
1864 struct ocfs2_caching_info *ref_ci,
1865 struct buffer_head *ref_root_bh)
1800{ 1866{
1801 1867
1802 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; 1868 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
@@ -1811,13 +1877,21 @@ static int ocfs2_xattr_ibody_remove(struct inode *inode,
1811 ((void *)di + inode->i_sb->s_blocksize - 1877 ((void *)di + inode->i_sb->s_blocksize -
1812 le16_to_cpu(di->i_xattr_inline_size)); 1878 le16_to_cpu(di->i_xattr_inline_size));
1813 1879
1814 ret = ocfs2_remove_value_outside(inode, &vb, header); 1880 ret = ocfs2_remove_value_outside(inode, &vb, header,
1881 ref_ci, ref_root_bh);
1815 1882
1816 return ret; 1883 return ret;
1817} 1884}
1818 1885
1886struct ocfs2_rm_xattr_bucket_para {
1887 struct ocfs2_caching_info *ref_ci;
1888 struct buffer_head *ref_root_bh;
1889};
1890
1819static int ocfs2_xattr_block_remove(struct inode *inode, 1891static int ocfs2_xattr_block_remove(struct inode *inode,
1820 struct buffer_head *blk_bh) 1892 struct buffer_head *blk_bh,
1893 struct ocfs2_caching_info *ref_ci,
1894 struct buffer_head *ref_root_bh)
1821{ 1895{
1822 struct ocfs2_xattr_block *xb; 1896 struct ocfs2_xattr_block *xb;
1823 int ret = 0; 1897 int ret = 0;
@@ -1825,22 +1899,29 @@ static int ocfs2_xattr_block_remove(struct inode *inode,
1825 .vb_bh = blk_bh, 1899 .vb_bh = blk_bh,
1826 .vb_access = ocfs2_journal_access_xb, 1900 .vb_access = ocfs2_journal_access_xb,
1827 }; 1901 };
1902 struct ocfs2_rm_xattr_bucket_para args = {
1903 .ref_ci = ref_ci,
1904 .ref_root_bh = ref_root_bh,
1905 };
1828 1906
1829 xb = (struct ocfs2_xattr_block *)blk_bh->b_data; 1907 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1830 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) { 1908 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
1831 struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header); 1909 struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header);
1832 ret = ocfs2_remove_value_outside(inode, &vb, header); 1910 ret = ocfs2_remove_value_outside(inode, &vb, header,
1911 ref_ci, ref_root_bh);
1833 } else 1912 } else
1834 ret = ocfs2_iterate_xattr_index_block(inode, 1913 ret = ocfs2_iterate_xattr_index_block(inode,
1835 blk_bh, 1914 blk_bh,
1836 ocfs2_rm_xattr_cluster, 1915 ocfs2_rm_xattr_cluster,
1837 NULL); 1916 &args);
1838 1917
1839 return ret; 1918 return ret;
1840} 1919}
1841 1920
1842static int ocfs2_xattr_free_block(struct inode *inode, 1921static int ocfs2_xattr_free_block(struct inode *inode,
1843 u64 block) 1922 u64 block,
1923 struct ocfs2_caching_info *ref_ci,
1924 struct buffer_head *ref_root_bh)
1844{ 1925{
1845 struct inode *xb_alloc_inode; 1926 struct inode *xb_alloc_inode;
1846 struct buffer_head *xb_alloc_bh = NULL; 1927 struct buffer_head *xb_alloc_bh = NULL;
@@ -1858,7 +1939,7 @@ static int ocfs2_xattr_free_block(struct inode *inode,
1858 goto out; 1939 goto out;
1859 } 1940 }
1860 1941
1861 ret = ocfs2_xattr_block_remove(inode, blk_bh); 1942 ret = ocfs2_xattr_block_remove(inode, blk_bh, ref_ci, ref_root_bh);
1862 if (ret < 0) { 1943 if (ret < 0) {
1863 mlog_errno(ret); 1944 mlog_errno(ret);
1864 goto out; 1945 goto out;
@@ -1918,6 +1999,9 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh)
1918{ 1999{
1919 struct ocfs2_inode_info *oi = OCFS2_I(inode); 2000 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1920 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; 2001 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
2002 struct ocfs2_refcount_tree *ref_tree = NULL;
2003 struct buffer_head *ref_root_bh = NULL;
2004 struct ocfs2_caching_info *ref_ci = NULL;
1921 handle_t *handle; 2005 handle_t *handle;
1922 int ret; 2006 int ret;
1923 2007
@@ -1927,8 +2011,21 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh)
1927 if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) 2011 if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL))
1928 return 0; 2012 return 0;
1929 2013
2014 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL) {
2015 ret = ocfs2_lock_refcount_tree(OCFS2_SB(inode->i_sb),
2016 le64_to_cpu(di->i_refcount_loc),
2017 1, &ref_tree, &ref_root_bh);
2018 if (ret) {
2019 mlog_errno(ret);
2020 goto out;
2021 }
2022 ref_ci = &ref_tree->rf_ci;
2023
2024 }
2025
1930 if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) { 2026 if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) {
1931 ret = ocfs2_xattr_ibody_remove(inode, di_bh); 2027 ret = ocfs2_xattr_ibody_remove(inode, di_bh,
2028 ref_ci, ref_root_bh);
1932 if (ret < 0) { 2029 if (ret < 0) {
1933 mlog_errno(ret); 2030 mlog_errno(ret);
1934 goto out; 2031 goto out;
@@ -1937,7 +2034,8 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh)
1937 2034
1938 if (di->i_xattr_loc) { 2035 if (di->i_xattr_loc) {
1939 ret = ocfs2_xattr_free_block(inode, 2036 ret = ocfs2_xattr_free_block(inode,
1940 le64_to_cpu(di->i_xattr_loc)); 2037 le64_to_cpu(di->i_xattr_loc),
2038 ref_ci, ref_root_bh);
1941 if (ret < 0) { 2039 if (ret < 0) {
1942 mlog_errno(ret); 2040 mlog_errno(ret);
1943 goto out; 2041 goto out;
@@ -1971,6 +2069,9 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh)
1971out_commit: 2069out_commit:
1972 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); 2070 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1973out: 2071out:
2072 if (ref_tree)
2073 ocfs2_unlock_refcount_tree(OCFS2_SB(inode->i_sb), ref_tree, 1);
2074 brelse(ref_root_bh);
1974 return ret; 2075 return ret;
1975} 2076}
1976 2077
@@ -4989,7 +5090,7 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
4989 struct ocfs2_extent_tree et; 5090 struct ocfs2_extent_tree et;
4990 5091
4991 ret = ocfs2_iterate_xattr_buckets(inode, blkno, len, 5092 ret = ocfs2_iterate_xattr_buckets(inode, blkno, len,
4992 ocfs2_delete_xattr_in_bucket, NULL); 5093 ocfs2_delete_xattr_in_bucket, para);
4993 if (ret) { 5094 if (ret) {
4994 mlog_errno(ret); 5095 mlog_errno(ret);
4995 return ret; 5096 return ret;
@@ -5378,7 +5479,7 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
5378 struct ocfs2_xattr_bucket *bucket, 5479 struct ocfs2_xattr_bucket *bucket,
5379 void *para) 5480 void *para)
5380{ 5481{
5381 int ret = 0; 5482 int ret = 0, ref_credits;
5382 struct ocfs2_xattr_header *xh = bucket_xh(bucket); 5483 struct ocfs2_xattr_header *xh = bucket_xh(bucket);
5383 u16 i; 5484 u16 i;
5384 struct ocfs2_xattr_entry *xe; 5485 struct ocfs2_xattr_entry *xe;
@@ -5386,7 +5487,9 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
5386 struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,}; 5487 struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,};
5387 int credits = ocfs2_remove_extent_credits(osb->sb) + 5488 int credits = ocfs2_remove_extent_credits(osb->sb) +
5388 ocfs2_blocks_per_xattr_bucket(inode->i_sb); 5489 ocfs2_blocks_per_xattr_bucket(inode->i_sb);
5389 5490 struct ocfs2_xattr_value_root *xv;
5491 struct ocfs2_rm_xattr_bucket_para *args =
5492 (struct ocfs2_rm_xattr_bucket_para *)para;
5390 5493
5391 ocfs2_init_dealloc_ctxt(&ctxt.dealloc); 5494 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
5392 5495
@@ -5395,7 +5498,16 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
5395 if (ocfs2_xattr_is_local(xe)) 5498 if (ocfs2_xattr_is_local(xe))
5396 continue; 5499 continue;
5397 5500
5398 ctxt.handle = ocfs2_start_trans(osb, credits); 5501 ret = ocfs2_get_xattr_tree_value_root(inode->i_sb, bucket,
5502 i, &xv, NULL);
5503
5504 ret = ocfs2_lock_xattr_remove_allocators(inode, xv,
5505 args->ref_ci,
5506 args->ref_root_bh,
5507 &ctxt.meta_ac,
5508 &ref_credits);
5509
5510 ctxt.handle = ocfs2_start_trans(osb, credits + ref_credits);
5399 if (IS_ERR(ctxt.handle)) { 5511 if (IS_ERR(ctxt.handle)) {
5400 ret = PTR_ERR(ctxt.handle); 5512 ret = PTR_ERR(ctxt.handle);
5401 mlog_errno(ret); 5513 mlog_errno(ret);
@@ -5406,12 +5518,18 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
5406 i, 0, &ctxt); 5518 i, 0, &ctxt);
5407 5519
5408 ocfs2_commit_trans(osb, ctxt.handle); 5520 ocfs2_commit_trans(osb, ctxt.handle);
5521 if (ctxt.meta_ac) {
5522 ocfs2_free_alloc_context(ctxt.meta_ac);
5523 ctxt.meta_ac = NULL;
5524 }
5409 if (ret) { 5525 if (ret) {
5410 mlog_errno(ret); 5526 mlog_errno(ret);
5411 break; 5527 break;
5412 } 5528 }
5413 } 5529 }
5414 5530
5531 if (ctxt.meta_ac)
5532 ocfs2_free_alloc_context(ctxt.meta_ac);
5415 ocfs2_schedule_truncate_log_flush(osb, 1); 5533 ocfs2_schedule_truncate_log_flush(osb, 1);
5416 ocfs2_run_deallocs(osb, &ctxt.dealloc); 5534 ocfs2_run_deallocs(osb, &ctxt.dealloc);
5417 return ret; 5535 return ret;