diff options
author | T Makphaibulchoke <tmac@hp.com> | 2014-03-18 19:24:49 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-03-18 19:24:49 -0400 |
commit | 9c191f701ce9f9bc604e88a5dc69cd943daa5d3b (patch) | |
tree | 2e7a0ffa25f89e6dab1719deeb6a710405517afc /fs/ext4/xattr.c | |
parent | 1f3e55fe02d12213f87869768aa2b0bad3ba9a7d (diff) |
ext4: each filesystem creates and uses its own mb_cache
This patch adds new interfaces to create and destory cache,
ext4_xattr_create_cache() and ext4_xattr_destroy_cache(), and remove
the cache creation and destory calls from ex4_init_xattr() and
ext4_exitxattr() in fs/ext4/xattr.c.
fs/ext4/super.c has been changed so that when a filesystem is mounted
a cache is allocated and attched to its ext4_sb_info structure.
fs/mbcache.c has been changed so that only one slab allocator is
allocated and used by all mbcache structures.
Signed-off-by: T. Makphaibulchoke <tmac@hp.com>
Diffstat (limited to 'fs/ext4/xattr.c')
-rw-r--r-- | fs/ext4/xattr.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 185066f475f1..1f5cf5880718 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -81,7 +81,7 @@ | |||
81 | # define ea_bdebug(bh, fmt, ...) no_printk(fmt, ##__VA_ARGS__) | 81 | # define ea_bdebug(bh, fmt, ...) no_printk(fmt, ##__VA_ARGS__) |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | static void ext4_xattr_cache_insert(struct buffer_head *); | 84 | static void ext4_xattr_cache_insert(struct mb_cache *, struct buffer_head *); |
85 | static struct buffer_head *ext4_xattr_cache_find(struct inode *, | 85 | static struct buffer_head *ext4_xattr_cache_find(struct inode *, |
86 | struct ext4_xattr_header *, | 86 | struct ext4_xattr_header *, |
87 | struct mb_cache_entry **); | 87 | struct mb_cache_entry **); |
@@ -90,8 +90,6 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *, | |||
90 | static int ext4_xattr_list(struct dentry *dentry, char *buffer, | 90 | static int ext4_xattr_list(struct dentry *dentry, char *buffer, |
91 | size_t buffer_size); | 91 | size_t buffer_size); |
92 | 92 | ||
93 | static struct mb_cache *ext4_xattr_cache; | ||
94 | |||
95 | static const struct xattr_handler *ext4_xattr_handler_map[] = { | 93 | static const struct xattr_handler *ext4_xattr_handler_map[] = { |
96 | [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, | 94 | [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, |
97 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 95 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
@@ -117,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = { | |||
117 | NULL | 115 | NULL |
118 | }; | 116 | }; |
119 | 117 | ||
118 | #define EXT4_GET_MB_CACHE(inode) (((struct ext4_sb_info *) \ | ||
119 | inode->i_sb->s_fs_info)->s_mb_cache) | ||
120 | |||
120 | static __le32 ext4_xattr_block_csum(struct inode *inode, | 121 | static __le32 ext4_xattr_block_csum(struct inode *inode, |
121 | sector_t block_nr, | 122 | sector_t block_nr, |
122 | struct ext4_xattr_header *hdr) | 123 | struct ext4_xattr_header *hdr) |
@@ -265,6 +266,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name, | |||
265 | struct ext4_xattr_entry *entry; | 266 | struct ext4_xattr_entry *entry; |
266 | size_t size; | 267 | size_t size; |
267 | int error; | 268 | int error; |
269 | struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode); | ||
268 | 270 | ||
269 | ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", | 271 | ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", |
270 | name_index, name, buffer, (long)buffer_size); | 272 | name_index, name, buffer, (long)buffer_size); |
@@ -286,7 +288,7 @@ bad_block: | |||
286 | error = -EIO; | 288 | error = -EIO; |
287 | goto cleanup; | 289 | goto cleanup; |
288 | } | 290 | } |
289 | ext4_xattr_cache_insert(bh); | 291 | ext4_xattr_cache_insert(ext4_mb_cache, bh); |
290 | entry = BFIRST(bh); | 292 | entry = BFIRST(bh); |
291 | error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1); | 293 | error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1); |
292 | if (error == -EIO) | 294 | if (error == -EIO) |
@@ -409,6 +411,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
409 | struct inode *inode = dentry->d_inode; | 411 | struct inode *inode = dentry->d_inode; |
410 | struct buffer_head *bh = NULL; | 412 | struct buffer_head *bh = NULL; |
411 | int error; | 413 | int error; |
414 | struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode); | ||
412 | 415 | ||
413 | ea_idebug(inode, "buffer=%p, buffer_size=%ld", | 416 | ea_idebug(inode, "buffer=%p, buffer_size=%ld", |
414 | buffer, (long)buffer_size); | 417 | buffer, (long)buffer_size); |
@@ -430,7 +433,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
430 | error = -EIO; | 433 | error = -EIO; |
431 | goto cleanup; | 434 | goto cleanup; |
432 | } | 435 | } |
433 | ext4_xattr_cache_insert(bh); | 436 | ext4_xattr_cache_insert(ext4_mb_cache, bh); |
434 | error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); | 437 | error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); |
435 | 438 | ||
436 | cleanup: | 439 | cleanup: |
@@ -526,8 +529,9 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode, | |||
526 | { | 529 | { |
527 | struct mb_cache_entry *ce = NULL; | 530 | struct mb_cache_entry *ce = NULL; |
528 | int error = 0; | 531 | int error = 0; |
532 | struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode); | ||
529 | 533 | ||
530 | ce = mb_cache_entry_get(ext4_xattr_cache, bh->b_bdev, bh->b_blocknr); | 534 | ce = mb_cache_entry_get(ext4_mb_cache, bh->b_bdev, bh->b_blocknr); |
531 | error = ext4_journal_get_write_access(handle, bh); | 535 | error = ext4_journal_get_write_access(handle, bh); |
532 | if (error) | 536 | if (error) |
533 | goto out; | 537 | goto out; |
@@ -746,13 +750,14 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, | |||
746 | struct ext4_xattr_search *s = &bs->s; | 750 | struct ext4_xattr_search *s = &bs->s; |
747 | struct mb_cache_entry *ce = NULL; | 751 | struct mb_cache_entry *ce = NULL; |
748 | int error = 0; | 752 | int error = 0; |
753 | struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode); | ||
749 | 754 | ||
750 | #define header(x) ((struct ext4_xattr_header *)(x)) | 755 | #define header(x) ((struct ext4_xattr_header *)(x)) |
751 | 756 | ||
752 | if (i->value && i->value_len > sb->s_blocksize) | 757 | if (i->value && i->value_len > sb->s_blocksize) |
753 | return -ENOSPC; | 758 | return -ENOSPC; |
754 | if (s->base) { | 759 | if (s->base) { |
755 | ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, | 760 | ce = mb_cache_entry_get(ext4_mb_cache, bs->bh->b_bdev, |
756 | bs->bh->b_blocknr); | 761 | bs->bh->b_blocknr); |
757 | error = ext4_journal_get_write_access(handle, bs->bh); | 762 | error = ext4_journal_get_write_access(handle, bs->bh); |
758 | if (error) | 763 | if (error) |
@@ -770,7 +775,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, | |||
770 | if (!IS_LAST_ENTRY(s->first)) | 775 | if (!IS_LAST_ENTRY(s->first)) |
771 | ext4_xattr_rehash(header(s->base), | 776 | ext4_xattr_rehash(header(s->base), |
772 | s->here); | 777 | s->here); |
773 | ext4_xattr_cache_insert(bs->bh); | 778 | ext4_xattr_cache_insert(ext4_mb_cache, |
779 | bs->bh); | ||
774 | } | 780 | } |
775 | unlock_buffer(bs->bh); | 781 | unlock_buffer(bs->bh); |
776 | if (error == -EIO) | 782 | if (error == -EIO) |
@@ -906,7 +912,7 @@ getblk_failed: | |||
906 | memcpy(new_bh->b_data, s->base, new_bh->b_size); | 912 | memcpy(new_bh->b_data, s->base, new_bh->b_size); |
907 | set_buffer_uptodate(new_bh); | 913 | set_buffer_uptodate(new_bh); |
908 | unlock_buffer(new_bh); | 914 | unlock_buffer(new_bh); |
909 | ext4_xattr_cache_insert(new_bh); | 915 | ext4_xattr_cache_insert(ext4_mb_cache, new_bh); |
910 | error = ext4_handle_dirty_xattr_block(handle, | 916 | error = ext4_handle_dirty_xattr_block(handle, |
911 | inode, new_bh); | 917 | inode, new_bh); |
912 | if (error) | 918 | if (error) |
@@ -1495,13 +1501,13 @@ ext4_xattr_put_super(struct super_block *sb) | |||
1495 | * Returns 0, or a negative error number on failure. | 1501 | * Returns 0, or a negative error number on failure. |
1496 | */ | 1502 | */ |
1497 | static void | 1503 | static void |
1498 | ext4_xattr_cache_insert(struct buffer_head *bh) | 1504 | ext4_xattr_cache_insert(struct mb_cache *ext4_mb_cache, struct buffer_head *bh) |
1499 | { | 1505 | { |
1500 | __u32 hash = le32_to_cpu(BHDR(bh)->h_hash); | 1506 | __u32 hash = le32_to_cpu(BHDR(bh)->h_hash); |
1501 | struct mb_cache_entry *ce; | 1507 | struct mb_cache_entry *ce; |
1502 | int error; | 1508 | int error; |
1503 | 1509 | ||
1504 | ce = mb_cache_entry_alloc(ext4_xattr_cache, GFP_NOFS); | 1510 | ce = mb_cache_entry_alloc(ext4_mb_cache, GFP_NOFS); |
1505 | if (!ce) { | 1511 | if (!ce) { |
1506 | ea_bdebug(bh, "out of memory"); | 1512 | ea_bdebug(bh, "out of memory"); |
1507 | return; | 1513 | return; |
@@ -1573,12 +1579,13 @@ ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header, | |||
1573 | { | 1579 | { |
1574 | __u32 hash = le32_to_cpu(header->h_hash); | 1580 | __u32 hash = le32_to_cpu(header->h_hash); |
1575 | struct mb_cache_entry *ce; | 1581 | struct mb_cache_entry *ce; |
1582 | struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode); | ||
1576 | 1583 | ||
1577 | if (!header->h_hash) | 1584 | if (!header->h_hash) |
1578 | return NULL; /* never share */ | 1585 | return NULL; /* never share */ |
1579 | ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); | 1586 | ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); |
1580 | again: | 1587 | again: |
1581 | ce = mb_cache_entry_find_first(ext4_xattr_cache, inode->i_sb->s_bdev, | 1588 | ce = mb_cache_entry_find_first(ext4_mb_cache, inode->i_sb->s_bdev, |
1582 | hash); | 1589 | hash); |
1583 | while (ce) { | 1590 | while (ce) { |
1584 | struct buffer_head *bh; | 1591 | struct buffer_head *bh; |
@@ -1676,19 +1683,17 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *header, | |||
1676 | 1683 | ||
1677 | #undef BLOCK_HASH_SHIFT | 1684 | #undef BLOCK_HASH_SHIFT |
1678 | 1685 | ||
1679 | int __init | 1686 | #define HASH_BUCKET_BITS 10 |
1680 | ext4_init_xattr(void) | 1687 | |
1688 | struct mb_cache * | ||
1689 | ext4_xattr_create_cache(char *name) | ||
1681 | { | 1690 | { |
1682 | ext4_xattr_cache = mb_cache_create("ext4_xattr", 6); | 1691 | return mb_cache_create(name, HASH_BUCKET_BITS); |
1683 | if (!ext4_xattr_cache) | ||
1684 | return -ENOMEM; | ||
1685 | return 0; | ||
1686 | } | 1692 | } |
1687 | 1693 | ||
1688 | void | 1694 | void ext4_xattr_destroy_cache(struct mb_cache *cache) |
1689 | ext4_exit_xattr(void) | ||
1690 | { | 1695 | { |
1691 | if (ext4_xattr_cache) | 1696 | if (cache) |
1692 | mb_cache_destroy(ext4_xattr_cache); | 1697 | mb_cache_destroy(cache); |
1693 | ext4_xattr_cache = NULL; | ||
1694 | } | 1698 | } |
1699 | |||