ext4: hoist ext4_block_write_begin and replace the __block_write_begin
Using __block_write_begin() make it inconvenient to journal the user data dirty process. We can't tell the block layer maintainer, ‘Hey, we want to trace the dirty user data in ext4, can we add some special code for ext4 in __block_write_begin?’:P So use ext4_block_write_begin() instead. The two functions are basically doing the same thing except for the fscrypt related code. Remove the unnecessary #ifdef since fscrypt_inode_uses_fs_layer_crypto() returns false (and it's known at compile time) when !CONFIG_FS_ENCRYPTION. And hoist the ext4_block_write_begin so that it can be used in other files. Suggested-by: Jan Kara <jack@suse.cz> Suggested-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Shida Zhang <zhangshida@kylinos.cn> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20240830053739.3588573-3-zhangshida@kylinos.cn Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
3910b513fc
commit
6b730a4050
@ -3853,6 +3853,8 @@ static inline int ext4_buffer_uptodate(struct buffer_head *bh)
|
|||||||
return buffer_uptodate(bh);
|
return buffer_uptodate(bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int ext4_block_write_begin(struct folio *folio, loff_t pos, unsigned len,
|
||||||
|
get_block_t *get_block);
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
#define EFSBADCRC EBADMSG /* Bad CRC detected */
|
#define EFSBADCRC EBADMSG /* Bad CRC detected */
|
||||||
|
@ -601,10 +601,10 @@ retry:
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (ext4_should_dioread_nolock(inode)) {
|
if (ext4_should_dioread_nolock(inode)) {
|
||||||
ret = __block_write_begin(&folio->page, from, to,
|
ret = ext4_block_write_begin(folio, from, to,
|
||||||
ext4_get_block_unwritten);
|
ext4_get_block_unwritten);
|
||||||
} else
|
} else
|
||||||
ret = __block_write_begin(&folio->page, from, to, ext4_get_block);
|
ret = ext4_block_write_begin(folio, from, to, ext4_get_block);
|
||||||
|
|
||||||
if (!ret && ext4_should_journal_data(inode)) {
|
if (!ret && ext4_should_journal_data(inode)) {
|
||||||
ret = ext4_walk_page_buffers(handle, inode,
|
ret = ext4_walk_page_buffers(handle, inode,
|
||||||
@ -856,7 +856,7 @@ static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = __block_write_begin(&folio->page, 0, inline_size,
|
ret = ext4_block_write_begin(folio, 0, inline_size,
|
||||||
ext4_da_get_block_prep);
|
ext4_da_get_block_prep);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
up_read(&EXT4_I(inode)->xattr_sem);
|
up_read(&EXT4_I(inode)->xattr_sem);
|
||||||
|
@ -1006,10 +1006,10 @@ int do_journal_get_write_access(handle_t *handle, struct inode *inode,
|
|||||||
if (!buffer_mapped(bh) || buffer_freed(bh))
|
if (!buffer_mapped(bh) || buffer_freed(bh))
|
||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
* __block_write_begin() could have dirtied some buffers. Clean
|
* ext4_block_write_begin() could have dirtied some buffers. Clean
|
||||||
* the dirty bit as jbd2_journal_get_write_access() could complain
|
* the dirty bit as jbd2_journal_get_write_access() could complain
|
||||||
* otherwise about fs integrity issues. Setting of the dirty bit
|
* otherwise about fs integrity issues. Setting of the dirty bit
|
||||||
* by __block_write_begin() isn't a real problem here as we clear
|
* by ext4_block_write_begin() isn't a real problem here as we clear
|
||||||
* the bit before releasing a page lock and thus writeback cannot
|
* the bit before releasing a page lock and thus writeback cannot
|
||||||
* ever write the buffer.
|
* ever write the buffer.
|
||||||
*/
|
*/
|
||||||
@ -1023,8 +1023,7 @@ int do_journal_get_write_access(handle_t *handle, struct inode *inode,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FS_ENCRYPTION
|
int ext4_block_write_begin(struct folio *folio, loff_t pos, unsigned len,
|
||||||
static int ext4_block_write_begin(struct folio *folio, loff_t pos, unsigned len,
|
|
||||||
get_block_t *get_block)
|
get_block_t *get_block)
|
||||||
{
|
{
|
||||||
unsigned from = pos & (PAGE_SIZE - 1);
|
unsigned from = pos & (PAGE_SIZE - 1);
|
||||||
@ -1116,7 +1115,6 @@ static int ext4_block_write_begin(struct folio *folio, loff_t pos, unsigned len,
|
|||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To preserve ordering, it is essential that the hole instantiation and
|
* To preserve ordering, it is essential that the hole instantiation and
|
||||||
@ -1198,19 +1196,11 @@ retry_journal:
|
|||||||
/* In case writeback began while the folio was unlocked */
|
/* In case writeback began while the folio was unlocked */
|
||||||
folio_wait_stable(folio);
|
folio_wait_stable(folio);
|
||||||
|
|
||||||
#ifdef CONFIG_FS_ENCRYPTION
|
|
||||||
if (ext4_should_dioread_nolock(inode))
|
if (ext4_should_dioread_nolock(inode))
|
||||||
ret = ext4_block_write_begin(folio, pos, len,
|
ret = ext4_block_write_begin(folio, pos, len,
|
||||||
ext4_get_block_unwritten);
|
ext4_get_block_unwritten);
|
||||||
else
|
else
|
||||||
ret = ext4_block_write_begin(folio, pos, len, ext4_get_block);
|
ret = ext4_block_write_begin(folio, pos, len, ext4_get_block);
|
||||||
#else
|
|
||||||
if (ext4_should_dioread_nolock(inode))
|
|
||||||
ret = __block_write_begin(&folio->page, pos, len,
|
|
||||||
ext4_get_block_unwritten);
|
|
||||||
else
|
|
||||||
ret = __block_write_begin(&folio->page, pos, len, ext4_get_block);
|
|
||||||
#endif
|
|
||||||
if (!ret && ext4_should_journal_data(inode)) {
|
if (!ret && ext4_should_journal_data(inode)) {
|
||||||
ret = ext4_walk_page_buffers(handle, inode,
|
ret = ext4_walk_page_buffers(handle, inode,
|
||||||
folio_buffers(folio), from, to,
|
folio_buffers(folio), from, to,
|
||||||
@ -1223,7 +1213,7 @@ retry_journal:
|
|||||||
|
|
||||||
folio_unlock(folio);
|
folio_unlock(folio);
|
||||||
/*
|
/*
|
||||||
* __block_write_begin may have instantiated a few blocks
|
* ext4_block_write_begin may have instantiated a few blocks
|
||||||
* outside i_size. Trim these off again. Don't need
|
* outside i_size. Trim these off again. Don't need
|
||||||
* i_size_read because we hold i_rwsem.
|
* i_size_read because we hold i_rwsem.
|
||||||
*
|
*
|
||||||
@ -2936,11 +2926,7 @@ retry:
|
|||||||
if (IS_ERR(folio))
|
if (IS_ERR(folio))
|
||||||
return PTR_ERR(folio);
|
return PTR_ERR(folio);
|
||||||
|
|
||||||
#ifdef CONFIG_FS_ENCRYPTION
|
|
||||||
ret = ext4_block_write_begin(folio, pos, len, ext4_da_get_block_prep);
|
ret = ext4_block_write_begin(folio, pos, len, ext4_da_get_block_prep);
|
||||||
#else
|
|
||||||
ret = __block_write_begin(&folio->page, pos, len, ext4_da_get_block_prep);
|
|
||||||
#endif
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
folio_unlock(folio);
|
folio_unlock(folio);
|
||||||
folio_put(folio);
|
folio_put(folio);
|
||||||
|
Loading…
Reference in New Issue
Block a user