xfs: pass a CIL context to xlog_write()
authorDave Chinner <dchinner@redhat.com>
Wed, 11 Aug 2021 01:00:42 +0000 (18:00 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 16 Aug 2021 19:09:29 +0000 (12:09 -0700)
Pass the CIL context to xlog_write() rather than a pointer to a LSN
variable. Only the CIL checkpoint calls to xlog_write() need to know
about the start LSN of the writes, so rework xlog_write to directly
write the LSNs into the CIL context structure.

This removes the commit_lsn variable from xlog_cil_push_work(), so
now we only have to issue the commit record ordering wakeup from
there.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/xfs_log.c
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_log_priv.h

index fbcf70f7804bd5857cacdf49b7b1b189c8b7b3c9..6ac5d52f573d47f0474738b2af6b6e0230764b59 100644 (file)
@@ -933,7 +933,7 @@ xlog_write_unmount_record(
        /* account for space used by record data */
        ticket->t_curr_res -= sizeof(ulf);
 
-       return xlog_write(log, &vec, ticket, NULL, NULL, XLOG_UNMOUNT_TRANS);
+       return xlog_write(log, NULL, &vec, ticket, NULL, XLOG_UNMOUNT_TRANS);
 }
 
 /*
@@ -2470,9 +2470,9 @@ release_iclog:
 int
 xlog_write(
        struct xlog             *log,
+       struct xfs_cil_ctx      *ctx,
        struct xfs_log_vec      *log_vector,
        struct xlog_ticket      *ticket,
-       xfs_lsn_t               *start_lsn,
        struct xlog_in_core     **commit_iclog,
        uint                    optype)
 {
@@ -2503,8 +2503,6 @@ xlog_write(
        }
 
        len = xlog_write_calc_vec_length(ticket, log_vector, optype);
-       if (start_lsn)
-               *start_lsn = 0;
        while (lv && (!lv->lv_niovecs || index < lv->lv_niovecs)) {
                void            *ptr;
                int             log_offset;
@@ -2517,9 +2515,15 @@ xlog_write(
                ASSERT(log_offset <= iclog->ic_size - 1);
                ptr = iclog->ic_datap + log_offset;
 
-               /* Start_lsn is the first lsn written to. */
-               if (start_lsn && !*start_lsn)
-                       *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
+               /*
+                * If we have a context pointer, pass it the first iclog we are
+                * writing to so it can record state needed for iclog write
+                * ordering.
+                */
+               if (ctx) {
+                       xlog_cil_set_ctx_write_state(ctx, iclog);
+                       ctx = NULL;
+               }
 
                /*
                 * This loop writes out as many regions as can fit in the amount
index 5ebb5737d73fd664c33c3b8465f7d9768999ccce..651118fbaa616b7c80f833aaa567e8d3f59bf3a2 100644 (file)
@@ -631,6 +631,30 @@ xlog_cil_process_committed(
        }
 }
 
+/*
+* Record the LSN of the iclog we were just granted space to start writing into.
+* If the context doesn't have a start_lsn recorded, then this iclog will
+* contain the start record for the checkpoint. Otherwise this write contains
+* the commit record for the checkpoint.
+*/
+void
+xlog_cil_set_ctx_write_state(
+       struct xfs_cil_ctx      *ctx,
+       struct xlog_in_core     *iclog)
+{
+       struct xfs_cil          *cil = ctx->cil;
+       xfs_lsn_t               lsn = be64_to_cpu(iclog->ic_header.h_lsn);
+
+       ASSERT(!ctx->commit_lsn);
+       spin_lock(&cil->xc_push_lock);
+       if (!ctx->start_lsn)
+               ctx->start_lsn = lsn;
+       else
+               ctx->commit_lsn = lsn;
+       spin_unlock(&cil->xc_push_lock);
+}
+
+
 /*
  * Write out the commit record of a checkpoint transaction associated with the
  * given ticket to close off a running log write. Return the lsn of the commit
@@ -638,26 +662,26 @@ xlog_cil_process_committed(
  */
 static int
 xlog_cil_write_commit_record(
-       struct xlog             *log,
-       struct xlog_ticket      *ticket,
-       struct xlog_in_core     **iclog,
-       xfs_lsn_t               *lsn)
+       struct xfs_cil_ctx      *ctx,
+       struct xlog_in_core     **iclog)
 {
-       struct xfs_log_iovec reg = {
+       struct xlog             *log = ctx->cil->xc_log;
+       struct xfs_log_iovec    reg = {
                .i_addr = NULL,
                .i_len = 0,
                .i_type = XLOG_REG_TYPE_COMMIT,
        };
-       struct xfs_log_vec vec = {
+       struct xfs_log_vec      vec = {
                .lv_niovecs = 1,
                .lv_iovecp = &reg,
        };
-       int     error;
+       int                     error;
 
        if (xlog_is_shutdown(log))
                return -EIO;
 
-       error = xlog_write(log, &vec, ticket, lsn, iclog, XLOG_COMMIT_TRANS);
+       error = xlog_write(log, ctx, &vec, ctx->ticket, iclog,
+                       XLOG_COMMIT_TRANS);
        if (error)
                xfs_force_shutdown(log->l_mp, SHUTDOWN_LOG_IO_ERROR);
        return error;
@@ -695,7 +719,6 @@ xlog_cil_push_work(
        struct xfs_log_iovec    lhdr;
        struct xfs_log_vec      lvhdr = { NULL };
        xfs_lsn_t               preflush_tail_lsn;
-       xfs_lsn_t               commit_lsn;
        xfs_csn_t               push_seq;
        struct bio              bio;
        DECLARE_COMPLETION_ONSTACK(bdev_flush);
@@ -877,8 +900,7 @@ xlog_cil_push_work(
         */
        wait_for_completion(&bdev_flush);
 
-       error = xlog_write(log, &lvhdr, tic, &ctx->start_lsn, NULL,
-                               XLOG_START_TRANS);
+       error = xlog_write(log, ctx, &lvhdr, tic, NULL, XLOG_START_TRANS);
        if (error)
                goto out_abort_free_ticket;
 
@@ -916,8 +938,7 @@ restart:
        }
        spin_unlock(&cil->xc_push_lock);
 
-       error = xlog_cil_write_commit_record(log, tic, &commit_iclog,
-                       &commit_lsn);
+       error = xlog_cil_write_commit_record(ctx, &commit_iclog);
        if (error)
                goto out_abort_free_ticket;
 
@@ -944,7 +965,6 @@ restart:
         * and wake up anyone who is waiting for the commit to complete.
         */
        spin_lock(&cil->xc_push_lock);
-       ctx->commit_lsn = commit_lsn;
        wake_up_all(&cil->xc_commit_wait);
        spin_unlock(&cil->xc_push_lock);
 
@@ -960,11 +980,11 @@ restart:
         * iclog header lsn and compare it to the commit lsn to determine if we
         * need to wait on iclogs or not.
         */
-       if (ctx->start_lsn != commit_lsn) {
+       if (ctx->start_lsn != ctx->commit_lsn) {
                xfs_lsn_t       plsn;
 
                plsn = be64_to_cpu(commit_iclog->ic_prev->ic_header.h_lsn);
-               if (plsn && XFS_LSN_CMP(plsn, commit_lsn) < 0) {
+               if (plsn && XFS_LSN_CMP(plsn, ctx->commit_lsn) < 0) {
                        /*
                         * Waiting on ic_force_wait orders the completion of
                         * iclogs older than ic_prev. Hence we only need to wait
index 951447fc04146f7bf9d2da86b2f655115c397038..09156399b46c05aac8dd4158790ad4d9ce62e5c7 100644 (file)
@@ -512,8 +512,8 @@ xlog_write_adv_cnt(void **ptr, int *len, int *off, size_t bytes)
 
 void   xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket);
 void   xlog_print_trans(struct xfs_trans *);
-int    xlog_write(struct xlog *log, struct xfs_log_vec *log_vector,
-               struct xlog_ticket *tic, xfs_lsn_t *start_lsn,
+int    xlog_write(struct xlog *log, struct xfs_cil_ctx *ctx,
+               struct xfs_log_vec *log_vector, struct xlog_ticket *tic,
                struct xlog_in_core **commit_iclog, uint optype);
 void   xfs_log_ticket_ungrant(struct xlog *log, struct xlog_ticket *ticket);
 void   xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket);
@@ -585,6 +585,9 @@ void        xlog_cil_destroy(struct xlog *log);
 bool   xlog_cil_empty(struct xlog *log);
 void   xlog_cil_commit(struct xlog *log, struct xfs_trans *tp,
                        xfs_csn_t *commit_seq, bool regrant);
+void   xlog_cil_set_ctx_write_state(struct xfs_cil_ctx *ctx,
+                       struct xlog_in_core *iclog);
+
 
 /*
  * CIL force routines