Whamcloud - gitweb
LU-17337 osd: ask for more revoke credits 65/53365/4
authorAlex Zhuravlev <bzzz@whamcloud.com>
Tue, 5 Dec 2023 05:20:58 +0000 (08:20 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 23 Feb 2024 07:12:58 +0000 (07:12 +0000)
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 <bzzz@whamcloud.com>
Change-Id: I4967deb56e5aba82b68ffdc91de589fffae6a64a
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53365
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Sergey Cheremencev <scherementsev@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_internal.h

index a43a2da..23fa126 100644 (file)
@@ -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;
index 8733554..330286e 100644 (file)
@@ -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)