On Sun, 11 Sep 2022 12:52:04 +0800, Zhihao Cheng wrote: > Following process may lead to fs corruption: > 1. ext4_create(dir/foo) > ext4_add_nondir > ext4_add_entry > ext4_dx_add_entry > a. add_dirent_to_buf > ext4_mark_inode_dirty > ext4_handle_dirty_metadata // dir inode bh is recorded into journal > b. ext4_append // dx_get_count(entries) == dx_get_limit(entries) > ext4_bread(EXT4_GET_BLOCKS_CREATE) > ext4_getblk > ext4_map_blocks > ext4_ext_map_blocks > ext4_mb_new_blocks > dquot_alloc_block > dquot_alloc_space_nodirty > inode_add_bytes // update dir's i_blocks > ext4_ext_insert_extent > ext4_ext_dirty // record extent bh into journal > ext4_handle_dirty_metadata(bh) > // record new block into journal > inode->i_size += inode->i_sb->s_blocksize // new size(in mem) > c. ext4_handle_dirty_dx_node(bh2) > // record dir's new block(dx_node) into journal > d. ext4_handle_dirty_dx_node((frame - 1)->bh) > e. ext4_handle_dirty_dx_node(frame->bh) > f. do_split // ret err! > g. add_dirent_to_buf > ext4_mark_inode_dirty(dir) // update raw_inode on disk(skipped) > 2. fsck -a /dev/sdb > drop last block(dx_node) which beyonds dir's i_size. > /dev/sdb: recovering journal > /dev/sdb contains a file system with errors, check forced. > /dev/sdb: Inode 12, end of extent exceeds allowed value > (logical block 128, physical block 3938, len 1) > 3. fsck -fn /dev/sdb > dx_node->entry[i].blk > dir->i_size > Pass 2: Checking directory structure > Problem in HTREE directory inode 12 (/dir): bad block number 128. > Clear HTree index? no > Problem in HTREE directory inode 12: block #3 has invalid depth (2) > Problem in HTREE directory inode 12: block #3 has bad max hash > Problem in HTREE directory inode 12: block #3 not referenced > > [...] Applied, thanks! [1/1] ext4: Fix dir corruption when ext4_dx_add_entry() fails commit: 7a3584fd605e6a72036c5759a6e9ed2c46d14899 Best regards, -- Theodore Ts'o <tytso@xxxxxxx>