]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
xfs: refactor log recovery icreate item dispatch for pass2 commit functions
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 1 May 2020 23:00:48 +0000 (16:00 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Fri, 8 May 2020 15:49:59 +0000 (08:49 -0700)
Move the log icreate item pass2 commit code into the per-item source code
files and use the dispatch function to call it.  We do these one at a
time because there's a lot of code to move.  No functional changes.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/xfs_icreate_item.c
fs/xfs/xfs_log_recover.c

index 366c1e722a29621bb2bde44f5f1a9c4072117fdc..287a9e5c7d758eeafa5a77e670bbc40cc80b4d8b 100644 (file)
@@ -6,13 +6,19 @@
 #include "xfs.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
+#include "xfs_format.h"
 #include "xfs_log_format.h"
+#include "xfs_trans_resv.h"
+#include "xfs_mount.h"
+#include "xfs_inode.h"
 #include "xfs_trans.h"
 #include "xfs_trans_priv.h"
 #include "xfs_icreate_item.h"
 #include "xfs_log.h"
 #include "xfs_log_priv.h"
 #include "xfs_log_recover.h"
+#include "xfs_ialloc.h"
+#include "xfs_trace.h"
 
 kmem_zone_t    *xfs_icreate_zone;              /* inode create item zone */
 
@@ -123,7 +129,133 @@ xlog_recover_icreate_reorder(
        return XLOG_REORDER_BUFFER_LIST;
 }
 
+/*
+ * This routine is called when an inode create format structure is found in a
+ * committed transaction in the log.  It's purpose is to initialise the inodes
+ * being allocated on disk. This requires us to get inode cluster buffers that
+ * match the range to be initialised, stamped with inode templates and written
+ * by delayed write so that subsequent modifications will hit the cached buffer
+ * and only need writing out at the end of recovery.
+ */
+STATIC int
+xlog_recover_icreate_commit_pass2(
+       struct xlog                     *log,
+       struct list_head                *buffer_list,
+       struct xlog_recover_item        *item,
+       xfs_lsn_t                       lsn)
+{
+       struct xfs_mount                *mp = log->l_mp;
+       struct xfs_icreate_log          *icl;
+       struct xfs_ino_geometry         *igeo = M_IGEO(mp);
+       xfs_agnumber_t                  agno;
+       xfs_agblock_t                   agbno;
+       unsigned int                    count;
+       unsigned int                    isize;
+       xfs_agblock_t                   length;
+       int                             bb_per_cluster;
+       int                             cancel_count;
+       int                             nbufs;
+       int                             i;
+
+       icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr;
+       if (icl->icl_type != XFS_LI_ICREATE) {
+               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad type");
+               return -EINVAL;
+       }
+
+       if (icl->icl_size != 1) {
+               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad icl size");
+               return -EINVAL;
+       }
+
+       agno = be32_to_cpu(icl->icl_ag);
+       if (agno >= mp->m_sb.sb_agcount) {
+               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agno");
+               return -EINVAL;
+       }
+       agbno = be32_to_cpu(icl->icl_agbno);
+       if (!agbno || agbno == NULLAGBLOCK || agbno >= mp->m_sb.sb_agblocks) {
+               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agbno");
+               return -EINVAL;
+       }
+       isize = be32_to_cpu(icl->icl_isize);
+       if (isize != mp->m_sb.sb_inodesize) {
+               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad isize");
+               return -EINVAL;
+       }
+       count = be32_to_cpu(icl->icl_count);
+       if (!count) {
+               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count");
+               return -EINVAL;
+       }
+       length = be32_to_cpu(icl->icl_length);
+       if (!length || length >= mp->m_sb.sb_agblocks) {
+               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad length");
+               return -EINVAL;
+       }
+
+       /*
+        * The inode chunk is either full or sparse and we only support
+        * m_ino_geo.ialloc_min_blks sized sparse allocations at this time.
+        */
+       if (length != igeo->ialloc_blks &&
+           length != igeo->ialloc_min_blks) {
+               xfs_warn(log->l_mp,
+                        "%s: unsupported chunk length", __FUNCTION__);
+               return -EINVAL;
+       }
+
+       /* verify inode count is consistent with extent length */
+       if ((count >> mp->m_sb.sb_inopblog) != length) {
+               xfs_warn(log->l_mp,
+                        "%s: inconsistent inode count and chunk length",
+                        __FUNCTION__);
+               return -EINVAL;
+       }
+
+       /*
+        * The icreate transaction can cover multiple cluster buffers and these
+        * buffers could have been freed and reused. Check the individual
+        * buffers for cancellation so we don't overwrite anything written after
+        * a cancellation.
+        */
+       bb_per_cluster = XFS_FSB_TO_BB(mp, igeo->blocks_per_cluster);
+       nbufs = length / igeo->blocks_per_cluster;
+       for (i = 0, cancel_count = 0; i < nbufs; i++) {
+               xfs_daddr_t     daddr;
+
+               daddr = XFS_AGB_TO_DADDR(mp, agno,
+                               agbno + i * igeo->blocks_per_cluster);
+               if (xlog_is_buffer_cancelled(log, daddr, bb_per_cluster))
+                       cancel_count++;
+       }
+
+       /*
+        * We currently only use icreate for a single allocation at a time. This
+        * means we should expect either all or none of the buffers to be
+        * cancelled. Be conservative and skip replay if at least one buffer is
+        * cancelled, but warn the user that something is awry if the buffers
+        * are not consistent.
+        *
+        * XXX: This must be refined to only skip cancelled clusters once we use
+        * icreate for multiple chunk allocations.
+        */
+       ASSERT(!cancel_count || cancel_count == nbufs);
+       if (cancel_count) {
+               if (cancel_count != nbufs)
+                       xfs_warn(mp,
+       "WARNING: partial inode chunk cancellation, skipped icreate.");
+               trace_xfs_log_recover_icreate_cancel(log, icl);
+               return 0;
+       }
+
+       trace_xfs_log_recover_icreate_recover(log, icl);
+       return xfs_ialloc_inode_init(mp, NULL, buffer_list, count, agno, agbno,
+                                    length, be32_to_cpu(icl->icl_gen));
+}
+
 const struct xlog_recover_item_ops xlog_icreate_item_ops = {
        .item_type              = XFS_LI_ICREATE,
        .reorder                = xlog_recover_icreate_reorder,
+       .commit_pass2           = xlog_recover_icreate_commit_pass2,
 };
index 1b96df78375617be2ef990fc4d9728b82e607922..0a90ec9d0ca6fda4784bce63cf9a2a8062d3f7a0 100644 (file)
@@ -2467,130 +2467,6 @@ xlog_recover_bud_pass2(
        return 0;
 }
 
-/*
- * This routine is called when an inode create format structure is found in a
- * committed transaction in the log.  It's purpose is to initialise the inodes
- * being allocated on disk. This requires us to get inode cluster buffers that
- * match the range to be initialised, stamped with inode templates and written
- * by delayed write so that subsequent modifications will hit the cached buffer
- * and only need writing out at the end of recovery.
- */
-STATIC int
-xlog_recover_do_icreate_pass2(
-       struct xlog             *log,
-       struct list_head        *buffer_list,
-       struct xlog_recover_item *item)
-{
-       struct xfs_mount        *mp = log->l_mp;
-       struct xfs_icreate_log  *icl;
-       struct xfs_ino_geometry *igeo = M_IGEO(mp);
-       xfs_agnumber_t          agno;
-       xfs_agblock_t           agbno;
-       unsigned int            count;
-       unsigned int            isize;
-       xfs_agblock_t           length;
-       int                     bb_per_cluster;
-       int                     cancel_count;
-       int                     nbufs;
-       int                     i;
-
-       icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr;
-       if (icl->icl_type != XFS_LI_ICREATE) {
-               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad type");
-               return -EINVAL;
-       }
-
-       if (icl->icl_size != 1) {
-               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad icl size");
-               return -EINVAL;
-       }
-
-       agno = be32_to_cpu(icl->icl_ag);
-       if (agno >= mp->m_sb.sb_agcount) {
-               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agno");
-               return -EINVAL;
-       }
-       agbno = be32_to_cpu(icl->icl_agbno);
-       if (!agbno || agbno == NULLAGBLOCK || agbno >= mp->m_sb.sb_agblocks) {
-               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agbno");
-               return -EINVAL;
-       }
-       isize = be32_to_cpu(icl->icl_isize);
-       if (isize != mp->m_sb.sb_inodesize) {
-               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad isize");
-               return -EINVAL;
-       }
-       count = be32_to_cpu(icl->icl_count);
-       if (!count) {
-               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count");
-               return -EINVAL;
-       }
-       length = be32_to_cpu(icl->icl_length);
-       if (!length || length >= mp->m_sb.sb_agblocks) {
-               xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad length");
-               return -EINVAL;
-       }
-
-       /*
-        * The inode chunk is either full or sparse and we only support
-        * m_ino_geo.ialloc_min_blks sized sparse allocations at this time.
-        */
-       if (length != igeo->ialloc_blks &&
-           length != igeo->ialloc_min_blks) {
-               xfs_warn(log->l_mp,
-                        "%s: unsupported chunk length", __FUNCTION__);
-               return -EINVAL;
-       }
-
-       /* verify inode count is consistent with extent length */
-       if ((count >> mp->m_sb.sb_inopblog) != length) {
-               xfs_warn(log->l_mp,
-                        "%s: inconsistent inode count and chunk length",
-                        __FUNCTION__);
-               return -EINVAL;
-       }
-
-       /*
-        * The icreate transaction can cover multiple cluster buffers and these
-        * buffers could have been freed and reused. Check the individual
-        * buffers for cancellation so we don't overwrite anything written after
-        * a cancellation.
-        */
-       bb_per_cluster = XFS_FSB_TO_BB(mp, igeo->blocks_per_cluster);
-       nbufs = length / igeo->blocks_per_cluster;
-       for (i = 0, cancel_count = 0; i < nbufs; i++) {
-               xfs_daddr_t     daddr;
-
-               daddr = XFS_AGB_TO_DADDR(mp, agno,
-                               agbno + i * igeo->blocks_per_cluster);
-               if (xlog_is_buffer_cancelled(log, daddr, bb_per_cluster))
-                       cancel_count++;
-       }
-
-       /*
-        * We currently only use icreate for a single allocation at a time. This
-        * means we should expect either all or none of the buffers to be
-        * cancelled. Be conservative and skip replay if at least one buffer is
-        * cancelled, but warn the user that something is awry if the buffers
-        * are not consistent.
-        *
-        * XXX: This must be refined to only skip cancelled clusters once we use
-        * icreate for multiple chunk allocations.
-        */
-       ASSERT(!cancel_count || cancel_count == nbufs);
-       if (cancel_count) {
-               if (cancel_count != nbufs)
-                       xfs_warn(mp,
-       "WARNING: partial inode chunk cancellation, skipped icreate.");
-               trace_xfs_log_recover_icreate_cancel(log, icl);
-               return 0;
-       }
-
-       trace_xfs_log_recover_icreate_recover(log, icl);
-       return xfs_ialloc_inode_init(mp, NULL, buffer_list, count, agno, agbno,
-                                    length, be32_to_cpu(icl->icl_gen));
-}
-
 STATIC int
 xlog_recover_commit_pass2(
        struct xlog                     *log,
@@ -2621,8 +2497,6 @@ xlog_recover_commit_pass2(
                return xlog_recover_bui_pass2(log, item, trans->r_lsn);
        case XFS_LI_BUD:
                return xlog_recover_bud_pass2(log, item);
-       case XFS_LI_ICREATE:
-               return xlog_recover_do_icreate_pass2(log, buffer_list, item);
        case XFS_LI_QUOTAOFF:
                /* nothing to do in pass2 */
                return 0;