[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230824092619.1327976-13-yi.zhang@huaweicloud.com>
Date: Thu, 24 Aug 2023 17:26:15 +0800
From: Zhang Yi <yi.zhang@...weicloud.com>
To: linux-ext4@...r.kernel.org
Cc: tytso@....edu, adilger.kernel@...ger.ca, jack@...e.cz,
yi.zhang@...wei.com, yi.zhang@...weicloud.com,
chengzhihao1@...wei.com, yukuai3@...wei.com
Subject: [RFC PATCH 12/16] ext4: update reserved meta blocks in ext4_da_{release|update_reserve}_space()
From: Zhang Yi <yi.zhang@...wei.com>
The same to ext4_da_reserve_space(), we also need to update reserved
metadata blocks when we release and convert a delalloc space range in
ext4_da_release_space() and ext4_da_update_reserve_space(). So also
prepare to reserve metadata blocks in these two functions, the
reservation logic are the same to data blocks. This patch is just a
preparation, the reserved ext_len is always zero.
Signed-off-by: Zhang Yi <yi.zhang@...wei.com>
---
fs/ext4/ext4.h | 4 ++--
fs/ext4/inode.c | 47 +++++++++++++++++++++----------------
include/trace/events/ext4.h | 28 ++++++++++++++--------
3 files changed, 47 insertions(+), 32 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ee2dbbde176e..3e0a39653469 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2998,9 +2998,9 @@ extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode,
extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf);
extern qsize_t *ext4_get_reserved_space(struct inode *inode);
extern int ext4_get_projid(struct inode *inode, kprojid_t *projid);
-extern void ext4_da_release_space(struct inode *inode, int to_free);
+extern void ext4_da_release_space(struct inode *inode, unsigned int data_len);
extern void ext4_da_update_reserve_space(struct inode *inode,
- int used, int quota_claim);
+ unsigned int data_len, int quota_claim);
extern int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk,
ext4_fsblk_t pblk, ext4_lblk_t len);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 13036cecbcc0..38c47ce1333b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -327,53 +327,59 @@ qsize_t *ext4_get_reserved_space(struct inode *inode)
static void __ext4_da_update_reserve_space(const char *where,
struct inode *inode,
- int data_len)
+ unsigned int data_len, int ext_len)
{
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct ext4_inode_info *ei = EXT4_I(inode);
- if (unlikely(data_len > ei->i_reserved_data_blocks)) {
- ext4_warning(inode->i_sb, "%s: ino %lu, clear %d "
- "with only %d reserved data blocks",
- where, inode->i_ino, data_len,
- ei->i_reserved_data_blocks);
+ if (unlikely(data_len > ei->i_reserved_data_blocks ||
+ ext_len > (long)ei->i_reserved_ext_blocks)) {
+ ext4_warning(inode->i_sb, "%s: ino %lu, clear %d,%d "
+ "with only %d,%d reserved data blocks",
+ where, inode->i_ino, data_len, ext_len,
+ ei->i_reserved_data_blocks,
+ ei->i_reserved_ext_blocks);
WARN_ON(1);
- data_len = ei->i_reserved_data_blocks;
+ data_len = min(data_len, ei->i_reserved_data_blocks);
+ ext_len = min_t(unsigned int, ext_len, ei->i_reserved_ext_blocks);
}
/* Update per-inode reservations */
ei->i_reserved_data_blocks -= data_len;
- percpu_counter_sub(&sbi->s_dirtyclusters_counter, data_len);
+ ei->i_reserved_ext_blocks -= ext_len;
+ percpu_counter_sub(&sbi->s_dirtyclusters_counter, (s64)data_len + ext_len);
}
/*
* Called with i_data_sem down, which is important since we can call
* ext4_discard_preallocations() from here.
*/
-void ext4_da_update_reserve_space(struct inode *inode,
- int used, int quota_claim)
+void ext4_da_update_reserve_space(struct inode *inode, unsigned int data_len,
+ int quota_claim)
{
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct ext4_inode_info *ei = EXT4_I(inode);
+ int ext_len = 0;
- if (!used)
+ if (!data_len)
return;
spin_lock(&ei->i_block_reservation_lock);
- trace_ext4_da_update_reserve_space(inode, used, quota_claim);
- __ext4_da_update_reserve_space(__func__, inode, used);
+ trace_ext4_da_update_reserve_space(inode, data_len, ext_len,
+ quota_claim);
+ __ext4_da_update_reserve_space(__func__, inode, data_len, ext_len);
spin_unlock(&ei->i_block_reservation_lock);
/* Update quota subsystem for data blocks */
if (quota_claim)
- dquot_claim_block(inode, EXT4_C2B(sbi, used));
+ dquot_claim_block(inode, EXT4_C2B(sbi, data_len));
else {
/*
* We did fallocate with an offset that is already delayed
* allocated. So on delayed allocated writeback we should
* not re-claim the quota for fallocated blocks.
*/
- dquot_release_reservation_block(inode, EXT4_C2B(sbi, used));
+ dquot_release_reservation_block(inode, EXT4_C2B(sbi, data_len));
}
/*
@@ -1484,20 +1490,21 @@ static int ext4_da_reserve_space(struct inode *inode, unsigned int rsv_dlen,
return 0; /* success */
}
-void ext4_da_release_space(struct inode *inode, int to_free)
+void ext4_da_release_space(struct inode *inode, unsigned int data_len)
{
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct ext4_inode_info *ei = EXT4_I(inode);
+ int ext_len = 0;
- if (!to_free)
+ if (!data_len)
return; /* Nothing to release, exit */
spin_lock(&ei->i_block_reservation_lock);
- trace_ext4_da_release_space(inode, to_free);
- __ext4_da_update_reserve_space(__func__, inode, to_free);
+ trace_ext4_da_release_space(inode, data_len, ext_len);
+ __ext4_da_update_reserve_space(__func__, inode, data_len, ext_len);
spin_unlock(&ei->i_block_reservation_lock);
- dquot_release_reservation_block(inode, EXT4_C2B(sbi, to_free));
+ dquot_release_reservation_block(inode, EXT4_C2B(sbi, data_len));
}
/*
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 7a9839f2d681..e1e9d7ead20f 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -1214,15 +1214,19 @@ TRACE_EVENT(ext4_forget,
);
TRACE_EVENT(ext4_da_update_reserve_space,
- TP_PROTO(struct inode *inode, int used_blocks, int quota_claim),
+ TP_PROTO(struct inode *inode,
+ int data_blocks,
+ int meta_blocks,
+ int quota_claim),
- TP_ARGS(inode, used_blocks, quota_claim),
+ TP_ARGS(inode, data_blocks, meta_blocks, quota_claim),
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
__field( __u64, i_blocks )
- __field( int, used_blocks )
+ __field( int, data_blocks )
+ __field( int, meta_blocks )
__field( int, reserved_data_blocks )
__field( int, reserved_ext_blocks )
__field( int, quota_claim )
@@ -1233,19 +1237,20 @@ TRACE_EVENT(ext4_da_update_reserve_space,
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
__entry->i_blocks = inode->i_blocks;
- __entry->used_blocks = used_blocks;
+ __entry->data_blocks = data_blocks;
+ __entry->meta_blocks = meta_blocks;
__entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
__entry->reserved_ext_blocks = EXT4_I(inode)->i_reserved_ext_blocks;
__entry->quota_claim = quota_claim;
__entry->mode = inode->i_mode;
),
- TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu used_blocks %d "
+ TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu data_blocks %d meta_blocks %d "
"reserved_data_blocks %d reserved_ext_blocks %d quota_claim %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
__entry->mode, __entry->i_blocks,
- __entry->used_blocks,
+ __entry->data_blocks, __entry->meta_blocks,
__entry->reserved_data_blocks, __entry->reserved_ext_blocks,
__entry->quota_claim)
);
@@ -1289,15 +1294,16 @@ TRACE_EVENT(ext4_da_reserve_space,
);
TRACE_EVENT(ext4_da_release_space,
- TP_PROTO(struct inode *inode, int freed_blocks),
+ TP_PROTO(struct inode *inode, int freed_blocks, int meta_blocks),
- TP_ARGS(inode, freed_blocks),
+ TP_ARGS(inode, freed_blocks, meta_blocks),
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
__field( __u64, i_blocks )
__field( int, freed_blocks )
+ __field( int, meta_blocks )
__field( int, reserved_data_blocks )
__field( int, reserved_ext_blocks )
__field( __u16, mode )
@@ -1308,17 +1314,19 @@ TRACE_EVENT(ext4_da_release_space,
__entry->ino = inode->i_ino;
__entry->i_blocks = inode->i_blocks;
__entry->freed_blocks = freed_blocks;
+ __entry->meta_blocks = meta_blocks;
__entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
__entry->reserved_ext_blocks = EXT4_I(inode)->i_reserved_ext_blocks;
__entry->mode = inode->i_mode;
),
- TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu freed_blocks %d "
+ TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu "
+ "freed_blocks %d meta_blocks %d"
"reserved_data_blocks %d reserved_ext_blocks %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
__entry->mode, __entry->i_blocks,
- __entry->freed_blocks,
+ __entry->freed_blocks, __entry->meta_blocks,
__entry->reserved_data_blocks,
__entry->reserved_ext_blocks)
);
--
2.39.2
Powered by blists - more mailing lists