Skip to content

Commit 9c191f7

Browse files
T Makphaibulchoketytso
authored andcommitted
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>
1 parent 1f3e55f commit 9c191f7

File tree

5 files changed

+62
-39
lines changed

5 files changed

+62
-39
lines changed

fs/ext4/ext4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,7 @@ struct ext4_sb_info {
13291329
struct list_head s_es_lru;
13301330
unsigned long s_es_last_sorted;
13311331
struct percpu_counter s_extent_cache_cnt;
1332+
struct mb_cache *s_mb_cache;
13321333
spinlock_t s_es_lru_lock ____cacheline_aligned_in_smp;
13331334

13341335
/* Ratelimit ext4 messages. */

fs/ext4/super.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static struct kset *ext4_kset;
5959
static struct ext4_lazy_init *ext4_li_info;
6060
static struct mutex ext4_li_mtx;
6161
static struct ext4_features *ext4_feat;
62+
static int ext4_mballoc_ready;
6263

6364
static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
6465
unsigned long journal_devnum);
@@ -845,6 +846,10 @@ static void ext4_put_super(struct super_block *sb)
845846
invalidate_bdev(sbi->journal_bdev);
846847
ext4_blkdev_remove(sbi);
847848
}
849+
if (sbi->s_mb_cache) {
850+
ext4_xattr_destroy_cache(sbi->s_mb_cache);
851+
sbi->s_mb_cache = NULL;
852+
}
848853
if (sbi->s_mmp_tsk)
849854
kthread_stop(sbi->s_mmp_tsk);
850855
sb->s_fs_info = NULL;
@@ -4010,6 +4015,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
40104015
percpu_counter_set(&sbi->s_dirtyclusters_counter, 0);
40114016

40124017
no_journal:
4018+
if (ext4_mballoc_ready) {
4019+
sbi->s_mb_cache = ext4_xattr_create_cache(sb->s_id);
4020+
if (!sbi->s_mb_cache) {
4021+
ext4_msg(sb, KERN_ERR, "Failed to create an mb_cache");
4022+
goto failed_mount_wq;
4023+
}
4024+
}
4025+
40134026
/*
40144027
* Get the # of file system overhead blocks from the
40154028
* superblock if present.
@@ -5518,12 +5531,10 @@ static int __init ext4_init_fs(void)
55185531
goto out4;
55195532

55205533
err = ext4_init_mballoc();
5521-
if (err)
5522-
goto out3;
5523-
5524-
err = ext4_init_xattr();
55255534
if (err)
55265535
goto out2;
5536+
else
5537+
ext4_mballoc_ready = 1;
55275538
err = init_inodecache();
55285539
if (err)
55295540
goto out1;
@@ -5539,10 +5550,9 @@ static int __init ext4_init_fs(void)
55395550
unregister_as_ext3();
55405551
destroy_inodecache();
55415552
out1:
5542-
ext4_exit_xattr();
5543-
out2:
5553+
ext4_mballoc_ready = 0;
55445554
ext4_exit_mballoc();
5545-
out3:
5555+
out2:
55465556
ext4_exit_feat_adverts();
55475557
out4:
55485558
if (ext4_proc_root)
@@ -5565,7 +5575,6 @@ static void __exit ext4_exit_fs(void)
55655575
unregister_as_ext3();
55665576
unregister_filesystem(&ext4_fs_type);
55675577
destroy_inodecache();
5568-
ext4_exit_xattr();
55695578
ext4_exit_mballoc();
55705579
ext4_exit_feat_adverts();
55715580
remove_proc_entry("fs/ext4", NULL);

fs/ext4/xattr.c

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
# define ea_bdebug(bh, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
8282
#endif
8383

84-
static void ext4_xattr_cache_insert(struct buffer_head *);
84+
static void ext4_xattr_cache_insert(struct mb_cache *, struct buffer_head *);
8585
static struct buffer_head *ext4_xattr_cache_find(struct inode *,
8686
struct ext4_xattr_header *,
8787
struct mb_cache_entry **);
@@ -90,8 +90,6 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *,
9090
static int ext4_xattr_list(struct dentry *dentry, char *buffer,
9191
size_t buffer_size);
9292

93-
static struct mb_cache *ext4_xattr_cache;
94-
9593
static const struct xattr_handler *ext4_xattr_handler_map[] = {
9694
[EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler,
9795
#ifdef CONFIG_EXT4_FS_POSIX_ACL
@@ -117,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = {
117115
NULL
118116
};
119117

118+
#define EXT4_GET_MB_CACHE(inode) (((struct ext4_sb_info *) \
119+
inode->i_sb->s_fs_info)->s_mb_cache)
120+
120121
static __le32 ext4_xattr_block_csum(struct inode *inode,
121122
sector_t block_nr,
122123
struct ext4_xattr_header *hdr)
@@ -265,6 +266,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
265266
struct ext4_xattr_entry *entry;
266267
size_t size;
267268
int error;
269+
struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
268270

269271
ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
270272
name_index, name, buffer, (long)buffer_size);
@@ -286,7 +288,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
286288
error = -EIO;
287289
goto cleanup;
288290
}
289-
ext4_xattr_cache_insert(bh);
291+
ext4_xattr_cache_insert(ext4_mb_cache, bh);
290292
entry = BFIRST(bh);
291293
error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
292294
if (error == -EIO)
@@ -409,6 +411,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
409411
struct inode *inode = dentry->d_inode;
410412
struct buffer_head *bh = NULL;
411413
int error;
414+
struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
412415

413416
ea_idebug(inode, "buffer=%p, buffer_size=%ld",
414417
buffer, (long)buffer_size);
@@ -430,7 +433,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
430433
error = -EIO;
431434
goto cleanup;
432435
}
433-
ext4_xattr_cache_insert(bh);
436+
ext4_xattr_cache_insert(ext4_mb_cache, bh);
434437
error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size);
435438

436439
cleanup:
@@ -526,8 +529,9 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
526529
{
527530
struct mb_cache_entry *ce = NULL;
528531
int error = 0;
532+
struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
529533

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);
531535
error = ext4_journal_get_write_access(handle, bh);
532536
if (error)
533537
goto out;
@@ -746,13 +750,14 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
746750
struct ext4_xattr_search *s = &bs->s;
747751
struct mb_cache_entry *ce = NULL;
748752
int error = 0;
753+
struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
749754

750755
#define header(x) ((struct ext4_xattr_header *)(x))
751756

752757
if (i->value && i->value_len > sb->s_blocksize)
753758
return -ENOSPC;
754759
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,
756761
bs->bh->b_blocknr);
757762
error = ext4_journal_get_write_access(handle, bs->bh);
758763
if (error)
@@ -770,7 +775,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
770775
if (!IS_LAST_ENTRY(s->first))
771776
ext4_xattr_rehash(header(s->base),
772777
s->here);
773-
ext4_xattr_cache_insert(bs->bh);
778+
ext4_xattr_cache_insert(ext4_mb_cache,
779+
bs->bh);
774780
}
775781
unlock_buffer(bs->bh);
776782
if (error == -EIO)
@@ -906,7 +912,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
906912
memcpy(new_bh->b_data, s->base, new_bh->b_size);
907913
set_buffer_uptodate(new_bh);
908914
unlock_buffer(new_bh);
909-
ext4_xattr_cache_insert(new_bh);
915+
ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
910916
error = ext4_handle_dirty_xattr_block(handle,
911917
inode, new_bh);
912918
if (error)
@@ -1495,13 +1501,13 @@ ext4_xattr_put_super(struct super_block *sb)
14951501
* Returns 0, or a negative error number on failure.
14961502
*/
14971503
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)
14991505
{
15001506
__u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
15011507
struct mb_cache_entry *ce;
15021508
int error;
15031509

1504-
ce = mb_cache_entry_alloc(ext4_xattr_cache, GFP_NOFS);
1510+
ce = mb_cache_entry_alloc(ext4_mb_cache, GFP_NOFS);
15051511
if (!ce) {
15061512
ea_bdebug(bh, "out of memory");
15071513
return;
@@ -1573,12 +1579,13 @@ ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header,
15731579
{
15741580
__u32 hash = le32_to_cpu(header->h_hash);
15751581
struct mb_cache_entry *ce;
1582+
struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
15761583

15771584
if (!header->h_hash)
15781585
return NULL; /* never share */
15791586
ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
15801587
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,
15821589
hash);
15831590
while (ce) {
15841591
struct buffer_head *bh;
@@ -1676,19 +1683,17 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *header,
16761683

16771684
#undef BLOCK_HASH_SHIFT
16781685

1679-
int __init
1680-
ext4_init_xattr(void)
1686+
#define HASH_BUCKET_BITS 10
1687+
1688+
struct mb_cache *
1689+
ext4_xattr_create_cache(char *name)
16811690
{
1682-
ext4_xattr_cache = mb_cache_create("ext4_xattr", 6);
1683-
if (!ext4_xattr_cache)
1684-
return -ENOMEM;
1685-
return 0;
1691+
return mb_cache_create(name, HASH_BUCKET_BITS);
16861692
}
16871693

1688-
void
1689-
ext4_exit_xattr(void)
1694+
void ext4_xattr_destroy_cache(struct mb_cache *cache)
16901695
{
1691-
if (ext4_xattr_cache)
1692-
mb_cache_destroy(ext4_xattr_cache);
1693-
ext4_xattr_cache = NULL;
1696+
if (cache)
1697+
mb_cache_destroy(cache);
16941698
}
1699+

fs/ext4/xattr.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,6 @@ extern void ext4_xattr_put_super(struct super_block *);
110110
extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
111111
struct ext4_inode *raw_inode, handle_t *handle);
112112

113-
extern int __init ext4_init_xattr(void);
114-
extern void ext4_exit_xattr(void);
115-
116113
extern const struct xattr_handler *ext4_xattr_handlers[];
117114

118115
extern int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
@@ -124,6 +121,9 @@ extern int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode,
124121
struct ext4_xattr_info *i,
125122
struct ext4_xattr_ibody_find *is);
126123

124+
extern struct mb_cache *ext4_xattr_create_cache(char *name);
125+
extern void ext4_xattr_destroy_cache(struct mb_cache *);
126+
127127
#ifdef CONFIG_EXT4_FS_SECURITY
128128
extern int ext4_init_security(handle_t *handle, struct inode *inode,
129129
struct inode *dir, const struct qstr *qstr);

fs/mbcache.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999

100100
static DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue);
101101
static struct blockgroup_lock *mb_cache_bg_lock;
102+
static struct kmem_cache *mb_cache_kmem_cache;
102103

103104
MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
104105
MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
@@ -351,11 +352,14 @@ mb_cache_create(const char *name, int bucket_bits)
351352
goto fail;
352353
for (n=0; n<bucket_count; n++)
353354
INIT_HLIST_BL_HEAD(&cache->c_index_hash[n]);
354-
cache->c_entry_cache = kmem_cache_create(name,
355-
sizeof(struct mb_cache_entry), 0,
356-
SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
357-
if (!cache->c_entry_cache)
358-
goto fail2;
355+
if (!mb_cache_kmem_cache) {
356+
mb_cache_kmem_cache = kmem_cache_create(name,
357+
sizeof(struct mb_cache_entry), 0,
358+
SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
359+
if (!mb_cache_kmem_cache)
360+
goto fail2;
361+
}
362+
cache->c_entry_cache = mb_cache_kmem_cache;
359363

360364
/*
361365
* Set an upper limit on the number of cache entries so that the hash
@@ -476,6 +480,10 @@ mb_cache_destroy(struct mb_cache *cache)
476480
atomic_read(&cache->c_entry_count));
477481
}
478482

483+
if (list_empty(&mb_cache_list)) {
484+
kmem_cache_destroy(mb_cache_kmem_cache);
485+
mb_cache_kmem_cache = NULL;
486+
}
479487
kfree(cache->c_index_hash);
480488
kfree(cache->c_block_hash);
481489
kfree(cache);

0 commit comments

Comments
 (0)