Commit 4e032990 authored by Jan Kara's avatar Jan Kara Committed by Stefan Bader

ext2: convert to mbcache2

The conversion is generally straightforward. We convert filesystem from
a global cache to per-fs one. Similarly to ext4 the tricky part is that
xattr block corresponding to found mbcache entry can get freed before we
get buffer lock for that block. So we have to check whether the entry is
still valid after getting the buffer lock.
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
(cherry picked from commit be0726d3)
CVE-2015-8952
Signed-off-by: default avatarThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Acked-by: default avatarStefan Bader <stefan.bader@canonical.com>
Acked-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: default avatarThadeu Lima de Souza Cascardo <cascardo@canonical.com>
parent eddecb99
...@@ -61,6 +61,8 @@ struct ext2_block_alloc_info { ...@@ -61,6 +61,8 @@ struct ext2_block_alloc_info {
#define rsv_start rsv_window._rsv_start #define rsv_start rsv_window._rsv_start
#define rsv_end rsv_window._rsv_end #define rsv_end rsv_window._rsv_end
struct mb2_cache;
/* /*
* second extended-fs super-block data in memory * second extended-fs super-block data in memory
*/ */
...@@ -111,6 +113,7 @@ struct ext2_sb_info { ...@@ -111,6 +113,7 @@ struct ext2_sb_info {
* of the mount options. * of the mount options.
*/ */
spinlock_t s_lock; spinlock_t s_lock;
struct mb2_cache *s_mb_cache;
}; };
static inline spinlock_t * static inline spinlock_t *
......
...@@ -131,7 +131,10 @@ static void ext2_put_super (struct super_block * sb) ...@@ -131,7 +131,10 @@ static void ext2_put_super (struct super_block * sb)
dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
ext2_xattr_put_super(sb); if (sbi->s_mb_cache) {
ext2_xattr_destroy_cache(sbi->s_mb_cache);
sbi->s_mb_cache = NULL;
}
if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->s_flags & MS_RDONLY)) {
struct ext2_super_block *es = sbi->s_es; struct ext2_super_block *es = sbi->s_es;
...@@ -1104,6 +1107,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1104,6 +1107,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
ext2_msg(sb, KERN_ERR, "error: insufficient memory"); ext2_msg(sb, KERN_ERR, "error: insufficient memory");
goto failed_mount3; goto failed_mount3;
} }
#ifdef CONFIG_EXT2_FS_XATTR
sbi->s_mb_cache = ext2_xattr_create_cache();
if (!sbi->s_mb_cache) {
ext2_msg(sb, KERN_ERR, "Failed to create an mb_cache");
goto failed_mount3;
}
#endif
/* /*
* set up enough so that it can read an inode * set up enough so that it can read an inode
*/ */
...@@ -1149,6 +1160,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1149,6 +1160,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
sb->s_id); sb->s_id);
goto failed_mount; goto failed_mount;
failed_mount3: failed_mount3:
if (sbi->s_mb_cache)
ext2_xattr_destroy_cache(sbi->s_mb_cache);
percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter); percpu_counter_destroy(&sbi->s_dirs_counter);
...@@ -1555,20 +1568,17 @@ MODULE_ALIAS_FS("ext2"); ...@@ -1555,20 +1568,17 @@ MODULE_ALIAS_FS("ext2");
static int __init init_ext2_fs(void) static int __init init_ext2_fs(void)
{ {
int err = init_ext2_xattr(); int err;
if (err)
return err;
err = init_inodecache(); err = init_inodecache();
if (err) if (err)
goto out1; return err;
err = register_filesystem(&ext2_fs_type); err = register_filesystem(&ext2_fs_type);
if (err) if (err)
goto out; goto out;
return 0; return 0;
out: out:
destroy_inodecache(); destroy_inodecache();
out1:
exit_ext2_xattr();
return err; return err;
} }
...@@ -1576,7 +1586,6 @@ static void __exit exit_ext2_fs(void) ...@@ -1576,7 +1586,6 @@ static void __exit exit_ext2_fs(void)
{ {
unregister_filesystem(&ext2_fs_type); unregister_filesystem(&ext2_fs_type);
destroy_inodecache(); destroy_inodecache();
exit_ext2_xattr();
} }
MODULE_AUTHOR("Remy Card and others"); MODULE_AUTHOR("Remy Card and others");
......
This diff is collapsed.
...@@ -53,6 +53,8 @@ struct ext2_xattr_entry { ...@@ -53,6 +53,8 @@ struct ext2_xattr_entry {
#define EXT2_XATTR_SIZE(size) \ #define EXT2_XATTR_SIZE(size) \
(((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND) (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
struct mb2_cache;
# ifdef CONFIG_EXT2_FS_XATTR # ifdef CONFIG_EXT2_FS_XATTR
extern const struct xattr_handler ext2_xattr_user_handler; extern 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); ...@@ -65,10 +67,9 @@ extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int); extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
extern void ext2_xattr_delete_inode(struct inode *); extern void ext2_xattr_delete_inode(struct inode *);
extern void ext2_xattr_put_super(struct super_block *);
extern int init_ext2_xattr(void); extern struct mb2_cache *ext2_xattr_create_cache(void);
extern void exit_ext2_xattr(void); extern void ext2_xattr_destroy_cache(struct mb2_cache *cache);
extern const struct xattr_handler *ext2_xattr_handlers[]; extern const struct xattr_handler *ext2_xattr_handlers[];
...@@ -93,19 +94,7 @@ ext2_xattr_delete_inode(struct inode *inode) ...@@ -93,19 +94,7 @@ ext2_xattr_delete_inode(struct inode *inode)
{ {
} }
static inline void static inline void ext2_xattr_destroy_cache(struct mb2_cache *cache)
ext2_xattr_put_super(struct super_block *sb)
{
}
static inline int
init_ext2_xattr(void)
{
return 0;
}
static inline void
exit_ext2_xattr(void)
{ {
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment