diff options
| author | Joel Becker <joel.becker@oracle.com> | 2009-08-18 16:52:38 -0400 |
|---|---|---|
| committer | Joel Becker <joel.becker@oracle.com> | 2010-02-26 18:41:11 -0500 |
| commit | cf2bc809403ae48a4a2bb5cc551d2ec35f2e4a47 (patch) | |
| tree | 3e1a0e3b8be59354325b68a169c5e8e4b8f1bf18 | |
| parent | 3fc12afa0cea5dc8845487b685165c89934ca1eb (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>
| -rw-r--r-- | fs/ocfs2/xattr.c | 115 |
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 { | |||
| 142 | struct ocfs2_xa_loc; | 142 | struct ocfs2_xa_loc; |
| 143 | struct ocfs2_xa_loc_operations { | 143 | struct 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 | */ |
| 188 | struct ocfs2_xa_loc { | 195 | struct 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 | ||
| 1553 | static 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 | |||
| 1559 | static 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 */ |
| 1544 | static void *ocfs2_xa_offset_pointer(struct ocfs2_xa_loc *loc, int offset) | 1565 | static 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 | ||
| 1653 | static 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 | |||
| 1668 | static 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 | |||
| 1632 | static void *ocfs2_xa_block_offset_pointer(struct ocfs2_xa_loc *loc, | 1676 | static 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 | */ |
| 1757 | static const struct ocfs2_xa_loc_operations ocfs2_xa_block_loc_ops = { | 1801 | static 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 | ||
| 1814 | static 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 | |||
| 1822 | static 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 | |||
| 1768 | static void *ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc *loc, | 1830 | static 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. */ |
| 1931 | static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = { | 1991 | static 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 | ||
| 2067 | static void ocfs2_init_xattr_block_xa_loc(struct ocfs2_xa_loc *loc, | 2130 | static 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 | ||
| 5350 | out: | 5407 | out: |
| 5351 | return ret; | 5408 | return ret; |
