1 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
2 index f256696..d7a3413 100644
5 @@ -1047,6 +1047,7 @@ struct ext4_inode_info {
7 * Mount flags set via mount options or defaults
9 +#define EXT4_MOUNT_NO_MBCACHE 0x00001 /* Disable mbcache */
10 #define EXT4_MOUNT_GRPID 0x00004 /* Create files with directory's group */
11 #define EXT4_MOUNT_DEBUG 0x00008 /* Some debugging messages */
12 #define EXT4_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */
13 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
14 index e286670..97e5e32 100644
17 @@ -1168,6 +1168,7 @@ enum {
18 Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
19 Opt_inode_readahead_blks, Opt_journal_ioprio,
20 Opt_dioread_nolock, Opt_dioread_lock,
22 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
23 Opt_max_dir_size_kb, Opt_nojournal_checksum,
25 @@ -1247,6 +1248,7 @@ static const match_table_t tokens = {
26 {Opt_discard, "discard"},
27 {Opt_nodiscard, "nodiscard"},
28 {Opt_init_itable, "init_itable=%u"},
29 + {Opt_no_mbcache, "no_mbcache"},
30 {Opt_init_itable, "init_itable"},
31 {Opt_noinit_itable, "noinit_itable"},
32 {Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
33 @@ -1410,6 +1412,7 @@ static const struct mount_opts {
34 {Opt_noauto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_SET},
35 {Opt_auto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_CLEAR},
36 {Opt_noinit_itable, EXT4_MOUNT_INIT_INODE_TABLE, MOPT_CLEAR},
37 + {Opt_no_mbcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET},
38 {Opt_commit, 0, MOPT_GTE0},
39 {Opt_max_batch_time, 0, MOPT_GTE0},
40 {Opt_min_batch_time, 0, MOPT_GTE0},
41 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
42 index 22ba197..d7e225e 100644
46 # define ea_bdebug(bh, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
49 -static void ext4_xattr_cache_insert(struct mb_cache *, struct buffer_head *);
50 +static void _ext4_xattr_cache_insert(struct mb_cache *, struct buffer_head *);
51 static struct buffer_head *ext4_xattr_cache_find(struct inode *,
52 struct ext4_xattr_header *,
53 struct mb_cache_entry **);
54 @@ -397,7 +397,8 @@ bad_block:
55 error = -EFSCORRUPTED;
58 - ext4_xattr_cache_insert(ext4_mb_cache, bh);
59 + if (!test_opt(inode->i_sb, NO_MBCACHE))
60 + _ext4_xattr_cache_insert(ext4_mb_cache, bh);
62 error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1,
64 @@ -561,7 +562,8 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
65 error = -EFSCORRUPTED;
68 - ext4_xattr_cache_insert(ext4_mb_cache, bh);
69 + if (!test_opt(inode->i_sb, NO_MBCACHE))
70 + _ext4_xattr_cache_insert(ext4_mb_cache, bh);
71 error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size);
74 @@ -669,7 +671,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
76 if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
77 ea_bdebug(bh, "refcount now=0; freeing");
79 + if (ce && !test_opt(inode->i_sb, NO_MBCACHE))
80 mb_cache_entry_free(ce);
83 @@ -1086,7 +1088,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
86 if (header(s->base)->h_refcount == cpu_to_le32(1)) {
88 + if (ce && !test_opt(inode->i_sb, NO_MBCACHE)) {
89 mb_cache_entry_free(ce);
92 @@ -1096,8 +1098,9 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
93 if (!IS_LAST_ENTRY(s->first))
94 ext4_xattr_rehash(header(s->base),
96 - ext4_xattr_cache_insert(ext4_mb_cache,
98 + if (!test_opt(inode->i_sb, NO_MBCACHE))
99 + _ext4_xattr_cache_insert(ext4_mb_cache,
102 ext4_xattr_block_csum_set(inode, bs->bh);
103 unlock_buffer(bs->bh);
104 @@ -1231,7 +1234,8 @@ getblk_failed:
105 ext4_xattr_block_csum_set(inode, new_bh);
106 set_buffer_uptodate(new_bh);
107 unlock_buffer(new_bh);
108 - ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
109 + if (!test_opt(inode->i_sb, NO_MBCACHE))
110 + _ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
111 error = ext4_handle_dirty_metadata(handle, inode,
114 @@ -2024,7 +2028,7 @@ ext4_xattr_put_super(struct super_block *sb)
115 * Returns 0, or a negative error number on failure.
118 -ext4_xattr_cache_insert(struct mb_cache *ext4_mb_cache, struct buffer_head *bh)
119 +_ext4_xattr_cache_insert(struct mb_cache *ext4_mb_cache, struct buffer_head *bh)
121 __u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
122 struct mb_cache_entry *ce;
123 @@ -2103,6 +2107,8 @@ ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header,
124 struct mb_cache_entry *ce;
125 struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
127 + if (test_opt(inode->i_sb, NO_MBCACHE))
130 return NULL; /* never share */
131 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);