From 682577b277e5d16875b3e4d70e6a03e19452e672 Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Tue, 5 Dec 2023 08:20:58 +0300 Subject: [PATCH] LU-17337 osd: ask for more revoke credits starting from 4.* kernels JBD2 tracks number of potential revoked blocks separately from regular journal blocks and checks a transaction doesn't exceed the declared number. before extent merging patch a regular block allocation could free only very limited number of blocks. now with extent merging when an extent tree is really big and few extents are inserted in a single transaction, then such an allocation can exceed default revoke credits (8). the patch uses number of extent in the transaction to calculate potential number of revoke records (max tree depth * default). Fixes: 0f7e6c02a9 ("LU-16843 ldiskfs: merge extent blocks") Signed-off-by: Alex Zhuravlev Change-Id: I4967deb56e5aba82b68ffdc91de589fffae6a64a Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53365 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Sergey Cheremencev Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger --- lustre/osd-ldiskfs/osd_handler.c | 31 +++++++++++++++++++++++++++++-- lustre/osd-ldiskfs/osd_internal.h | 8 ++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index a43a2da..23fa126 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -2003,6 +2003,31 @@ void osd_trans_dump_creds(const struct lu_env *env, struct thandle *th) oti->oti_declare_ops_used[OSD_OT_REF_DEL]); } +#ifdef HAVE_LDISKFS_JOURNAL_ENSURE_CREDITS +void osd_ldiskfs_credits_for_revoke(struct osd_device *osd, + struct osd_thandle *oh, + int *credits, int *revoke) +{ + int blocks = LDISKFS_MAX_EXTENT_DEPTH * oh->oh_declared_ext; + *revoke += ldiskfs_trans_default_revoke_credits(osd_sb(osd)) + blocks; +} +#else +void osd_ldiskfs_credits_for_revoke(struct osd_device *osd, + struct osd_thandle *oh, + int *credits, int *revoke) +{ + struct journal_s *journal = LDISKFS_SB(osd_sb(osd))->s_journal; + int blocks, jbsize, records_per_block; + + blocks = LDISKFS_MAX_EXTENT_DEPTH * oh->oh_declared_ext; + jbsize = journal->j_blocksize; + jbsize -= sizeof(struct jbd2_journal_block_tail) + + sizeof(jbd2_journal_revoke_header_t); + records_per_block = jbsize / 8; + *credits += (blocks + records_per_block - 1) / records_per_block; +} +#endif + /* * Concurrency: shouldn't matter. */ @@ -2013,7 +2038,7 @@ static int osd_trans_start(const struct lu_env *env, struct dt_device *d, struct osd_device *dev = osd_dt_dev(d); handle_t *jh; struct osd_thandle *oh; - int rc; + int rc, revoke = 0; ENTRY; @@ -2087,7 +2112,9 @@ static int osd_trans_start(const struct lu_env *env, struct dt_device *d, * XXX temporary stuff. Some abstraction layer should * be used. */ - jh = osd_journal_start_sb(osd_sb(dev), LDISKFS_HT_MISC, oh->ot_credits); + osd_ldiskfs_credits_for_revoke(dev, oh, &oh->ot_credits, &revoke); + jh = osd_journal_start_with_revoke(osd_sb(dev), LDISKFS_HT_MISC, + oh->ot_credits, revoke); osd_th_started(oh); if (!IS_ERR(jh)) { oh->ot_handle = jh; diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index 8733554..330286e 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -992,6 +992,14 @@ static inline void i_projid_write(struct inode *inode, __u32 projid) #ifdef LDISKFS_HT_MISC # define osd_journal_start_sb(sb, type, nblock) \ ldiskfs_journal_start_sb(sb, type, nblock) +#ifdef HAVE_LDISKFS_JOURNAL_ENSURE_CREDITS +# define osd_journal_start_with_revoke(sb, type, nblock, revoke) \ + ldiskfs_journal_start_with_revoke((sb)->s_root->d_inode, type, \ + nblock, revoke) +#else +# define osd_journal_start_with_revoke(sb, type, nblock, revoke) \ + ldiskfs_journal_start_sb(sb, type, nblock) +#endif static inline struct buffer_head *osd_ldiskfs_append(handle_t *handle, struct inode *inode, ldiskfs_lblk_t *nblock) -- 1.8.3.1