diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 835109f054936b8448a6af1e357ec629acbba5b6..631bd9af197100dfa4f8827176393f381d2d9f78 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -502,7 +502,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, goto fallback; } - max_dirs = ndirs / ngroups + inodes_per_group / 16; + max_dirs = ndirs / ngroups + inodes_per_group*flex_size / 16; min_inodes = avefreei - inodes_per_group*flex_size / 4; if (min_inodes < 1) min_inodes = 1; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ce88148cdc4adcd5a33db5fa3714b98637ec43aa..51ce7006afba02134305899befa8ea4584df1c27 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1300,6 +1300,13 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; + /* + * The same as page allocation, we prealloc buffer heads before + * starting the handle. + */ + if (!page_has_buffers(page)) + create_empty_buffers(page, inode->i_sb->s_blocksize, 0); + unlock_page(page); retry_journal: diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 972611b721957837289f13dc608a2a6d9cb16c1c..e21d05e64bd1f8e9dc877afa75e4cb521b064250 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2841,11 +2841,8 @@ bool ext4_empty_dir(struct inode *inode) de = (struct ext4_dir_entry_2 *) (bh->b_data + (offset & (sb->s_blocksize - 1))); if (ext4_check_dir_entry(inode, NULL, de, bh, - bh->b_data, bh->b_size, offset)) { - offset = (offset | (sb->s_blocksize - 1)) + 1; - continue; - } - if (le32_to_cpu(de->inode)) { + bh->b_data, bh->b_size, offset) || + le32_to_cpu(de->inode)) { brelse(bh); return false; } diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index bc870561e3942f458f519a9fad73e25e2a01f147..6db398ef0a65bbab9a6513f5b85f367685cb840e 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -2084,7 +2084,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count) goto out; } - if (ext4_blocks_count(es) == n_blocks_count) + if (ext4_blocks_count(es) == n_blocks_count && n_blocks_count_retry == 0) goto out; err = ext4_alloc_flex_bg_array(sb, n_group + 1); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e4abf3de254f64c1c3ea1e44a16591e8d99649b1..31162458ce2c178e9d89b77bb6ddb3f45f5944a8 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3308,6 +3308,7 @@ static int ext4_lazyinit_thread(void *arg) unsigned long next_wakeup, cur; BUG_ON(NULL == eli); + set_freezable(); cont_thread: while (true) { @@ -6023,7 +6024,7 @@ static int ext4_write_info(struct super_block *sb, int type) handle_t *handle; /* Data block + inode block */ - handle = ext4_journal_start(d_inode(sb->s_root), EXT4_HT_QUOTA, 2); + handle = ext4_journal_start_sb(sb, EXT4_HT_QUOTA, 2); if (IS_ERR(handle)) return PTR_ERR(handle); ret = dquot_commit_info(sb, type);