aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h1
-rw-r--r--fs/ext4/super.c34
-rw-r--r--fs/ext4/xattr.c52
3 files changed, 59 insertions, 28 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index fe92a63c86cb..68ddd24db9a2 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1114,6 +1114,7 @@ struct ext4_inode_info {
1114/* 1114/*
1115 * Mount flags set via mount options or defaults 1115 * Mount flags set via mount options or defaults
1116 */ 1116 */
1117#define EXT4_MOUNT_NO_MBCACHE 0x00001 /* Do not use mbcache */
1117#define EXT4_MOUNT_GRPID 0x00004 /* Create files with directory's group */ 1118#define EXT4_MOUNT_GRPID 0x00004 /* Create files with directory's group */
1118#define EXT4_MOUNT_DEBUG 0x00008 /* Some debugging messages */ 1119#define EXT4_MOUNT_DEBUG 0x00008 /* Some debugging messages */
1119#define EXT4_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */ 1120#define EXT4_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 5ac76e8d4013..1fec35bd4084 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1336,7 +1336,7 @@ enum {
1336 Opt_inode_readahead_blks, Opt_journal_ioprio, 1336 Opt_inode_readahead_blks, Opt_journal_ioprio,
1337 Opt_dioread_nolock, Opt_dioread_lock, 1337 Opt_dioread_nolock, Opt_dioread_lock,
1338 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable, 1338 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
1339 Opt_max_dir_size_kb, Opt_nojournal_checksum, 1339 Opt_max_dir_size_kb, Opt_nojournal_checksum, Opt_nombcache,
1340}; 1340};
1341 1341
1342static const match_table_t tokens = { 1342static const match_table_t tokens = {
@@ -1419,6 +1419,8 @@ static const match_table_t tokens = {
1419 {Opt_noinit_itable, "noinit_itable"}, 1419 {Opt_noinit_itable, "noinit_itable"},
1420 {Opt_max_dir_size_kb, "max_dir_size_kb=%u"}, 1420 {Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
1421 {Opt_test_dummy_encryption, "test_dummy_encryption"}, 1421 {Opt_test_dummy_encryption, "test_dummy_encryption"},
1422 {Opt_nombcache, "nombcache"},
1423 {Opt_nombcache, "no_mbcache"}, /* for backward compatibility */
1422 {Opt_removed, "check=none"}, /* mount option from ext2/3 */ 1424 {Opt_removed, "check=none"}, /* mount option from ext2/3 */
1423 {Opt_removed, "nocheck"}, /* mount option from ext2/3 */ 1425 {Opt_removed, "nocheck"}, /* mount option from ext2/3 */
1424 {Opt_removed, "reservation"}, /* mount option from ext2/3 */ 1426 {Opt_removed, "reservation"}, /* mount option from ext2/3 */
@@ -1626,6 +1628,7 @@ static const struct mount_opts {
1626 {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT}, 1628 {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
1627 {Opt_max_dir_size_kb, 0, MOPT_GTE0}, 1629 {Opt_max_dir_size_kb, 0, MOPT_GTE0},
1628 {Opt_test_dummy_encryption, 0, MOPT_GTE0}, 1630 {Opt_test_dummy_encryption, 0, MOPT_GTE0},
1631 {Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET},
1629 {Opt_err, 0, 0} 1632 {Opt_err, 0, 0}
1630}; 1633};
1631 1634
@@ -4080,19 +4083,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
4080 sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; 4083 sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
4081 4084
4082no_journal: 4085no_journal:
4083 sbi->s_ea_block_cache = ext4_xattr_create_cache(); 4086 if (!test_opt(sb, NO_MBCACHE)) {
4084 if (!sbi->s_ea_block_cache) { 4087 sbi->s_ea_block_cache = ext4_xattr_create_cache();
4085 ext4_msg(sb, KERN_ERR, "Failed to create ea_block_cache"); 4088 if (!sbi->s_ea_block_cache) {
4086 goto failed_mount_wq;
4087 }
4088
4089 if (ext4_has_feature_ea_inode(sb)) {
4090 sbi->s_ea_inode_cache = ext4_xattr_create_cache();
4091 if (!sbi->s_ea_inode_cache) {
4092 ext4_msg(sb, KERN_ERR, 4089 ext4_msg(sb, KERN_ERR,
4093 "Failed to create ea_inode_cache"); 4090 "Failed to create ea_block_cache");
4094 goto failed_mount_wq; 4091 goto failed_mount_wq;
4095 } 4092 }
4093
4094 if (ext4_has_feature_ea_inode(sb)) {
4095 sbi->s_ea_inode_cache = ext4_xattr_create_cache();
4096 if (!sbi->s_ea_inode_cache) {
4097 ext4_msg(sb, KERN_ERR,
4098 "Failed to create ea_inode_cache");
4099 goto failed_mount_wq;
4100 }
4101 }
4096 } 4102 }
4097 4103
4098 if ((DUMMY_ENCRYPTION_ENABLED(sbi) || ext4_has_feature_encrypt(sb)) && 4104 if ((DUMMY_ENCRYPTION_ENABLED(sbi) || ext4_has_feature_encrypt(sb)) &&
@@ -4989,6 +4995,12 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
4989 } 4995 }
4990 } 4996 }
4991 4997
4998 if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT4_MOUNT_NO_MBCACHE) {
4999 ext4_msg(sb, KERN_ERR, "can't enable nombcache during remount");
5000 err = -EINVAL;
5001 goto restore_opts;
5002 }
5003
4992 if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT4_MOUNT_DAX) { 5004 if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT4_MOUNT_DAX) {
4993 ext4_msg(sb, KERN_WARNING, "warning: refusing change of " 5005 ext4_msg(sb, KERN_WARNING, "warning: refusing change of "
4994 "dax flag with busy inodes while remounting"); 5006 "dax flag with busy inodes while remounting");
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index a5ad0ccdd1cb..34fa37e7744c 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -991,10 +991,13 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
991 set_nlink(ea_inode, 1); 991 set_nlink(ea_inode, 1);
992 ext4_orphan_del(handle, ea_inode); 992 ext4_orphan_del(handle, ea_inode);
993 993
994 hash = ext4_xattr_inode_get_hash(ea_inode); 994 if (ea_inode_cache) {
995 mb_cache_entry_create(ea_inode_cache, GFP_NOFS, hash, 995 hash = ext4_xattr_inode_get_hash(ea_inode);
996 ea_inode->i_ino, 996 mb_cache_entry_create(ea_inode_cache,
997 true /* reusable */); 997 GFP_NOFS, hash,
998 ea_inode->i_ino,
999 true /* reusable */);
1000 }
998 } 1001 }
999 } else { 1002 } else {
1000 WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld", 1003 WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
@@ -1008,9 +1011,11 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
1008 clear_nlink(ea_inode); 1011 clear_nlink(ea_inode);
1009 ext4_orphan_add(handle, ea_inode); 1012 ext4_orphan_add(handle, ea_inode);
1010 1013
1011 hash = ext4_xattr_inode_get_hash(ea_inode); 1014 if (ea_inode_cache) {
1012 mb_cache_entry_delete(ea_inode_cache, hash, 1015 hash = ext4_xattr_inode_get_hash(ea_inode);
1013 ea_inode->i_ino); 1016 mb_cache_entry_delete(ea_inode_cache, hash,
1017 ea_inode->i_ino);
1018 }
1014 } 1019 }
1015 } 1020 }
1016 1021
@@ -1194,7 +1199,9 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
1194 * This must happen under buffer lock for 1199 * This must happen under buffer lock for
1195 * ext4_xattr_block_set() to reliably detect freed block 1200 * ext4_xattr_block_set() to reliably detect freed block
1196 */ 1201 */
1197 mb_cache_entry_delete(ea_block_cache, hash, bh->b_blocknr); 1202 if (ea_block_cache)
1203 mb_cache_entry_delete(ea_block_cache, hash,
1204 bh->b_blocknr);
1198 get_bh(bh); 1205 get_bh(bh);
1199 unlock_buffer(bh); 1206 unlock_buffer(bh);
1200 1207
@@ -1214,11 +1221,13 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
1214 if (ref == EXT4_XATTR_REFCOUNT_MAX - 1) { 1221 if (ref == EXT4_XATTR_REFCOUNT_MAX - 1) {
1215 struct mb_cache_entry *ce; 1222 struct mb_cache_entry *ce;
1216 1223
1217 ce = mb_cache_entry_get(ea_block_cache, hash, 1224 if (ea_block_cache) {
1218 bh->b_blocknr); 1225 ce = mb_cache_entry_get(ea_block_cache, hash,
1219 if (ce) { 1226 bh->b_blocknr);
1220 ce->e_reusable = 1; 1227 if (ce) {
1221 mb_cache_entry_put(ea_block_cache, ce); 1228 ce->e_reusable = 1;
1229 mb_cache_entry_put(ea_block_cache, ce);
1230 }
1222 } 1231 }
1223 } 1232 }
1224 1233
@@ -1395,6 +1404,9 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value,
1395 struct mb_cache *ea_inode_cache = EA_INODE_CACHE(inode); 1404 struct mb_cache *ea_inode_cache = EA_INODE_CACHE(inode);
1396 void *ea_data; 1405 void *ea_data;
1397 1406
1407 if (!ea_inode_cache)
1408 return NULL;
1409
1398 ce = mb_cache_entry_find_first(ea_inode_cache, hash); 1410 ce = mb_cache_entry_find_first(ea_inode_cache, hash);
1399 if (!ce) 1411 if (!ce)
1400 return NULL; 1412 return NULL;
@@ -1465,8 +1477,9 @@ static int ext4_xattr_inode_lookup_create(handle_t *handle, struct inode *inode,
1465 return err; 1477 return err;
1466 } 1478 }
1467 1479
1468 mb_cache_entry_create(EA_INODE_CACHE(inode), GFP_NOFS, hash, 1480 if (EA_INODE_CACHE(inode))
1469 ea_inode->i_ino, true /* reusable */); 1481 mb_cache_entry_create(EA_INODE_CACHE(inode), GFP_NOFS, hash,
1482 ea_inode->i_ino, true /* reusable */);
1470 1483
1471 *ret_inode = ea_inode; 1484 *ret_inode = ea_inode;
1472 return 0; 1485 return 0;
@@ -1793,8 +1806,9 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
1793 * ext4_xattr_block_set() to reliably detect modified 1806 * ext4_xattr_block_set() to reliably detect modified
1794 * block 1807 * block
1795 */ 1808 */
1796 mb_cache_entry_delete(ea_block_cache, hash, 1809 if (ea_block_cache)
1797 bs->bh->b_blocknr); 1810 mb_cache_entry_delete(ea_block_cache, hash,
1811 bs->bh->b_blocknr);
1798 ea_bdebug(bs->bh, "modifying in-place"); 1812 ea_bdebug(bs->bh, "modifying in-place");
1799 error = ext4_xattr_set_entry(i, s, handle, inode, 1813 error = ext4_xattr_set_entry(i, s, handle, inode,
1800 true /* is_block */); 1814 true /* is_block */);
@@ -2883,6 +2897,8 @@ ext4_xattr_block_cache_insert(struct mb_cache *ea_block_cache,
2883 EXT4_XATTR_REFCOUNT_MAX; 2897 EXT4_XATTR_REFCOUNT_MAX;
2884 int error; 2898 int error;
2885 2899
2900 if (!ea_block_cache)
2901 return;
2886 error = mb_cache_entry_create(ea_block_cache, GFP_NOFS, hash, 2902 error = mb_cache_entry_create(ea_block_cache, GFP_NOFS, hash,
2887 bh->b_blocknr, reusable); 2903 bh->b_blocknr, reusable);
2888 if (error) { 2904 if (error) {
@@ -2949,6 +2965,8 @@ ext4_xattr_block_cache_find(struct inode *inode,
2949 struct mb_cache_entry *ce; 2965 struct mb_cache_entry *ce;
2950 struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode); 2966 struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode);
2951 2967
2968 if (!ea_block_cache)
2969 return NULL;
2952 if (!header->h_hash) 2970 if (!header->h_hash)
2953 return NULL; /* never share */ 2971 return NULL; /* never share */
2954 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); 2972 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);