Any write operation on an existing inline data regular file now triggers immediate conversion to block-based storage instead of writing inline. Remove ext4_try_to_write_inline_data() and have its caller directly call ext4_convert_inline_data(). ext4_generic_write_inline_data() converts immediately for the non-DA path. Directory inline data operations (ext4_try_add_inline_entry) are preserved as directories benefit most from inline storage without the write path complexity. Read, truncate, and convert paths remain intact. Signed-off-by: Yun Zhou --- fs/ext4/ext4.h | 4 --- fs/ext4/inline.c | 94 +++++------------------------------------------- fs/ext4/inode.c | 3 +- 3 files changed, 9 insertions(+), 92 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 21a951f10636..5f0448b960fe 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3759,10 +3759,6 @@ extern int ext4_destroy_inline_data(handle_t *handle, struct inode *inode); extern void ext4_update_final_de(void *de_buf, int old_size, int new_size); int ext4_readpage_inline(struct inode *inode, struct folio *folio); -extern int ext4_try_to_write_inline_data(struct address_space *mapping, - struct inode *inode, - loff_t pos, unsigned len, - struct folio **foliop); int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, unsigned copied, struct folio *folio); extern int ext4_generic_write_inline_data(struct address_space *mapping, diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 8f1efe4297a0..0803fa8eade7 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -699,97 +699,19 @@ int ext4_generic_write_inline_data(struct address_space *mapping, bool da) { int ret; - handle_t *handle; - struct folio *folio; - struct ext4_iloc iloc; int retries = 0; - ret = ext4_get_inode_loc(inode, &iloc); - if (ret) - return ret; - -retry_journal: - handle = ext4_journal_start(inode, EXT4_HT_INODE, 1); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out_release_bh; - } - - ret = ext4_prepare_inline_data(handle, inode, pos + len); - if (ret && ret != -ENOSPC) - goto out_stop_journal; - - if (ret == -ENOSPC) { - ext4_journal_stop(handle); - if (!da) { - brelse(iloc.bh); - /* Retry inside */ - return ext4_convert_inline_data(inode); - } - - ret = ext4_da_convert_inline_data_to_extent(mapping, inode); - if (ret == -ENOSPC && - ext4_should_retry_alloc(inode->i_sb, &retries)) - goto retry_journal; - goto out_release_bh; - } - - folio = __filemap_get_folio(mapping, 0, FGP_WRITEBEGIN | FGP_NOFS, - mapping_gfp_mask(mapping)); - if (IS_ERR(folio)) { - ret = PTR_ERR(folio); - goto out_stop_journal; - } - - down_read(&EXT4_I(inode)->xattr_sem); - /* Someone else had converted it to extent */ - if (!ext4_has_inline_data(inode)) { - ret = 0; - goto out_release_folio; - } - - if (!folio_test_uptodate(folio)) { - ret = ext4_read_inline_folio(inode, folio); - if (ret < 0) - goto out_release_folio; - } - - ret = ext4_journal_get_write_access(handle, inode->i_sb, iloc.bh, EXT4_JTR_NONE); - if (ret) - goto out_release_folio; - *foliop = folio; - up_read(&EXT4_I(inode)->xattr_sem); - brelse(iloc.bh); - return 1; + /* Inline data is deprecated: always convert to block format */ + if (!da) + return ext4_convert_inline_data(inode); -out_release_folio: - up_read(&EXT4_I(inode)->xattr_sem); - folio_unlock(folio); - folio_put(folio); -out_stop_journal: - ext4_journal_stop(handle); -out_release_bh: - brelse(iloc.bh); +retry: + ret = ext4_da_convert_inline_data_to_extent(mapping, inode); + if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; return ret; } -/* - * Try to write data in the inode. - * If the inode has inline data, check whether the new write can be - * in the inode also. If not, create the page the handle, move the data - * to the page make it update and let the later codes create extent for it. - */ -int ext4_try_to_write_inline_data(struct address_space *mapping, - struct inode *inode, - loff_t pos, unsigned len, - struct folio **foliop) -{ - if (pos + len > ext4_get_max_inline_size(inode)) - return ext4_convert_inline_data(inode); - return ext4_generic_write_inline_data(mapping, inode, pos, len, - foliop, false); -} - int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, unsigned copied, struct folio *folio) { @@ -828,7 +750,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, /* * ei->i_inline_off may have changed since * ext4_write_begin() called - * ext4_try_to_write_inline_data() + * ext4_convert_inline_data() */ (void) ext4_find_inline_data_nolock(inode); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ad14dd58a003..f9e1f0a6024d 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1312,8 +1312,7 @@ static int ext4_write_begin(const struct kiocb *iocb, index = pos >> PAGE_SHIFT; if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { - ret = ext4_try_to_write_inline_data(mapping, inode, pos, len, - foliop); + ret = ext4_convert_inline_data(inode); if (ret < 0) return ret; if (ret == 1) { -- 2.43.0