Commit 0add491d authored by Eric Whitney's avatar Eric Whitney Committed by Theodore Ts'o

ext4: remove extent cache entries when truncating inline data

Conditionally remove all cached extents belonging to an inode
when truncating its inline data.  It's only necessary to attempt to
remove cached extents when a conversion from inline to extent storage
has been initiated (!EXT4_STATE_MAY_INLINE_DATA).  This avoids
unnecessary es lock overhead in the more common inline case.
Signed-off-by: default avatarEric Whitney <enwlinux@gmail.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Link: https://lore.kernel.org/r/20210819144927.25163-2-enwlinux@gmail.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 11ef08c9
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/iomap.h> #include <linux/iomap.h>
#include <linux/fiemap.h> #include <linux/fiemap.h>
#include <linux/iversion.h> #include <linux/iversion.h>
#include <linux/backing-dev.h>
#include "ext4_jbd2.h" #include "ext4_jbd2.h"
#include "ext4.h" #include "ext4.h"
...@@ -1918,6 +1919,24 @@ int ext4_inline_data_truncate(struct inode *inode, int *has_inline) ...@@ -1918,6 +1919,24 @@ int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
EXT4_I(inode)->i_disksize = i_size; EXT4_I(inode)->i_disksize = i_size;
if (i_size < inline_size) { if (i_size < inline_size) {
/*
* if there's inline data to truncate and this file was
* converted to extents after that inline data was written,
* the extent status cache must be cleared to avoid leaving
* behind stale delayed allocated extent entries
*/
if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
retry:
err = ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
if (err == -ENOMEM) {
cond_resched();
congestion_wait(BLK_RW_ASYNC, HZ/50);
goto retry;
}
if (err)
goto out_error;
}
/* Clear the content in the xattr space. */ /* Clear the content in the xattr space. */
if (inline_size > EXT4_MIN_INLINE_DATA_SIZE) { if (inline_size > EXT4_MIN_INLINE_DATA_SIZE) {
if ((err = ext4_xattr_ibody_find(inode, &i, &is)) != 0) if ((err = ext4_xattr_ibody_find(inode, &i, &is)) != 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment