Skip to content

Commit 3e7447a

Browse files
committed
Merge tag 'ext4_for_linus-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: "A lot of miscellaneous ext4 bug fixes and cleanups this cycle, most notably in the journaling code, bufered I/O, and compiler warning cleanups" * tag 'ext4_for_linus-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (33 commits) jbd2: Fix comment describing journal_init_common() ext4: prevent an infinite loop in the lazyinit thread ext4: use struct_size() to improve ext4_htree_store_dirent() ext4: annotate struct fname with __counted_by() jbd2: avoid dozens of -Wflex-array-member-not-at-end warnings ext4: use str_yes_no() helper function ext4: prevent delalloc to nodelalloc on remount jbd2: make b_frozen_data allocation always succeed ext4: cleanup variable name in ext4_fc_del() ext4: use string choices helpers jbd2: remove the 'success' parameter from the jbd2_do_replay() function jbd2: remove useless 'block_error' variable jbd2: factor out jbd2_do_replay() jbd2: refactor JBD2_COMMIT_BLOCK process in do_one_pass() jbd2: unified release of buffer_head in do_one_pass() jbd2: remove redundant judgments for check v1 checksum ext4: use ERR_CAST to return an error-valued pointer mm: zero range of eof folio exposed by inode size extension ext4: partial zero eof block on unaligned inode size extension ext4: disambiguate the return value of ext4_dio_write_end_io() ...
2 parents c6d6447 + 3e7c69c commit 3e7447a

25 files changed

+402
-287
lines changed

fs/ext4/balloc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,8 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group,
550550
trace_ext4_read_block_bitmap_load(sb, block_group, ignore_locked);
551551
ext4_read_bh_nowait(bh, REQ_META | REQ_PRIO |
552552
(ignore_locked ? REQ_RAHEAD : 0),
553-
ext4_end_bitmap_read);
553+
ext4_end_bitmap_read,
554+
ext4_simulate_fail(sb, EXT4_SIM_BBITMAP_EIO));
554555
return bh;
555556
verify:
556557
err = ext4_validate_block_bitmap(sb, desc, block_group, bh);
@@ -577,7 +578,6 @@ int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group,
577578
if (!desc)
578579
return -EFSCORRUPTED;
579580
wait_on_buffer(bh);
580-
ext4_simulate_fail_bh(sb, bh, EXT4_SIM_BBITMAP_EIO);
581581
if (!buffer_uptodate(bh)) {
582582
ext4_error_err(sb, EIO, "Cannot read block bitmap - "
583583
"block_group = %u, block_bitmap = %llu",

fs/ext4/dir.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ struct fname {
418418
__u32 inode;
419419
__u8 name_len;
420420
__u8 file_type;
421-
char name[];
421+
char name[] __counted_by(name_len);
422422
};
423423

424424
/*
@@ -471,14 +471,13 @@ int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
471471
struct rb_node **p, *parent = NULL;
472472
struct fname *fname, *new_fn;
473473
struct dir_private_info *info;
474-
int len;
475474

476475
info = dir_file->private_data;
477476
p = &info->root.rb_node;
478477

479478
/* Create and allocate the fname structure */
480-
len = sizeof(struct fname) + ent_name->len + 1;
481-
new_fn = kzalloc(len, GFP_KERNEL);
479+
new_fn = kzalloc(struct_size(new_fn, name, ent_name->len + 1),
480+
GFP_KERNEL);
482481
if (!new_fn)
483482
return -ENOMEM;
484483
new_fn->hash = hash;

fs/ext4/ext4.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,14 +1869,6 @@ static inline bool ext4_simulate_fail(struct super_block *sb,
18691869
return false;
18701870
}
18711871

1872-
static inline void ext4_simulate_fail_bh(struct super_block *sb,
1873-
struct buffer_head *bh,
1874-
unsigned long code)
1875-
{
1876-
if (!IS_ERR(bh) && ext4_simulate_fail(sb, code))
1877-
clear_buffer_uptodate(bh);
1878-
}
1879-
18801872
/*
18811873
* Error number codes for s_{first,last}_error_errno
18821874
*
@@ -3104,9 +3096,9 @@ extern struct buffer_head *ext4_sb_bread(struct super_block *sb,
31043096
extern struct buffer_head *ext4_sb_bread_unmovable(struct super_block *sb,
31053097
sector_t block);
31063098
extern void ext4_read_bh_nowait(struct buffer_head *bh, blk_opf_t op_flags,
3107-
bh_end_io_t *end_io);
3099+
bh_end_io_t *end_io, bool simu_fail);
31083100
extern int ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags,
3109-
bh_end_io_t *end_io);
3101+
bh_end_io_t *end_io, bool simu_fail);
31103102
extern int ext4_read_bh_lock(struct buffer_head *bh, blk_opf_t op_flags, bool wait);
31113103
extern void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block);
31123104
extern int ext4_seq_options_show(struct seq_file *seq, void *offset);

fs/ext4/extents.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ __read_extent_tree_block(const char *function, unsigned int line,
568568

569569
if (!bh_uptodate_or_lock(bh)) {
570570
trace_ext4_ext_load_extent(inode, pblk, _RET_IP_);
571-
err = ext4_read_bh(bh, 0, NULL);
571+
err = ext4_read_bh(bh, 0, NULL, false);
572572
if (err < 0)
573573
goto errout;
574574
}
@@ -3138,7 +3138,7 @@ static void ext4_zeroout_es(struct inode *inode, struct ext4_extent *ex)
31383138
return;
31393139

31403140
ext4_es_insert_extent(inode, ee_block, ee_len, ee_pblock,
3141-
EXTENT_STATUS_WRITTEN, 0);
3141+
EXTENT_STATUS_WRITTEN, false);
31423142
}
31433143

31443144
/* FIXME!! we need to try to merge to left or right after zero-out */
@@ -4158,7 +4158,7 @@ static ext4_lblk_t ext4_ext_determine_insert_hole(struct inode *inode,
41584158
/* Put just found gap into cache to speed up subsequent requests */
41594159
ext_debug(inode, " -> %u:%u\n", hole_start, len);
41604160
ext4_es_insert_extent(inode, hole_start, len, ~0,
4161-
EXTENT_STATUS_HOLE, 0);
4161+
EXTENT_STATUS_HOLE, false);
41624162

41634163
/* Update hole_len to reflect hole size after lblk */
41644164
if (hole_start != lblk)
@@ -4482,7 +4482,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
44824482
int depth = 0;
44834483
struct ext4_map_blocks map;
44844484
unsigned int credits;
4485-
loff_t epos;
4485+
loff_t epos, old_size = i_size_read(inode);
44864486

44874487
BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS));
44884488
map.m_lblk = offset;
@@ -4541,6 +4541,11 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
45414541
if (ext4_update_inode_size(inode, epos) & 0x1)
45424542
inode_set_mtime_to_ts(inode,
45434543
inode_get_ctime(inode));
4544+
if (epos > old_size) {
4545+
pagecache_isize_extended(inode, old_size, epos);
4546+
ext4_zero_partial_blocks(handle, inode,
4547+
old_size, epos - old_size);
4548+
}
45444549
}
45454550
ret2 = ext4_mark_inode_dirty(handle, inode);
45464551
ext4_update_inode_fsync_trans(handle, inode, 1);

fs/ext4/extents_status.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ static int __es_insert_extent(struct inode *inode, struct extent_status *newes,
848848
*/
849849
void ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
850850
ext4_lblk_t len, ext4_fsblk_t pblk,
851-
unsigned int status, int flags)
851+
unsigned int status, bool delalloc_reserve_used)
852852
{
853853
struct extent_status newes;
854854
ext4_lblk_t end = lblk + len - 1;
@@ -863,8 +863,8 @@ void ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
863863
if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
864864
return;
865865

866-
es_debug("add [%u/%u) %llu %x %x to extent status tree of inode %lu\n",
867-
lblk, len, pblk, status, flags, inode->i_ino);
866+
es_debug("add [%u/%u) %llu %x %d to extent status tree of inode %lu\n",
867+
lblk, len, pblk, status, delalloc_reserve_used, inode->i_ino);
868868

869869
if (!len)
870870
return;
@@ -945,7 +945,7 @@ void ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
945945
resv_used += pending;
946946
if (resv_used)
947947
ext4_da_update_reserve_space(inode, resv_used,
948-
flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE);
948+
delalloc_reserve_used);
949949

950950
if (err1 || err2 || err3 < 0)
951951
goto retry;

fs/ext4/extents_status.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ extern void ext4_es_init_tree(struct ext4_es_tree *tree);
135135

136136
extern void ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
137137
ext4_lblk_t len, ext4_fsblk_t pblk,
138-
unsigned int status, int flags);
138+
unsigned int status,
139+
bool delalloc_reserve_used);
139140
extern void ext4_es_cache_extent(struct inode *inode, ext4_lblk_t lblk,
140141
ext4_lblk_t len, ext4_fsblk_t pblk,
141142
unsigned int status);

fs/ext4/fast_commit.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,9 @@ void ext4_fc_del(struct inode *inode)
291291
return;
292292

293293
restart:
294-
spin_lock(&EXT4_SB(inode->i_sb)->s_fc_lock);
294+
spin_lock(&sbi->s_fc_lock);
295295
if (list_empty(&ei->i_fc_list) && list_empty(&ei->i_fc_dilist)) {
296-
spin_unlock(&EXT4_SB(inode->i_sb)->s_fc_lock);
296+
spin_unlock(&sbi->s_fc_lock);
297297
return;
298298
}
299299

@@ -357,9 +357,7 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, handle_t *handl
357357
}
358358
spin_lock(&sbi->s_fc_lock);
359359
is_ineligible = ext4_test_mount_flag(sb, EXT4_MF_FC_INELIGIBLE);
360-
if (has_transaction &&
361-
(!is_ineligible ||
362-
(is_ineligible && tid_gt(tid, sbi->s_fc_ineligible_tid))))
360+
if (has_transaction && (!is_ineligible || tid_gt(tid, sbi->s_fc_ineligible_tid)))
363361
sbi->s_fc_ineligible_tid = tid;
364362
ext4_set_mount_flag(sb, EXT4_MF_FC_INELIGIBLE);
365363
spin_unlock(&sbi->s_fc_lock);

fs/ext4/file.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,9 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
392392
*/
393393
if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize) &&
394394
pos + size <= i_size_read(inode))
395-
return size;
396-
return ext4_handle_inode_extension(inode, pos, size, size);
395+
return 0;
396+
error = ext4_handle_inode_extension(inode, pos, size, size);
397+
return error < 0 ? error : 0;
397398
}
398399

399400
static const struct iomap_dio_ops ext4_dio_write_ops = {
@@ -564,12 +565,9 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
564565
}
565566

566567
ret = ext4_orphan_add(handle, inode);
567-
if (ret) {
568-
ext4_journal_stop(handle);
569-
goto out;
570-
}
571-
572568
ext4_journal_stop(handle);
569+
if (ret)
570+
goto out;
573571
}
574572

575573
if (ilock_shared && !unwritten)

fs/ext4/fsmap.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,56 @@ static inline ext4_fsblk_t ext4_fsmap_next_pblk(struct ext4_fsmap *fmr)
185185
return fmr->fmr_physical + fmr->fmr_length;
186186
}
187187

188+
static int ext4_getfsmap_meta_helper(struct super_block *sb,
189+
ext4_group_t agno, ext4_grpblk_t start,
190+
ext4_grpblk_t len, void *priv)
191+
{
192+
struct ext4_getfsmap_info *info = priv;
193+
struct ext4_fsmap *p;
194+
struct ext4_fsmap *tmp;
195+
struct ext4_sb_info *sbi = EXT4_SB(sb);
196+
ext4_fsblk_t fsb, fs_start, fs_end;
197+
int error;
198+
199+
fs_start = fsb = (EXT4_C2B(sbi, start) +
200+
ext4_group_first_block_no(sb, agno));
201+
fs_end = fs_start + EXT4_C2B(sbi, len);
202+
203+
/* Return relevant extents from the meta_list */
204+
list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) {
205+
if (p->fmr_physical < info->gfi_next_fsblk) {
206+
list_del(&p->fmr_list);
207+
kfree(p);
208+
continue;
209+
}
210+
if (p->fmr_physical <= fs_start ||
211+
p->fmr_physical + p->fmr_length <= fs_end) {
212+
/* Emit the retained free extent record if present */
213+
if (info->gfi_lastfree.fmr_owner) {
214+
error = ext4_getfsmap_helper(sb, info,
215+
&info->gfi_lastfree);
216+
if (error)
217+
return error;
218+
info->gfi_lastfree.fmr_owner = 0;
219+
}
220+
error = ext4_getfsmap_helper(sb, info, p);
221+
if (error)
222+
return error;
223+
fsb = p->fmr_physical + p->fmr_length;
224+
if (info->gfi_next_fsblk < fsb)
225+
info->gfi_next_fsblk = fsb;
226+
list_del(&p->fmr_list);
227+
kfree(p);
228+
continue;
229+
}
230+
}
231+
if (info->gfi_next_fsblk < fsb)
232+
info->gfi_next_fsblk = fsb;
233+
234+
return 0;
235+
}
236+
237+
188238
/* Transform a blockgroup's free record into a fsmap */
189239
static int ext4_getfsmap_datadev_helper(struct super_block *sb,
190240
ext4_group_t agno, ext4_grpblk_t start,
@@ -539,6 +589,7 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
539589
error = ext4_mballoc_query_range(sb, info->gfi_agno,
540590
EXT4_B2C(sbi, info->gfi_low.fmr_physical),
541591
EXT4_B2C(sbi, info->gfi_high.fmr_physical),
592+
ext4_getfsmap_meta_helper,
542593
ext4_getfsmap_datadev_helper, info);
543594
if (error)
544595
goto err;
@@ -560,7 +611,8 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
560611

561612
/* Report any gaps at the end of the bg */
562613
info->gfi_last = true;
563-
error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster, 0, info);
614+
error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1,
615+
0, info);
564616
if (error)
565617
goto err;
566618

fs/ext4/ialloc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,9 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
193193
* submit the buffer_head for reading
194194
*/
195195
trace_ext4_load_inode_bitmap(sb, block_group);
196-
ext4_read_bh(bh, REQ_META | REQ_PRIO, ext4_end_bitmap_read);
197-
ext4_simulate_fail_bh(sb, bh, EXT4_SIM_IBITMAP_EIO);
196+
ext4_read_bh(bh, REQ_META | REQ_PRIO,
197+
ext4_end_bitmap_read,
198+
ext4_simulate_fail(sb, EXT4_SIM_IBITMAP_EIO));
198199
if (!buffer_uptodate(bh)) {
199200
put_bh(bh);
200201
ext4_error_err(sb, EIO, "Cannot read inode bitmap - "

0 commit comments

Comments
 (0)