aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2009-08-18 16:52:38 -0400
committerJoel Becker <joel.becker@oracle.com>2010-02-26 18:41:11 -0500
commitcf2bc809403ae48a4a2bb5cc551d2ec35f2e4a47 (patch)
tree3e1a0e3b8be59354325b68a169c5e8e4b8f1bf18 /fs/ocfs2/xattr.c
parent3fc12afa0cea5dc8845487b685165c89934ca1eb (diff)
ocfs2: Teach ocfs2_xa_loc how to do its own journal work
We're going to want to make sure our buffers get accessed and dirtied correctly. So have the xa_loc do the work. This includes storing the inode on ocfs2_xa_loc. Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c115
1 files changed, 86 insertions, 29 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index e0d0fa23a19b..fbec11610223 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -142,6 +142,13 @@ struct ocfs2_xattr_search {
142struct ocfs2_xa_loc; 142struct ocfs2_xa_loc;
143struct ocfs2_xa_loc_operations { 143struct ocfs2_xa_loc_operations {
144 /* 144 /*
145 * Journal functions
146 */
147 int (*xlo_journal_access)(handle_t *handle, struct ocfs2_xa_loc *loc,
148 int type);
149 void (*xlo_journal_dirty)(handle_t *handle, struct ocfs2_xa_loc *loc);
150
151 /*
145 * Return a pointer to the appropriate buffer in loc->xl_storage 152 * Return a pointer to the appropriate buffer in loc->xl_storage
146 * at the given offset from loc->xl_header. 153 * at the given offset from loc->xl_header.
147 */ 154 */
@@ -186,6 +193,9 @@ struct ocfs2_xa_loc_operations {
186 * tracking the on-disk structure. 193 * tracking the on-disk structure.
187 */ 194 */
188struct ocfs2_xa_loc { 195struct ocfs2_xa_loc {
196 /* This xattr belongs to this inode */
197 struct inode *xl_inode;
198
189 /* The ocfs2_xattr_header inside the on-disk storage. Not NULL. */ 199 /* The ocfs2_xattr_header inside the on-disk storage. Not NULL. */
190 struct ocfs2_xattr_header *xl_header; 200 struct ocfs2_xattr_header *xl_header;
191 201
@@ -1540,6 +1550,17 @@ static int ocfs2_xa_check_space_helper(int needed_space, int free_start,
1540 return 0; 1550 return 0;
1541} 1551}
1542 1552
1553static int ocfs2_xa_journal_access(handle_t *handle, struct ocfs2_xa_loc *loc,
1554 int type)
1555{
1556 return loc->xl_ops->xlo_journal_access(handle, loc, type);
1557}
1558
1559static void ocfs2_xa_journal_dirty(handle_t *handle, struct ocfs2_xa_loc *loc)
1560{
1561 loc->xl_ops->xlo_journal_dirty(handle, loc);
1562}
1563
1543/* Give a pointer into the storage for the given offset */ 1564/* Give a pointer into the storage for the given offset */
1544static void *ocfs2_xa_offset_pointer(struct ocfs2_xa_loc *loc, int offset) 1565static void *ocfs2_xa_offset_pointer(struct ocfs2_xa_loc *loc, int offset)
1545{ 1566{
@@ -1629,6 +1650,29 @@ static void ocfs2_xa_fill_value_buf(struct ocfs2_xa_loc *loc,
1629 name_size); 1650 name_size);
1630} 1651}
1631 1652
1653static int ocfs2_xa_block_journal_access(handle_t *handle,
1654 struct ocfs2_xa_loc *loc, int type)
1655{
1656 struct buffer_head *bh = loc->xl_storage;
1657 ocfs2_journal_access_func access;
1658
1659 if (loc->xl_size == (bh->b_size -
1660 offsetof(struct ocfs2_xattr_block,
1661 xb_attrs.xb_header)))
1662 access = ocfs2_journal_access_xb;
1663 else
1664 access = ocfs2_journal_access_di;
1665 return access(handle, INODE_CACHE(loc->xl_inode), bh, type);
1666}
1667
1668static void ocfs2_xa_block_journal_dirty(handle_t *handle,
1669 struct ocfs2_xa_loc *loc)
1670{
1671 struct buffer_head *bh = loc->xl_storage;
1672
1673 ocfs2_journal_dirty(handle, bh);
1674}
1675
1632static void *ocfs2_xa_block_offset_pointer(struct ocfs2_xa_loc *loc, 1676static void *ocfs2_xa_block_offset_pointer(struct ocfs2_xa_loc *loc,
1633 int offset) 1677 int offset)
1634{ 1678{
@@ -1755,6 +1799,8 @@ static void ocfs2_xa_block_fill_value_buf(struct ocfs2_xa_loc *loc,
1755 * storage and unindexed ocfs2_xattr_blocks. 1799 * storage and unindexed ocfs2_xattr_blocks.
1756 */ 1800 */
1757static const struct ocfs2_xa_loc_operations ocfs2_xa_block_loc_ops = { 1801static const struct ocfs2_xa_loc_operations ocfs2_xa_block_loc_ops = {
1802 .xlo_journal_access = ocfs2_xa_block_journal_access,
1803 .xlo_journal_dirty = ocfs2_xa_block_journal_dirty,
1758 .xlo_offset_pointer = ocfs2_xa_block_offset_pointer, 1804 .xlo_offset_pointer = ocfs2_xa_block_offset_pointer,
1759 .xlo_check_space = ocfs2_xa_block_check_space, 1805 .xlo_check_space = ocfs2_xa_block_check_space,
1760 .xlo_can_reuse = ocfs2_xa_block_can_reuse, 1806 .xlo_can_reuse = ocfs2_xa_block_can_reuse,
@@ -1765,6 +1811,22 @@ static const struct ocfs2_xa_loc_operations ocfs2_xa_block_loc_ops = {
1765 .xlo_fill_value_buf = ocfs2_xa_block_fill_value_buf, 1811 .xlo_fill_value_buf = ocfs2_xa_block_fill_value_buf,
1766}; 1812};
1767 1813
1814static int ocfs2_xa_bucket_journal_access(handle_t *handle,
1815 struct ocfs2_xa_loc *loc, int type)
1816{
1817 struct ocfs2_xattr_bucket *bucket = loc->xl_storage;
1818
1819 return ocfs2_xattr_bucket_journal_access(handle, bucket, type);
1820}
1821
1822static void ocfs2_xa_bucket_journal_dirty(handle_t *handle,
1823 struct ocfs2_xa_loc *loc)
1824{
1825 struct ocfs2_xattr_bucket *bucket = loc->xl_storage;
1826
1827 ocfs2_xattr_bucket_journal_dirty(handle, bucket);
1828}
1829
1768static void *ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc *loc, 1830static void *ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc *loc,
1769 int offset) 1831 int offset)
1770{ 1832{
@@ -1772,8 +1834,8 @@ static void *ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc *loc,
1772 int block, block_offset; 1834 int block, block_offset;
1773 1835
1774 /* The header is at the front of the bucket */ 1836 /* The header is at the front of the bucket */
1775 block = offset >> bucket->bu_inode->i_sb->s_blocksize_bits; 1837 block = offset >> loc->xl_inode->i_sb->s_blocksize_bits;
1776 block_offset = offset % bucket->bu_inode->i_sb->s_blocksize; 1838 block_offset = offset % loc->xl_inode->i_sb->s_blocksize;
1777 1839
1778 return bucket_block(bucket, block) + block_offset; 1840 return bucket_block(bucket, block) + block_offset;
1779} 1841}
@@ -1813,8 +1875,7 @@ static int ocfs2_xa_bucket_check_space(struct ocfs2_xa_loc *loc,
1813 int free_start = ocfs2_xa_get_free_start(loc); 1875 int free_start = ocfs2_xa_get_free_start(loc);
1814 int needed_space = ocfs2_xi_entry_usage(xi); 1876 int needed_space = ocfs2_xi_entry_usage(xi);
1815 int size = namevalue_size_xi(xi); 1877 int size = namevalue_size_xi(xi);
1816 struct ocfs2_xattr_bucket *bucket = loc->xl_storage; 1878 struct super_block *sb = loc->xl_inode->i_sb;
1817 struct super_block *sb = bucket->bu_inode->i_sb;
1818 1879
1819 /* 1880 /*
1820 * Bucket storage does not reclaim name+value pairs it cannot 1881 * Bucket storage does not reclaim name+value pairs it cannot
@@ -1896,8 +1957,7 @@ static void ocfs2_xa_bucket_add_namevalue(struct ocfs2_xa_loc *loc, int size)
1896{ 1957{
1897 int free_start = ocfs2_xa_get_free_start(loc); 1958 int free_start = ocfs2_xa_get_free_start(loc);
1898 struct ocfs2_xattr_header *xh = loc->xl_header; 1959 struct ocfs2_xattr_header *xh = loc->xl_header;
1899 struct ocfs2_xattr_bucket *bucket = loc->xl_storage; 1960 struct super_block *sb = loc->xl_inode->i_sb;
1900 struct super_block *sb = bucket->bu_inode->i_sb;
1901 int nameval_offset; 1961 int nameval_offset;
1902 1962
1903 free_start = ocfs2_bucket_align_free_start(sb, free_start, size); 1963 free_start = ocfs2_bucket_align_free_start(sb, free_start, size);
@@ -1912,7 +1972,7 @@ static void ocfs2_xa_bucket_fill_value_buf(struct ocfs2_xa_loc *loc,
1912 struct ocfs2_xattr_value_buf *vb) 1972 struct ocfs2_xattr_value_buf *vb)
1913{ 1973{
1914 struct ocfs2_xattr_bucket *bucket = loc->xl_storage; 1974 struct ocfs2_xattr_bucket *bucket = loc->xl_storage;
1915 struct super_block *sb = bucket->bu_inode->i_sb; 1975 struct super_block *sb = loc->xl_inode->i_sb;
1916 int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset); 1976 int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset);
1917 int size = namevalue_size_xe(loc->xl_entry); 1977 int size = namevalue_size_xe(loc->xl_entry);
1918 int block_offset = nameval_offset >> sb->s_blocksize_bits; 1978 int block_offset = nameval_offset >> sb->s_blocksize_bits;
@@ -1929,6 +1989,8 @@ static void ocfs2_xa_bucket_fill_value_buf(struct ocfs2_xa_loc *loc,
1929 1989
1930/* Operations for xattrs stored in buckets. */ 1990/* Operations for xattrs stored in buckets. */
1931static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = { 1991static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = {
1992 .xlo_journal_access = ocfs2_xa_bucket_journal_access,
1993 .xlo_journal_dirty = ocfs2_xa_bucket_journal_dirty,
1932 .xlo_offset_pointer = ocfs2_xa_bucket_offset_pointer, 1994 .xlo_offset_pointer = ocfs2_xa_bucket_offset_pointer,
1933 .xlo_check_space = ocfs2_xa_bucket_check_space, 1995 .xlo_check_space = ocfs2_xa_bucket_check_space,
1934 .xlo_can_reuse = ocfs2_xa_bucket_can_reuse, 1996 .xlo_can_reuse = ocfs2_xa_bucket_can_reuse,
@@ -2049,6 +2111,7 @@ static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc,
2049{ 2111{
2050 struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; 2112 struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
2051 2113
2114 loc->xl_inode = inode;
2052 loc->xl_ops = &ocfs2_xa_block_loc_ops; 2115 loc->xl_ops = &ocfs2_xa_block_loc_ops;
2053 loc->xl_storage = bh; 2116 loc->xl_storage = bh;
2054 loc->xl_entry = entry; 2117 loc->xl_entry = entry;
@@ -2065,6 +2128,7 @@ static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc,
2065} 2128}
2066 2129
2067static void ocfs2_init_xattr_block_xa_loc(struct ocfs2_xa_loc *loc, 2130static void ocfs2_init_xattr_block_xa_loc(struct ocfs2_xa_loc *loc,
2131 struct inode *inode,
2068 struct buffer_head *bh, 2132 struct buffer_head *bh,
2069 struct ocfs2_xattr_entry *entry) 2133 struct ocfs2_xattr_entry *entry)
2070{ 2134{
@@ -2073,6 +2137,7 @@ static void ocfs2_init_xattr_block_xa_loc(struct ocfs2_xa_loc *loc,
2073 2137
2074 BUG_ON(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED); 2138 BUG_ON(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED);
2075 2139
2140 loc->xl_inode = inode;
2076 loc->xl_ops = &ocfs2_xa_block_loc_ops; 2141 loc->xl_ops = &ocfs2_xa_block_loc_ops;
2077 loc->xl_storage = bh; 2142 loc->xl_storage = bh;
2078 loc->xl_header = &(xb->xb_attrs.xb_header); 2143 loc->xl_header = &(xb->xb_attrs.xb_header);
@@ -2085,6 +2150,7 @@ static void ocfs2_init_xattr_bucket_xa_loc(struct ocfs2_xa_loc *loc,
2085 struct ocfs2_xattr_bucket *bucket, 2150 struct ocfs2_xattr_bucket *bucket,
2086 struct ocfs2_xattr_entry *entry) 2151 struct ocfs2_xattr_entry *entry)
2087{ 2152{
2153 loc->xl_inode = bucket->bu_inode;
2088 loc->xl_ops = &ocfs2_xa_bucket_loc_ops; 2154 loc->xl_ops = &ocfs2_xa_bucket_loc_ops;
2089 loc->xl_storage = bucket; 2155 loc->xl_storage = bucket;
2090 loc->xl_header = bucket_xh(bucket); 2156 loc->xl_header = bucket_xh(bucket);
@@ -2226,21 +2292,18 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2226 goto out; 2292 goto out;
2227 } 2293 }
2228 2294
2229 if (!(flag & OCFS2_INLINE_XATTR_FL)) {
2230 ret = vb.vb_access(handle, INODE_CACHE(inode), vb.vb_bh,
2231 OCFS2_JOURNAL_ACCESS_WRITE);
2232 if (ret) {
2233 mlog_errno(ret);
2234 goto out;
2235 }
2236 }
2237
2238 if (xs->xattr_bh == xs->inode_bh) 2295 if (xs->xattr_bh == xs->inode_bh)
2239 ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh, 2296 ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh,
2240 xs->not_found ? NULL : xs->here); 2297 xs->not_found ? NULL : xs->here);
2241 else 2298 else
2242 ocfs2_init_xattr_block_xa_loc(&loc, xs->xattr_bh, 2299 ocfs2_init_xattr_block_xa_loc(&loc, inode, xs->xattr_bh,
2243 xs->not_found ? NULL : xs->here); 2300 xs->not_found ? NULL : xs->here);
2301 ret = ocfs2_xa_journal_access(handle, &loc,
2302 OCFS2_JOURNAL_ACCESS_WRITE);
2303 if (ret) {
2304 mlog_errno(ret);
2305 goto out;
2306 }
2244 2307
2245 /* 2308 /*
2246 * Prepare our entry and insert the inline value. This will 2309 * Prepare our entry and insert the inline value. This will
@@ -2258,13 +2321,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
2258 ocfs2_xa_store_inline_value(&loc, xi); 2321 ocfs2_xa_store_inline_value(&loc, xi);
2259 xs->here = loc.xl_entry; 2322 xs->here = loc.xl_entry;
2260 2323
2261 if (!(flag & OCFS2_INLINE_XATTR_FL)) { 2324 ocfs2_xa_journal_dirty(handle, &loc);
2262 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
2263 if (ret < 0) {
2264 mlog_errno(ret);
2265 goto out;
2266 }
2267 }
2268 2325
2269 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) && 2326 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) &&
2270 (flag & OCFS2_INLINE_XATTR_FL)) { 2327 (flag & OCFS2_INLINE_XATTR_FL)) {
@@ -5325,15 +5382,15 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
5325 } 5382 }
5326 } 5383 }
5327 5384
5328 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket, 5385 ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket,
5329 OCFS2_JOURNAL_ACCESS_WRITE); 5386 xs->not_found ? NULL : xs->here);
5387 ret = ocfs2_xa_journal_access(handle, &loc,
5388 OCFS2_JOURNAL_ACCESS_WRITE);
5330 if (ret < 0) { 5389 if (ret < 0) {
5331 mlog_errno(ret); 5390 mlog_errno(ret);
5332 goto out; 5391 goto out;
5333 } 5392 }
5334 5393
5335 ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket,
5336 xs->not_found ? NULL : xs->here);
5337 ret = ocfs2_xa_prepare_entry(&loc, xi, name_hash); 5394 ret = ocfs2_xa_prepare_entry(&loc, xi, name_hash);
5338 if (ret) { 5395 if (ret) {
5339 if (ret != -ENOSPC) 5396 if (ret != -ENOSPC)
@@ -5345,7 +5402,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
5345 ocfs2_xa_store_inline_value(&loc, xi); 5402 ocfs2_xa_store_inline_value(&loc, xi);
5346 xs->here = loc.xl_entry; 5403 xs->here = loc.xl_entry;
5347 5404
5348 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket); 5405 ocfs2_xa_journal_dirty(handle, &loc);
5349 5406
5350out: 5407out:
5351 return ret; 5408 return ret;