Skip to content

Commit bc32a63

Browse files
committed
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: "The first two changes involve files outside of fs/ext4: - submit_bh() can never return an error, so change it to return void, and remove the unused checks from its callers - fix I_DIRTY_TIME handling so it will be set even if the inode already has I_DIRTY_INODE Performance: - Always enable i_version counter (as btrfs and xfs already do). Remove some uneeded i_version bumps to avoid unnecessary nfs cache invalidations - Wake up journal waiters in FIFO order, to avoid some journal users from not getting a journal handle for an unfairly long time - In ext4_write_begin() allocate any necessary buffer heads before starting the journal handle - Don't try to prefetch the block allocation bitmaps for a read-only file system Bug Fixes: - Fix a number of fast commit bugs, including resources leaks and out of bound references in various error handling paths and/or if the fast commit log is corrupted - Avoid stopping the online resize early when expanding a file system which is less than 16TiB to a size greater than 16TiB - Fix apparent metadata corruption caused by a race with a metadata buffer head getting migrated while it was trying to be read - Mark the lazy initialization thread freezable to prevent suspend failures - Other miscellaneous bug fixes Cleanups: - Break up the incredibly long ext4_full_super() function by refactoring to move code into more understandable, smaller functions - Remove the deprecated (and ignored) noacl and nouser_attr mount option - Factor out some common code in fast commit handling - Other miscellaneous cleanups" * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (53 commits) ext4: fix potential out of bound read in ext4_fc_replay_scan() ext4: factor out ext4_fc_get_tl() ext4: introduce EXT4_FC_TAG_BASE_LEN helper ext4: factor out ext4_free_ext_path() ext4: remove unnecessary drop path references in mext_check_coverage() ext4: update 'state->fc_regions_size' after successful memory allocation ext4: fix potential memory leak in ext4_fc_record_regions() ext4: fix potential memory leak in ext4_fc_record_modified_inode() ext4: remove redundant checking in ext4_ioctl_checkpoint jbd2: add miss release buffer head in fc_do_one_pass() ext4: move DIOREAD_NOLOCK setting to ext4_set_def_opts() ext4: remove useless local variable 'blocksize' ext4: unify the ext4 super block loading operation ext4: factor out ext4_journal_data_mode_check() ext4: factor out ext4_load_and_init_journal() ext4: factor out ext4_group_desc_init() and ext4_group_desc_free() ext4: factor out ext4_geometry_check() ext4: factor out ext4_check_feature_compatibility() ext4: factor out ext4_init_metadata_csum() ext4: factor out ext4_encoding_init() ...
2 parents 7f198ba + 1b45cc5 commit bc32a63

27 files changed

+998
-811
lines changed

Documentation/filesystems/vfs.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ or bottom half).
274274
This is specifically for the inode itself being marked dirty,
275275
not its data. If the update needs to be persisted by fdatasync(),
276276
then I_DIRTY_DATASYNC will be set in the flags argument.
277+
I_DIRTY_TIME will be set in the flags in case lazytime is enabled
278+
and struct inode has times updated since the last ->dirty_inode
279+
call.
277280

278281
``write_inode``
279282
this method is called when the VFS needs to write an inode to

fs/buffer.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
#include "internal.h"
5353

5454
static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
55-
static int submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
56-
struct writeback_control *wbc);
55+
static void submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
56+
struct writeback_control *wbc);
5757

5858
#define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers)
5959

@@ -2673,8 +2673,8 @@ static void end_bio_bh_io_sync(struct bio *bio)
26732673
bio_put(bio);
26742674
}
26752675

2676-
static int submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
2677-
struct writeback_control *wbc)
2676+
static void submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
2677+
struct writeback_control *wbc)
26782678
{
26792679
const enum req_op op = opf & REQ_OP_MASK;
26802680
struct bio *bio;
@@ -2717,12 +2717,11 @@ static int submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
27172717
}
27182718

27192719
submit_bio(bio);
2720-
return 0;
27212720
}
27222721

2723-
int submit_bh(blk_opf_t opf, struct buffer_head *bh)
2722+
void submit_bh(blk_opf_t opf, struct buffer_head *bh)
27242723
{
2725-
return submit_bh_wbc(opf, bh, NULL);
2724+
submit_bh_wbc(opf, bh, NULL);
27262725
}
27272726
EXPORT_SYMBOL(submit_bh);
27282727

@@ -2801,8 +2800,6 @@ EXPORT_SYMBOL(write_dirty_buffer);
28012800
*/
28022801
int __sync_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags)
28032802
{
2804-
int ret = 0;
2805-
28062803
WARN_ON(atomic_read(&bh->b_count) < 1);
28072804
lock_buffer(bh);
28082805
if (test_clear_buffer_dirty(bh)) {
@@ -2817,14 +2814,14 @@ int __sync_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags)
28172814

28182815
get_bh(bh);
28192816
bh->b_end_io = end_buffer_write_sync;
2820-
ret = submit_bh(REQ_OP_WRITE | op_flags, bh);
2817+
submit_bh(REQ_OP_WRITE | op_flags, bh);
28212818
wait_on_buffer(bh);
2822-
if (!ret && !buffer_uptodate(bh))
2823-
ret = -EIO;
2819+
if (!buffer_uptodate(bh))
2820+
return -EIO;
28242821
} else {
28252822
unlock_buffer(bh);
28262823
}
2827-
return ret;
2824+
return 0;
28282825
}
28292826
EXPORT_SYMBOL(__sync_dirty_buffer);
28302827

fs/ext4/ext4.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3592,9 +3592,6 @@ extern bool empty_inline_dir(struct inode *dir, int *has_inline_data);
35923592
extern struct buffer_head *ext4_get_first_inline_block(struct inode *inode,
35933593
struct ext4_dir_entry_2 **parent_de,
35943594
int *retval);
3595-
extern int ext4_inline_data_fiemap(struct inode *inode,
3596-
struct fiemap_extent_info *fieinfo,
3597-
int *has_inline, __u64 start, __u64 len);
35983595
extern void *ext4_read_inline_link(struct inode *inode);
35993596

36003597
struct iomap;
@@ -3713,7 +3710,7 @@ extern int ext4_ext_insert_extent(handle_t *, struct inode *,
37133710
extern struct ext4_ext_path *ext4_find_extent(struct inode *, ext4_lblk_t,
37143711
struct ext4_ext_path **,
37153712
int flags);
3716-
extern void ext4_ext_drop_refs(struct ext4_ext_path *);
3713+
extern void ext4_free_ext_path(struct ext4_ext_path *);
37173714
extern int ext4_ext_check_inode(struct inode *inode);
37183715
extern ext4_lblk_t ext4_ext_next_allocated_block(struct ext4_ext_path *path);
37193716
extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,

fs/ext4/extents.c

Lines changed: 44 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,25 @@ static int ext4_ext_trunc_restart_fn(struct inode *inode, int *dropped)
106106
return 0;
107107
}
108108

109+
static void ext4_ext_drop_refs(struct ext4_ext_path *path)
110+
{
111+
int depth, i;
112+
113+
if (!path)
114+
return;
115+
depth = path->p_depth;
116+
for (i = 0; i <= depth; i++, path++) {
117+
brelse(path->p_bh);
118+
path->p_bh = NULL;
119+
}
120+
}
121+
122+
void ext4_free_ext_path(struct ext4_ext_path *path)
123+
{
124+
ext4_ext_drop_refs(path);
125+
kfree(path);
126+
}
127+
109128
/*
110129
* Make sure 'handle' has at least 'check_cred' credits. If not, restart
111130
* transaction with 'restart_cred' credits. The function drops i_data_sem
@@ -636,8 +655,7 @@ int ext4_ext_precache(struct inode *inode)
636655
ext4_set_inode_state(inode, EXT4_STATE_EXT_PRECACHED);
637656
out:
638657
up_read(&ei->i_data_sem);
639-
ext4_ext_drop_refs(path);
640-
kfree(path);
658+
ext4_free_ext_path(path);
641659
return ret;
642660
}
643661

@@ -724,19 +742,6 @@ static void ext4_ext_show_move(struct inode *inode, struct ext4_ext_path *path,
724742
#define ext4_ext_show_move(inode, path, newblock, level)
725743
#endif
726744

727-
void ext4_ext_drop_refs(struct ext4_ext_path *path)
728-
{
729-
int depth, i;
730-
731-
if (!path)
732-
return;
733-
depth = path->p_depth;
734-
for (i = 0; i <= depth; i++, path++) {
735-
brelse(path->p_bh);
736-
path->p_bh = NULL;
737-
}
738-
}
739-
740745
/*
741746
* ext4_ext_binsearch_idx:
742747
* binary search for the closest index of the given block
@@ -955,8 +960,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
955960
return path;
956961

957962
err:
958-
ext4_ext_drop_refs(path);
959-
kfree(path);
963+
ext4_free_ext_path(path);
960964
if (orig_path)
961965
*orig_path = NULL;
962966
return ERR_PTR(ret);
@@ -2174,8 +2178,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
21742178
err = ext4_ext_dirty(handle, inode, path + path->p_depth);
21752179

21762180
cleanup:
2177-
ext4_ext_drop_refs(npath);
2178-
kfree(npath);
2181+
ext4_free_ext_path(npath);
21792182
return err;
21802183
}
21812184

@@ -3061,8 +3064,7 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
30613064
}
30623065
}
30633066
out:
3064-
ext4_ext_drop_refs(path);
3065-
kfree(path);
3067+
ext4_free_ext_path(path);
30663068
path = NULL;
30673069
if (err == -EAGAIN)
30683070
goto again;
@@ -4375,8 +4377,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
43754377
allocated = map->m_len;
43764378
ext4_ext_show_leaf(inode, path);
43774379
out:
4378-
ext4_ext_drop_refs(path);
4379-
kfree(path);
4380+
ext4_free_ext_path(path);
43804381

43814382
trace_ext4_ext_map_blocks_exit(inode, flags, map,
43824383
err ? err : allocated);
@@ -5245,8 +5246,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
52455246
break;
52465247
}
52475248
out:
5248-
ext4_ext_drop_refs(path);
5249-
kfree(path);
5249+
ext4_free_ext_path(path);
52505250
return ret;
52515251
}
52525252

@@ -5538,15 +5538,13 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
55385538
EXT4_GET_BLOCKS_METADATA_NOFAIL);
55395539
}
55405540

5541-
ext4_ext_drop_refs(path);
5542-
kfree(path);
5541+
ext4_free_ext_path(path);
55435542
if (ret < 0) {
55445543
up_write(&EXT4_I(inode)->i_data_sem);
55455544
goto out_stop;
55465545
}
55475546
} else {
5548-
ext4_ext_drop_refs(path);
5549-
kfree(path);
5547+
ext4_free_ext_path(path);
55505548
}
55515549

55525550
ret = ext4_es_remove_extent(inode, offset_lblk,
@@ -5766,10 +5764,8 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
57665764
count -= len;
57675765

57685766
repeat:
5769-
ext4_ext_drop_refs(path1);
5770-
kfree(path1);
5771-
ext4_ext_drop_refs(path2);
5772-
kfree(path2);
5767+
ext4_free_ext_path(path1);
5768+
ext4_free_ext_path(path2);
57735769
path1 = path2 = NULL;
57745770
}
57755771
return replaced_count;
@@ -5848,8 +5844,7 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
58485844
}
58495845

58505846
out:
5851-
ext4_ext_drop_refs(path);
5852-
kfree(path);
5847+
ext4_free_ext_path(path);
58535848

58545849
return err ? err : mapped;
58555850
}
@@ -5916,8 +5911,7 @@ int ext4_ext_replay_update_ex(struct inode *inode, ext4_lblk_t start,
59165911
ret = ext4_ext_dirty(NULL, inode, &path[path->p_depth]);
59175912
up_write(&EXT4_I(inode)->i_data_sem);
59185913
out:
5919-
ext4_ext_drop_refs(path);
5920-
kfree(path);
5914+
ext4_free_ext_path(path);
59215915
ext4_mark_inode_dirty(NULL, inode);
59225916
return ret;
59235917
}
@@ -5935,8 +5929,7 @@ void ext4_ext_replay_shrink_inode(struct inode *inode, ext4_lblk_t end)
59355929
return;
59365930
ex = path[path->p_depth].p_ext;
59375931
if (!ex) {
5938-
ext4_ext_drop_refs(path);
5939-
kfree(path);
5932+
ext4_free_ext_path(path);
59405933
ext4_mark_inode_dirty(NULL, inode);
59415934
return;
59425935
}
@@ -5949,8 +5942,7 @@ void ext4_ext_replay_shrink_inode(struct inode *inode, ext4_lblk_t end)
59495942
ext4_ext_dirty(NULL, inode, &path[path->p_depth]);
59505943
up_write(&EXT4_I(inode)->i_data_sem);
59515944
ext4_mark_inode_dirty(NULL, inode);
5952-
ext4_ext_drop_refs(path);
5953-
kfree(path);
5945+
ext4_free_ext_path(path);
59545946
}
59555947
}
59565948

@@ -5989,13 +5981,11 @@ int ext4_ext_replay_set_iblocks(struct inode *inode)
59895981
return PTR_ERR(path);
59905982
ex = path[path->p_depth].p_ext;
59915983
if (!ex) {
5992-
ext4_ext_drop_refs(path);
5993-
kfree(path);
5984+
ext4_free_ext_path(path);
59945985
goto out;
59955986
}
59965987
end = le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex);
5997-
ext4_ext_drop_refs(path);
5998-
kfree(path);
5988+
ext4_free_ext_path(path);
59995989

60005990
/* Count the number of data blocks */
60015991
cur = 0;
@@ -6025,30 +6015,26 @@ int ext4_ext_replay_set_iblocks(struct inode *inode)
60256015
if (IS_ERR(path))
60266016
goto out;
60276017
numblks += path->p_depth;
6028-
ext4_ext_drop_refs(path);
6029-
kfree(path);
6018+
ext4_free_ext_path(path);
60306019
while (cur < end) {
60316020
path = ext4_find_extent(inode, cur, NULL, 0);
60326021
if (IS_ERR(path))
60336022
break;
60346023
ex = path[path->p_depth].p_ext;
60356024
if (!ex) {
6036-
ext4_ext_drop_refs(path);
6037-
kfree(path);
6025+
ext4_free_ext_path(path);
60386026
return 0;
60396027
}
60406028
cur = max(cur + 1, le32_to_cpu(ex->ee_block) +
60416029
ext4_ext_get_actual_len(ex));
60426030
ret = skip_hole(inode, &cur);
60436031
if (ret < 0) {
6044-
ext4_ext_drop_refs(path);
6045-
kfree(path);
6032+
ext4_free_ext_path(path);
60466033
break;
60476034
}
60486035
path2 = ext4_find_extent(inode, cur, NULL, 0);
60496036
if (IS_ERR(path2)) {
6050-
ext4_ext_drop_refs(path);
6051-
kfree(path);
6037+
ext4_free_ext_path(path);
60526038
break;
60536039
}
60546040
for (i = 0; i <= max(path->p_depth, path2->p_depth); i++) {
@@ -6062,10 +6048,8 @@ int ext4_ext_replay_set_iblocks(struct inode *inode)
60626048
if (cmp1 != cmp2 && cmp2 != 0)
60636049
numblks++;
60646050
}
6065-
ext4_ext_drop_refs(path);
6066-
ext4_ext_drop_refs(path2);
6067-
kfree(path);
6068-
kfree(path2);
6051+
ext4_free_ext_path(path);
6052+
ext4_free_ext_path(path2);
60696053
}
60706054

60716055
out:
@@ -6092,13 +6076,11 @@ int ext4_ext_clear_bb(struct inode *inode)
60926076
return PTR_ERR(path);
60936077
ex = path[path->p_depth].p_ext;
60946078
if (!ex) {
6095-
ext4_ext_drop_refs(path);
6096-
kfree(path);
6079+
ext4_free_ext_path(path);
60976080
return 0;
60986081
}
60996082
end = le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex);
6100-
ext4_ext_drop_refs(path);
6101-
kfree(path);
6083+
ext4_free_ext_path(path);
61026084

61036085
cur = 0;
61046086
while (cur < end) {
@@ -6117,8 +6099,7 @@ int ext4_ext_clear_bb(struct inode *inode)
61176099
ext4_fc_record_regions(inode->i_sb, inode->i_ino,
61186100
0, path[j].p_block, 1, 1);
61196101
}
6120-
ext4_ext_drop_refs(path);
6121-
kfree(path);
6102+
ext4_free_ext_path(path);
61226103
}
61236104
ext4_mb_mark_bb(inode->i_sb, map.m_pblk, map.m_len, 0);
61246105
ext4_fc_record_regions(inode->i_sb, inode->i_ino,

fs/ext4/extents_status.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,8 +667,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
667667
}
668668
}
669669
out:
670-
ext4_ext_drop_refs(path);
671-
kfree(path);
670+
ext4_free_ext_path(path);
672671
}
673672

674673
static void ext4_es_insert_extent_ind_check(struct inode *inode,

0 commit comments

Comments
 (0)