aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/ext2.h3
-rw-r--r--fs/ext2/super.c25
-rw-r--r--fs/ext2/xattr.c139
-rw-r--r--fs/ext2/xattr.h21
4 files changed, 90 insertions, 98 deletions
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 4c69c94cafd8..170939f379d7 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -61,6 +61,8 @@ struct ext2_block_alloc_info {
61#define rsv_start rsv_window._rsv_start 61#define rsv_start rsv_window._rsv_start
62#define rsv_end rsv_window._rsv_end 62#define rsv_end rsv_window._rsv_end
63 63
64struct mb_cache;
65
64/* 66/*
65 * second extended-fs super-block data in memory 67 * second extended-fs super-block data in memory
66 */ 68 */
@@ -111,6 +113,7 @@ struct ext2_sb_info {
111 * of the mount options. 113 * of the mount options.
112 */ 114 */
113 spinlock_t s_lock; 115 spinlock_t s_lock;
116 struct mb_cache *s_mb_cache;
114}; 117};
115 118
116static inline spinlock_t * 119static inline spinlock_t *
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 2a188413a2b0..b78caf25f746 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -131,7 +131,10 @@ static void ext2_put_super (struct super_block * sb)
131 131
132 dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); 132 dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
133 133
134 ext2_xattr_put_super(sb); 134 if (sbi->s_mb_cache) {
135 ext2_xattr_destroy_cache(sbi->s_mb_cache);
136 sbi->s_mb_cache = NULL;
137 }
135 if (!(sb->s_flags & MS_RDONLY)) { 138 if (!(sb->s_flags & MS_RDONLY)) {
136 struct ext2_super_block *es = sbi->s_es; 139 struct ext2_super_block *es = sbi->s_es;
137 140
@@ -1104,6 +1107,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
1104 ext2_msg(sb, KERN_ERR, "error: insufficient memory"); 1107 ext2_msg(sb, KERN_ERR, "error: insufficient memory");
1105 goto failed_mount3; 1108 goto failed_mount3;
1106 } 1109 }
1110
1111#ifdef CONFIG_EXT2_FS_XATTR
1112 sbi->s_mb_cache = ext2_xattr_create_cache();
1113 if (!sbi->s_mb_cache) {
1114 ext2_msg(sb, KERN_ERR, "Failed to create an mb_cache");
1115 goto failed_mount3;
1116 }
1117#endif
1107 /* 1118 /*
1108 * set up enough so that it can read an inode 1119 * set up enough so that it can read an inode
1109 */ 1120 */
@@ -1149,6 +1160,8 @@ cantfind_ext2:
1149 sb->s_id); 1160 sb->s_id);
1150 goto failed_mount; 1161 goto failed_mount;
1151failed_mount3: 1162failed_mount3:
1163 if (sbi->s_mb_cache)
1164 ext2_xattr_destroy_cache(sbi->s_mb_cache);
1152 percpu_counter_destroy(&sbi->s_freeblocks_counter); 1165 percpu_counter_destroy(&sbi->s_freeblocks_counter);
1153 percpu_counter_destroy(&sbi->s_freeinodes_counter); 1166 percpu_counter_destroy(&sbi->s_freeinodes_counter);
1154 percpu_counter_destroy(&sbi->s_dirs_counter); 1167 percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -1555,20 +1568,17 @@ MODULE_ALIAS_FS("ext2");
1555 1568
1556static int __init init_ext2_fs(void) 1569static int __init init_ext2_fs(void)
1557{ 1570{
1558 int err = init_ext2_xattr(); 1571 int err;
1559 if (err) 1572
1560 return err;
1561 err = init_inodecache(); 1573 err = init_inodecache();
1562 if (err) 1574 if (err)
1563 goto out1; 1575 return err;
1564 err = register_filesystem(&ext2_fs_type); 1576 err = register_filesystem(&ext2_fs_type);
1565 if (err) 1577 if (err)
1566 goto out; 1578 goto out;
1567 return 0; 1579 return 0;
1568out: 1580out:
1569 destroy_inodecache(); 1581 destroy_inodecache();
1570out1:
1571 exit_ext2_xattr();
1572 return err; 1582 return err;
1573} 1583}
1574 1584
@@ -1576,7 +1586,6 @@ static void __exit exit_ext2_fs(void)
1576{ 1586{
1577 unregister_filesystem(&ext2_fs_type); 1587 unregister_filesystem(&ext2_fs_type);
1578 destroy_inodecache(); 1588 destroy_inodecache();
1579 exit_ext2_xattr();
1580} 1589}
1581 1590
1582MODULE_AUTHOR("Remy Card and others"); 1591MODULE_AUTHOR("Remy Card and others");
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index f57a7aba32eb..1a5e3bff0b63 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -90,14 +90,12 @@
90static int ext2_xattr_set2(struct inode *, struct buffer_head *, 90static int ext2_xattr_set2(struct inode *, struct buffer_head *,
91 struct ext2_xattr_header *); 91 struct ext2_xattr_header *);
92 92
93static int ext2_xattr_cache_insert(struct buffer_head *); 93static int ext2_xattr_cache_insert(struct mb_cache *, struct buffer_head *);
94static struct buffer_head *ext2_xattr_cache_find(struct inode *, 94static struct buffer_head *ext2_xattr_cache_find(struct inode *,
95 struct ext2_xattr_header *); 95 struct ext2_xattr_header *);
96static void ext2_xattr_rehash(struct ext2_xattr_header *, 96static void ext2_xattr_rehash(struct ext2_xattr_header *,
97 struct ext2_xattr_entry *); 97 struct ext2_xattr_entry *);
98 98
99static struct mb_cache *ext2_xattr_cache;
100
101static const struct xattr_handler *ext2_xattr_handler_map[] = { 99static const struct xattr_handler *ext2_xattr_handler_map[] = {
102 [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, 100 [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler,
103#ifdef CONFIG_EXT2_FS_POSIX_ACL 101#ifdef CONFIG_EXT2_FS_POSIX_ACL
@@ -152,6 +150,7 @@ ext2_xattr_get(struct inode *inode, int name_index, const char *name,
152 size_t name_len, size; 150 size_t name_len, size;
153 char *end; 151 char *end;
154 int error; 152 int error;
153 struct mb_cache *ext2_mb_cache = EXT2_SB(inode->i_sb)->s_mb_cache;
155 154
156 ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", 155 ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
157 name_index, name, buffer, (long)buffer_size); 156 name_index, name, buffer, (long)buffer_size);
@@ -196,7 +195,7 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_get",
196 goto found; 195 goto found;
197 entry = next; 196 entry = next;
198 } 197 }
199 if (ext2_xattr_cache_insert(bh)) 198 if (ext2_xattr_cache_insert(ext2_mb_cache, bh))
200 ea_idebug(inode, "cache insert failed"); 199 ea_idebug(inode, "cache insert failed");
201 error = -ENODATA; 200 error = -ENODATA;
202 goto cleanup; 201 goto cleanup;
@@ -209,7 +208,7 @@ found:
209 le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) 208 le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
210 goto bad_block; 209 goto bad_block;
211 210
212 if (ext2_xattr_cache_insert(bh)) 211 if (ext2_xattr_cache_insert(ext2_mb_cache, bh))
213 ea_idebug(inode, "cache insert failed"); 212 ea_idebug(inode, "cache insert failed");
214 if (buffer) { 213 if (buffer) {
215 error = -ERANGE; 214 error = -ERANGE;
@@ -247,6 +246,7 @@ ext2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
247 char *end; 246 char *end;
248 size_t rest = buffer_size; 247 size_t rest = buffer_size;
249 int error; 248 int error;
249 struct mb_cache *ext2_mb_cache = EXT2_SB(inode->i_sb)->s_mb_cache;
250 250
251 ea_idebug(inode, "buffer=%p, buffer_size=%ld", 251 ea_idebug(inode, "buffer=%p, buffer_size=%ld",
252 buffer, (long)buffer_size); 252 buffer, (long)buffer_size);
@@ -281,7 +281,7 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list",
281 goto bad_block; 281 goto bad_block;
282 entry = next; 282 entry = next;
283 } 283 }
284 if (ext2_xattr_cache_insert(bh)) 284 if (ext2_xattr_cache_insert(ext2_mb_cache, bh))
285 ea_idebug(inode, "cache insert failed"); 285 ea_idebug(inode, "cache insert failed");
286 286
287 /* list the attribute names */ 287 /* list the attribute names */
@@ -483,22 +483,23 @@ bad_block: ext2_error(sb, "ext2_xattr_set",
483 /* Here we know that we can set the new attribute. */ 483 /* Here we know that we can set the new attribute. */
484 484
485 if (header) { 485 if (header) {
486 struct mb_cache_entry *ce;
487
488 /* assert(header == HDR(bh)); */ 486 /* assert(header == HDR(bh)); */
489 ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev,
490 bh->b_blocknr);
491 lock_buffer(bh); 487 lock_buffer(bh);
492 if (header->h_refcount == cpu_to_le32(1)) { 488 if (header->h_refcount == cpu_to_le32(1)) {
489 __u32 hash = le32_to_cpu(header->h_hash);
490
493 ea_bdebug(bh, "modifying in-place"); 491 ea_bdebug(bh, "modifying in-place");
494 if (ce) 492 /*
495 mb_cache_entry_free(ce); 493 * This must happen under buffer lock for
494 * ext2_xattr_set2() to reliably detect modified block
495 */
496 mb_cache_entry_delete_block(EXT2_SB(sb)->s_mb_cache,
497 hash, bh->b_blocknr);
498
496 /* keep the buffer locked while modifying it. */ 499 /* keep the buffer locked while modifying it. */
497 } else { 500 } else {
498 int offset; 501 int offset;
499 502
500 if (ce)
501 mb_cache_entry_release(ce);
502 unlock_buffer(bh); 503 unlock_buffer(bh);
503 ea_bdebug(bh, "cloning"); 504 ea_bdebug(bh, "cloning");
504 header = kmalloc(bh->b_size, GFP_KERNEL); 505 header = kmalloc(bh->b_size, GFP_KERNEL);
@@ -626,6 +627,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
626 struct super_block *sb = inode->i_sb; 627 struct super_block *sb = inode->i_sb;
627 struct buffer_head *new_bh = NULL; 628 struct buffer_head *new_bh = NULL;
628 int error; 629 int error;
630 struct mb_cache *ext2_mb_cache = EXT2_SB(sb)->s_mb_cache;
629 631
630 if (header) { 632 if (header) {
631 new_bh = ext2_xattr_cache_find(inode, header); 633 new_bh = ext2_xattr_cache_find(inode, header);
@@ -653,7 +655,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
653 don't need to change the reference count. */ 655 don't need to change the reference count. */
654 new_bh = old_bh; 656 new_bh = old_bh;
655 get_bh(new_bh); 657 get_bh(new_bh);
656 ext2_xattr_cache_insert(new_bh); 658 ext2_xattr_cache_insert(ext2_mb_cache, new_bh);
657 } else { 659 } else {
658 /* We need to allocate a new block */ 660 /* We need to allocate a new block */
659 ext2_fsblk_t goal = ext2_group_first_block_no(sb, 661 ext2_fsblk_t goal = ext2_group_first_block_no(sb,
@@ -674,7 +676,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
674 memcpy(new_bh->b_data, header, new_bh->b_size); 676 memcpy(new_bh->b_data, header, new_bh->b_size);
675 set_buffer_uptodate(new_bh); 677 set_buffer_uptodate(new_bh);
676 unlock_buffer(new_bh); 678 unlock_buffer(new_bh);
677 ext2_xattr_cache_insert(new_bh); 679 ext2_xattr_cache_insert(ext2_mb_cache, new_bh);
678 680
679 ext2_xattr_update_super_block(sb); 681 ext2_xattr_update_super_block(sb);
680 } 682 }
@@ -707,19 +709,21 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
707 709
708 error = 0; 710 error = 0;
709 if (old_bh && old_bh != new_bh) { 711 if (old_bh && old_bh != new_bh) {
710 struct mb_cache_entry *ce;
711
712 /* 712 /*
713 * If there was an old block and we are no longer using it, 713 * If there was an old block and we are no longer using it,
714 * release the old block. 714 * release the old block.
715 */ 715 */
716 ce = mb_cache_entry_get(ext2_xattr_cache, old_bh->b_bdev,
717 old_bh->b_blocknr);
718 lock_buffer(old_bh); 716 lock_buffer(old_bh);
719 if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) { 717 if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) {
718 __u32 hash = le32_to_cpu(HDR(old_bh)->h_hash);
719
720 /*
721 * This must happen under buffer lock for
722 * ext2_xattr_set2() to reliably detect freed block
723 */
724 mb_cache_entry_delete_block(ext2_mb_cache,
725 hash, old_bh->b_blocknr);
720 /* Free the old block. */ 726 /* Free the old block. */
721 if (ce)
722 mb_cache_entry_free(ce);
723 ea_bdebug(old_bh, "freeing"); 727 ea_bdebug(old_bh, "freeing");
724 ext2_free_blocks(inode, old_bh->b_blocknr, 1); 728 ext2_free_blocks(inode, old_bh->b_blocknr, 1);
725 mark_inode_dirty(inode); 729 mark_inode_dirty(inode);
@@ -730,8 +734,6 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
730 } else { 734 } else {
731 /* Decrement the refcount only. */ 735 /* Decrement the refcount only. */
732 le32_add_cpu(&HDR(old_bh)->h_refcount, -1); 736 le32_add_cpu(&HDR(old_bh)->h_refcount, -1);
733 if (ce)
734 mb_cache_entry_release(ce);
735 dquot_free_block_nodirty(inode, 1); 737 dquot_free_block_nodirty(inode, 1);
736 mark_inode_dirty(inode); 738 mark_inode_dirty(inode);
737 mark_buffer_dirty(old_bh); 739 mark_buffer_dirty(old_bh);
@@ -757,7 +759,6 @@ void
757ext2_xattr_delete_inode(struct inode *inode) 759ext2_xattr_delete_inode(struct inode *inode)
758{ 760{
759 struct buffer_head *bh = NULL; 761 struct buffer_head *bh = NULL;
760 struct mb_cache_entry *ce;
761 762
762 down_write(&EXT2_I(inode)->xattr_sem); 763 down_write(&EXT2_I(inode)->xattr_sem);
763 if (!EXT2_I(inode)->i_file_acl) 764 if (!EXT2_I(inode)->i_file_acl)
@@ -777,19 +778,22 @@ ext2_xattr_delete_inode(struct inode *inode)
777 EXT2_I(inode)->i_file_acl); 778 EXT2_I(inode)->i_file_acl);
778 goto cleanup; 779 goto cleanup;
779 } 780 }
780 ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev, bh->b_blocknr);
781 lock_buffer(bh); 781 lock_buffer(bh);
782 if (HDR(bh)->h_refcount == cpu_to_le32(1)) { 782 if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
783 if (ce) 783 __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
784 mb_cache_entry_free(ce); 784
785 /*
786 * This must happen under buffer lock for ext2_xattr_set2() to
787 * reliably detect freed block
788 */
789 mb_cache_entry_delete_block(EXT2_SB(inode->i_sb)->s_mb_cache,
790 hash, bh->b_blocknr);
785 ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1); 791 ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1);
786 get_bh(bh); 792 get_bh(bh);
787 bforget(bh); 793 bforget(bh);
788 unlock_buffer(bh); 794 unlock_buffer(bh);
789 } else { 795 } else {
790 le32_add_cpu(&HDR(bh)->h_refcount, -1); 796 le32_add_cpu(&HDR(bh)->h_refcount, -1);
791 if (ce)
792 mb_cache_entry_release(ce);
793 ea_bdebug(bh, "refcount now=%d", 797 ea_bdebug(bh, "refcount now=%d",
794 le32_to_cpu(HDR(bh)->h_refcount)); 798 le32_to_cpu(HDR(bh)->h_refcount));
795 unlock_buffer(bh); 799 unlock_buffer(bh);
@@ -806,18 +810,6 @@ cleanup:
806} 810}
807 811
808/* 812/*
809 * ext2_xattr_put_super()
810 *
811 * This is called when a file system is unmounted.
812 */
813void
814ext2_xattr_put_super(struct super_block *sb)
815{
816 mb_cache_shrink(sb->s_bdev);
817}
818
819
820/*
821 * ext2_xattr_cache_insert() 813 * ext2_xattr_cache_insert()
822 * 814 *
823 * Create a new entry in the extended attribute cache, and insert 815 * Create a new entry in the extended attribute cache, and insert
@@ -826,28 +818,20 @@ ext2_xattr_put_super(struct super_block *sb)
826 * Returns 0, or a negative error number on failure. 818 * Returns 0, or a negative error number on failure.
827 */ 819 */
828static int 820static int
829ext2_xattr_cache_insert(struct buffer_head *bh) 821ext2_xattr_cache_insert(struct mb_cache *cache, struct buffer_head *bh)
830{ 822{
831 __u32 hash = le32_to_cpu(HDR(bh)->h_hash); 823 __u32 hash = le32_to_cpu(HDR(bh)->h_hash);
832 struct mb_cache_entry *ce;
833 int error; 824 int error;
834 825
835 ce = mb_cache_entry_alloc(ext2_xattr_cache, GFP_NOFS); 826 error = mb_cache_entry_create(cache, GFP_NOFS, hash, bh->b_blocknr, 1);
836 if (!ce)
837 return -ENOMEM;
838 error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, hash);
839 if (error) { 827 if (error) {
840 mb_cache_entry_free(ce);
841 if (error == -EBUSY) { 828 if (error == -EBUSY) {
842 ea_bdebug(bh, "already in cache (%d cache entries)", 829 ea_bdebug(bh, "already in cache (%d cache entries)",
843 atomic_read(&ext2_xattr_cache->c_entry_count)); 830 atomic_read(&ext2_xattr_cache->c_entry_count));
844 error = 0; 831 error = 0;
845 } 832 }
846 } else { 833 } else
847 ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, 834 ea_bdebug(bh, "inserting [%x]", (int)hash);
848 atomic_read(&ext2_xattr_cache->c_entry_count));
849 mb_cache_entry_release(ce);
850 }
851 return error; 835 return error;
852} 836}
853 837
@@ -904,22 +888,16 @@ ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
904{ 888{
905 __u32 hash = le32_to_cpu(header->h_hash); 889 __u32 hash = le32_to_cpu(header->h_hash);
906 struct mb_cache_entry *ce; 890 struct mb_cache_entry *ce;
891 struct mb_cache *ext2_mb_cache = EXT2_SB(inode->i_sb)->s_mb_cache;
907 892
908 if (!header->h_hash) 893 if (!header->h_hash)
909 return NULL; /* never share */ 894 return NULL; /* never share */
910 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); 895 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
911again: 896again:
912 ce = mb_cache_entry_find_first(ext2_xattr_cache, inode->i_sb->s_bdev, 897 ce = mb_cache_entry_find_first(ext2_mb_cache, hash);
913 hash);
914 while (ce) { 898 while (ce) {
915 struct buffer_head *bh; 899 struct buffer_head *bh;
916 900
917 if (IS_ERR(ce)) {
918 if (PTR_ERR(ce) == -EAGAIN)
919 goto again;
920 break;
921 }
922
923 bh = sb_bread(inode->i_sb, ce->e_block); 901 bh = sb_bread(inode->i_sb, ce->e_block);
924 if (!bh) { 902 if (!bh) {
925 ext2_error(inode->i_sb, "ext2_xattr_cache_find", 903 ext2_error(inode->i_sb, "ext2_xattr_cache_find",
@@ -927,7 +905,21 @@ again:
927 inode->i_ino, (unsigned long) ce->e_block); 905 inode->i_ino, (unsigned long) ce->e_block);
928 } else { 906 } else {
929 lock_buffer(bh); 907 lock_buffer(bh);
930 if (le32_to_cpu(HDR(bh)->h_refcount) > 908 /*
909 * We have to be careful about races with freeing or
910 * rehashing of xattr block. Once we hold buffer lock
911 * xattr block's state is stable so we can check
912 * whether the block got freed / rehashed or not.
913 * Since we unhash mbcache entry under buffer lock when
914 * freeing / rehashing xattr block, checking whether
915 * entry is still hashed is reliable.
916 */
917 if (hlist_bl_unhashed(&ce->e_hash_list)) {
918 mb_cache_entry_put(ext2_mb_cache, ce);
919 unlock_buffer(bh);
920 brelse(bh);
921 goto again;
922 } else if (le32_to_cpu(HDR(bh)->h_refcount) >
931 EXT2_XATTR_REFCOUNT_MAX) { 923 EXT2_XATTR_REFCOUNT_MAX) {
932 ea_idebug(inode, "block %ld refcount %d>%d", 924 ea_idebug(inode, "block %ld refcount %d>%d",
933 (unsigned long) ce->e_block, 925 (unsigned long) ce->e_block,
@@ -936,13 +928,14 @@ again:
936 } else if (!ext2_xattr_cmp(header, HDR(bh))) { 928 } else if (!ext2_xattr_cmp(header, HDR(bh))) {
937 ea_bdebug(bh, "b_count=%d", 929 ea_bdebug(bh, "b_count=%d",
938 atomic_read(&(bh->b_count))); 930 atomic_read(&(bh->b_count)));
939 mb_cache_entry_release(ce); 931 mb_cache_entry_touch(ext2_mb_cache, ce);
932 mb_cache_entry_put(ext2_mb_cache, ce);
940 return bh; 933 return bh;
941 } 934 }
942 unlock_buffer(bh); 935 unlock_buffer(bh);
943 brelse(bh); 936 brelse(bh);
944 } 937 }
945 ce = mb_cache_entry_find_next(ce, inode->i_sb->s_bdev, hash); 938 ce = mb_cache_entry_find_next(ext2_mb_cache, ce);
946 } 939 }
947 return NULL; 940 return NULL;
948} 941}
@@ -1015,17 +1008,15 @@ static void ext2_xattr_rehash(struct ext2_xattr_header *header,
1015 1008
1016#undef BLOCK_HASH_SHIFT 1009#undef BLOCK_HASH_SHIFT
1017 1010
1018int __init 1011#define HASH_BUCKET_BITS 10
1019init_ext2_xattr(void) 1012
1013struct mb_cache *ext2_xattr_create_cache(void)
1020{ 1014{
1021 ext2_xattr_cache = mb_cache_create("ext2_xattr", 6); 1015 return mb_cache_create(HASH_BUCKET_BITS);
1022 if (!ext2_xattr_cache)
1023 return -ENOMEM;
1024 return 0;
1025} 1016}
1026 1017
1027void 1018void ext2_xattr_destroy_cache(struct mb_cache *cache)
1028exit_ext2_xattr(void)
1029{ 1019{
1030 mb_cache_destroy(ext2_xattr_cache); 1020 if (cache)
1021 mb_cache_destroy(cache);
1031} 1022}
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h
index 60edf298644e..6f82ab1b00ca 100644
--- a/fs/ext2/xattr.h
+++ b/fs/ext2/xattr.h
@@ -53,6 +53,8 @@ struct ext2_xattr_entry {
53#define EXT2_XATTR_SIZE(size) \ 53#define EXT2_XATTR_SIZE(size) \
54 (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND) 54 (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
55 55
56struct mb_cache;
57
56# ifdef CONFIG_EXT2_FS_XATTR 58# ifdef CONFIG_EXT2_FS_XATTR
57 59
58extern const struct xattr_handler ext2_xattr_user_handler; 60extern const struct xattr_handler ext2_xattr_user_handler;
@@ -65,10 +67,9 @@ extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
65extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int); 67extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
66 68
67extern void ext2_xattr_delete_inode(struct inode *); 69extern void ext2_xattr_delete_inode(struct inode *);
68extern void ext2_xattr_put_super(struct super_block *);
69 70
70extern int init_ext2_xattr(void); 71extern struct mb_cache *ext2_xattr_create_cache(void);
71extern void exit_ext2_xattr(void); 72extern void ext2_xattr_destroy_cache(struct mb_cache *cache);
72 73
73extern const struct xattr_handler *ext2_xattr_handlers[]; 74extern const struct xattr_handler *ext2_xattr_handlers[];
74 75
@@ -93,19 +94,7 @@ ext2_xattr_delete_inode(struct inode *inode)
93{ 94{
94} 95}
95 96
96static inline void 97static inline void ext2_xattr_destroy_cache(struct mb_cache *cache)
97ext2_xattr_put_super(struct super_block *sb)
98{
99}
100
101static inline int
102init_ext2_xattr(void)
103{
104 return 0;
105}
106
107static inline void
108exit_ext2_xattr(void)
109{ 98{
110} 99}
111 100