^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2008 Dave Chinner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_trans_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_errortag.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_error.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "xfs_log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Check that the list is sorted as it should be.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Called with the ail lock held, but we don't want to assert fail with it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * held otherwise we'll lock everything up and won't be able to debug the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * cause. Hence we sample and check the state under the AIL lock and return if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * everything is fine, otherwise we drop the lock and run the ASSERT checks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Asserts may not be fatal, so pick the lock back up and continue onwards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) xfs_ail_check(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) __must_hold(&ailp->ail_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct xfs_log_item *prev_lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct xfs_log_item *next_lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) xfs_lsn_t prev_lsn = NULLCOMMITLSN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) xfs_lsn_t next_lsn = NULLCOMMITLSN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) xfs_lsn_t lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) bool in_ail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (list_empty(&ailp->ail_head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Sample then check the next and previous entries are valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) in_ail = test_bit(XFS_LI_IN_AIL, &lip->li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) prev_lip = list_entry(lip->li_ail.prev, struct xfs_log_item, li_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (&prev_lip->li_ail != &ailp->ail_head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) prev_lsn = prev_lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) next_lip = list_entry(lip->li_ail.next, struct xfs_log_item, li_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (&next_lip->li_ail != &ailp->ail_head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) next_lsn = next_lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) lsn = lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (in_ail &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) (prev_lsn == NULLCOMMITLSN || XFS_LSN_CMP(prev_lsn, lsn) <= 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) (next_lsn == NULLCOMMITLSN || XFS_LSN_CMP(next_lsn, lsn) >= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ASSERT(in_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ASSERT(prev_lsn == NULLCOMMITLSN || XFS_LSN_CMP(prev_lsn, lsn) <= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ASSERT(next_lsn == NULLCOMMITLSN || XFS_LSN_CMP(next_lsn, lsn) >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #else /* !DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define xfs_ail_check(a,l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #endif /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Return a pointer to the last item in the AIL. If the AIL is empty, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * return NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) xfs_ail_max(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct xfs_ail *ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (list_empty(&ailp->ail_head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return list_entry(ailp->ail_head.prev, struct xfs_log_item, li_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Return a pointer to the item which follows the given item in the AIL. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * the given item is the last item in the list, then return NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) xfs_ail_next(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (lip->li_ail.next == &ailp->ail_head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return list_first_entry(&lip->li_ail, struct xfs_log_item, li_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * This is called by the log manager code to determine the LSN of the tail of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * the log. This is exactly the LSN of the first item in the AIL. If the AIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * is empty, then this function returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * We need the AIL lock in order to get a coherent read of the lsn of the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * item in the AIL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static xfs_lsn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __xfs_ail_min_lsn(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct xfs_ail *ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct xfs_log_item *lip = xfs_ail_min(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) xfs_lsn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) xfs_ail_min_lsn(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct xfs_ail *ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) xfs_lsn_t lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) lsn = __xfs_ail_min_lsn(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Return the maximum lsn held in the AIL, or zero if the AIL is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static xfs_lsn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) xfs_ail_max_lsn(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct xfs_ail *ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) xfs_lsn_t lsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct xfs_log_item *lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) lip = xfs_ail_max(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) lsn = lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * The cursor keeps track of where our current traversal is up to by tracking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * the next item in the list for us. However, for this to be safe, removing an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * object from the AIL needs to invalidate any cursor that points to it. hence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * the traversal cursor needs to be linked to the struct xfs_ail so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * deletion can search all the active cursors for invalidation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) xfs_trans_ail_cursor_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct xfs_ail_cursor *cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) cur->item = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) list_add_tail(&cur->list, &ailp->ail_cursors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * Get the next item in the traversal and advance the cursor. If the cursor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * was invalidated (indicated by a lip of 1), restart the traversal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) xfs_trans_ail_cursor_next(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct xfs_ail_cursor *cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct xfs_log_item *lip = cur->item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if ((uintptr_t)lip & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) lip = xfs_ail_min(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) cur->item = xfs_ail_next(ailp, lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * When the traversal is complete, we need to remove the cursor from the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * of traversing cursors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) xfs_trans_ail_cursor_done(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct xfs_ail_cursor *cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) cur->item = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) list_del_init(&cur->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Invalidate any cursor that is pointing to this item. This is called when an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * item is removed from the AIL. Any cursor pointing to this object is now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * invalid and the traversal needs to be terminated so it doesn't reference a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * freed object. We set the low bit of the cursor item pointer so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * distinguish between an invalidation and the end of the list when getting the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * next item from the cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) xfs_trans_ail_cursor_clear(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct xfs_ail_cursor *cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) list_for_each_entry(cur, &ailp->ail_cursors, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (cur->item == lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) cur->item = (struct xfs_log_item *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ((uintptr_t)cur->item | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * Find the first item in the AIL with the given @lsn by searching in ascending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * LSN order and initialise the cursor to point to the next item for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * ascending traversal. Pass a @lsn of zero to initialise the cursor to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * first item in the AIL. Returns NULL if the list is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) xfs_trans_ail_cursor_first(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct xfs_ail_cursor *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) xfs_lsn_t lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct xfs_log_item *lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) xfs_trans_ail_cursor_init(ailp, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (lsn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) lip = xfs_ail_min(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) list_for_each_entry(lip, &ailp->ail_head, li_ail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (XFS_LSN_CMP(lip->li_lsn, lsn) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) cur->item = xfs_ail_next(ailp, lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) __xfs_trans_ail_cursor_last(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) xfs_lsn_t lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct xfs_log_item *lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) list_for_each_entry_reverse(lip, &ailp->ail_head, li_ail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (XFS_LSN_CMP(lip->li_lsn, lsn) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * Find the last item in the AIL with the given @lsn by searching in descending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * LSN order and initialise the cursor to point to that item. If there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * item with the value of @lsn, then it sets the cursor to the last item with an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * LSN lower than @lsn. Returns NULL if the list is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) xfs_trans_ail_cursor_last(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct xfs_ail_cursor *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) xfs_lsn_t lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) xfs_trans_ail_cursor_init(ailp, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) cur->item = __xfs_trans_ail_cursor_last(ailp, lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return cur->item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * Splice the log item list into the AIL at the given LSN. We splice to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * tail of the given LSN to maintain insert order for push traversals. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * cursor is optional, allowing repeated updates to the same LSN to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * repeated traversals. This should not be called with an empty list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) xfs_ail_splice(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct xfs_ail_cursor *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) xfs_lsn_t lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct xfs_log_item *lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ASSERT(!list_empty(list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * Use the cursor to determine the insertion point if one is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * provided. If not, or if the one we got is not valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * find the place in the AIL where the items belong.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) lip = cur ? cur->item : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (!lip || (uintptr_t)lip & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) lip = __xfs_trans_ail_cursor_last(ailp, lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * If a cursor is provided, we know we're processing the AIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * in lsn order, and future items to be spliced in will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * follow the last one being inserted now. Update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * cursor to point to that last item, now while we have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * reliable pointer to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) cur->item = list_entry(list->prev, struct xfs_log_item, li_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * Finally perform the splice. Unless the AIL was empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * lip points to the item in the AIL _after_ which the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * items should go. If lip is null the AIL was empty, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * the new items go at the head of the AIL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) list_splice(list, &lip->li_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) list_splice(list, &ailp->ail_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * Delete the given item from the AIL. Return a pointer to the item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) xfs_ail_delete(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) xfs_ail_check(ailp, lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) list_del(&lip->li_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) xfs_trans_ail_cursor_clear(ailp, lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * Requeue a failed buffer for writeback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * We clear the log item failed state here as well, but we have to be careful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * about reference counts because the only active reference counts on the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * may be the failed log items. Hence if we clear the log item failed state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * before queuing the buffer for IO we can release all active references to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * the buffer and free it, leading to use after free problems in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * xfs_buf_delwri_queue. It makes no difference to the buffer or log items which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * order we process them in - the buffer is locked, and we own the buffer list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * so nothing on them is going to change while we are performing this action.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * Hence we can safely queue the buffer for IO before we clear the failed log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * item state, therefore always having an active reference to the buffer and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * avoiding the transient zero-reference state that leads to use-after-free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) xfsaild_resubmit_item(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct list_head *buffer_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct xfs_buf *bp = lip->li_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!xfs_buf_trylock(bp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return XFS_ITEM_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!xfs_buf_delwri_queue(bp, buffer_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) xfs_buf_unlock(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return XFS_ITEM_FLUSHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* protected by ail_lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) list_for_each_entry(lip, &bp->b_li_list, li_bio_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (bp->b_flags & _XBF_INODES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) clear_bit(XFS_LI_FAILED, &lip->li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) xfs_clear_li_failed(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) xfs_buf_unlock(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return XFS_ITEM_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static inline uint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) xfsaild_push_item(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * If log item pinning is enabled, skip the push and track the item as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * pinned. This can help induce head-behind-tail conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (XFS_TEST_ERROR(false, ailp->ail_mount, XFS_ERRTAG_LOG_ITEM_PIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return XFS_ITEM_PINNED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * Consider the item pinned if a push callback is not defined so the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * caller will force the log. This should only happen for intent items
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * as they are unpinned once the associated done item is committed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * the on-disk log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (!lip->li_ops->iop_push)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return XFS_ITEM_PINNED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (test_bit(XFS_LI_FAILED, &lip->li_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return xfsaild_resubmit_item(lip, &ailp->ail_buf_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return lip->li_ops->iop_push(lip, &ailp->ail_buf_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) xfsaild_push(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct xfs_ail *ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) xfs_mount_t *mp = ailp->ail_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct xfs_ail_cursor cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct xfs_log_item *lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) xfs_lsn_t lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) xfs_lsn_t target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) long tout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int stuck = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int flushing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * If we encountered pinned items or did not finish writing out all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * buffers the last time we ran, force the log first and wait for it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * before pushing again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (ailp->ail_log_flush && ailp->ail_last_pushed_lsn == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) (!list_empty_careful(&ailp->ail_buf_list) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) xfs_ail_min_lsn(ailp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ailp->ail_log_flush = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) XFS_STATS_INC(mp, xs_push_ail_flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) xfs_log_force(mp, XFS_LOG_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /* barrier matches the ail_target update in xfs_ail_push() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) target = ailp->ail_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ailp->ail_target_prev = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* we're done if the AIL is empty or our push has reached the end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) lip = xfs_trans_ail_cursor_first(ailp, &cur, ailp->ail_last_pushed_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) goto out_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) XFS_STATS_INC(mp, xs_push_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) lsn = lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) int lock_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * Note that iop_push may unlock and reacquire the AIL lock. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * rely on the AIL cursor implementation to be able to deal with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * the dropped lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) lock_result = xfsaild_push_item(ailp, lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) switch (lock_result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case XFS_ITEM_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) XFS_STATS_INC(mp, xs_push_ail_success);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) trace_xfs_ail_push(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ailp->ail_last_pushed_lsn = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) case XFS_ITEM_FLUSHING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * The item or its backing buffer is already being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * flushed. The typical reason for that is that an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * inode buffer is locked because we already pushed the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * updates to it as part of inode clustering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * We do not want to stop flushing just because lots
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * of items are already being flushed, but we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * re-try the flushing relatively soon if most of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * AIL is being flushed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) XFS_STATS_INC(mp, xs_push_ail_flushing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) trace_xfs_ail_flushing(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) flushing++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ailp->ail_last_pushed_lsn = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case XFS_ITEM_PINNED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) XFS_STATS_INC(mp, xs_push_ail_pinned);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) trace_xfs_ail_pinned(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) stuck++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ailp->ail_log_flush++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) case XFS_ITEM_LOCKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) XFS_STATS_INC(mp, xs_push_ail_locked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) trace_xfs_ail_locked(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) stuck++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * Are there too many items we can't do anything with?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * If we are skipping too many items because we can't flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * them or they are already being flushed, we back off and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * given them time to complete whatever operation is being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * done. i.e. remove pressure from the AIL while we can't make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * progress so traversals don't slow down further inserts and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * removals to/from the AIL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * The value of 100 is an arbitrary magic number based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * observation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (stuck > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) lip = xfs_trans_ail_cursor_next(ailp, &cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (lip == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) lsn = lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) out_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) xfs_trans_ail_cursor_done(&cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (xfs_buf_delwri_submit_nowait(&ailp->ail_buf_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) ailp->ail_log_flush++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (!count || XFS_LSN_CMP(lsn, target) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * We reached the target or the AIL is empty, so wait a bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * longer for I/O to complete and remove pushed items from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * AIL before we start the next scan from the start of the AIL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) tout = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ailp->ail_last_pushed_lsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) } else if (((stuck + flushing) * 100) / count > 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * Either there is a lot of contention on the AIL or we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * stuck due to operations in progress. "Stuck" in this case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * is defined as >90% of the items we tried to push were stuck.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * Backoff a bit more to allow some I/O to complete before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * restarting from the start of the AIL. This prevents us from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * spinning on the same items, and if they are pinned will all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * the restart to issue a log force to unpin the stuck items.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) tout = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) ailp->ail_last_pushed_lsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * Assume we have more work to do in a short while.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) tout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return tout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) xfsaild(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct xfs_ail *ailp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) long tout = 0; /* milliseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unsigned int noreclaim_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) noreclaim_flag = memalloc_noreclaim_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) set_freezable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (tout && tout <= 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) set_current_state(TASK_KILLABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * Check kthread_should_stop() after we set the task state to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * guarantee that we either see the stop bit and exit or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * task state is reset to runnable such that it's not scheduled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * out indefinitely and detects the stop bit at next iteration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * A memory barrier is included in above task state set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * serialize again kthread_stop().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (kthread_should_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) __set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * The caller forces out the AIL before stopping the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * thread in the common case, which means the delwri
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * queue is drained. In the shutdown case, the queue may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * still hold relogged buffers that haven't been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * submitted because they were pinned since added to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * Log I/O error processing stales the underlying buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * and clears the delwri state, expecting the buf to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * removed on the next submission attempt. That won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * happen if we're shutting down, so this is the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * opportunity to release such buffers from the queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ASSERT(list_empty(&ailp->ail_buf_list) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) XFS_FORCED_SHUTDOWN(ailp->ail_mount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) xfs_buf_delwri_cancel(&ailp->ail_buf_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * Idle if the AIL is empty and we are not racing with a target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * update. We check the AIL after we set the task to a sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * state to guarantee that we either catch an ail_target update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * or that a wake_up resets the state to TASK_RUNNING.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * Otherwise, we run the risk of sleeping indefinitely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * The barrier matches the ail_target update in xfs_ail_push().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (!xfs_ail_min(ailp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ailp->ail_target == ailp->ail_target_prev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) list_empty(&ailp->ail_buf_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) freezable_schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) tout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (tout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) freezable_schedule_timeout(msecs_to_jiffies(tout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) __set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) try_to_freeze();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) tout = xfsaild_push(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) memalloc_noreclaim_restore(noreclaim_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * This routine is called to move the tail of the AIL forward. It does this by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * trying to flush items in the AIL whose lsns are below the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * threshold_lsn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * The push is run asynchronously in a workqueue, which means the caller needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * to handle waiting on the async flush for space to become available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * We don't want to interrupt any push that is in progress, hence we only queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * work if we set the pushing bit appropriately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * We do this unlocked - we only need to know whether there is anything in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * AIL at the time we are called. We don't need to access the contents of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * any of the objects, so the lock is not needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) xfs_ail_push(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) xfs_lsn_t threshold_lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct xfs_log_item *lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) lip = xfs_ail_min(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!lip || XFS_FORCED_SHUTDOWN(ailp->ail_mount) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) XFS_LSN_CMP(threshold_lsn, ailp->ail_target) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * Ensure that the new target is noticed in push code before it clears
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * the XFS_AIL_PUSHING_BIT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) xfs_trans_ail_copy_lsn(ailp, &ailp->ail_target, &threshold_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) wake_up_process(ailp->ail_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * Push out all items in the AIL immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) xfs_ail_push_all(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct xfs_ail *ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) xfs_lsn_t threshold_lsn = xfs_ail_max_lsn(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (threshold_lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) xfs_ail_push(ailp, threshold_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * Push out all items in the AIL immediately and wait until the AIL is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) xfs_ail_push_all_sync(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct xfs_ail *ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct xfs_log_item *lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) while ((lip = xfs_ail_max(ailp)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) prepare_to_wait(&ailp->ail_empty, &wait, TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ailp->ail_target = lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) wake_up_process(ailp->ail_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) finish_wait(&ailp->ail_empty, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) xfs_ail_update_finish(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) xfs_lsn_t old_lsn) __releases(ailp->ail_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct xfs_mount *mp = ailp->ail_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* if the tail lsn hasn't changed, don't do updates or wakeups. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!old_lsn || old_lsn == __xfs_ail_min_lsn(ailp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (!XFS_FORCED_SHUTDOWN(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) xlog_assign_tail_lsn_locked(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (list_empty(&ailp->ail_head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) wake_up_all(&ailp->ail_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) xfs_log_space_wake(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * xfs_trans_ail_update - bulk AIL insertion operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * @xfs_trans_ail_update takes an array of log items that all need to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * positioned at the same LSN in the AIL. If an item is not in the AIL, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * be added. Otherwise, it will be repositioned by removing it and re-adding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * it to the AIL. If we move the first item in the AIL, update the log tail to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * match the new minimum LSN in the AIL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * This function takes the AIL lock once to execute the update operations on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * all the items in the array, and as such should not be called with the AIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * lock held. As a result, once we have the AIL lock, we need to check each log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * item LSN to confirm it needs to be moved forward in the AIL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * To optimise the insert operation, we delete all the items from the AIL in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * the first pass, moving them into a temporary list, then splice the temporary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * list into the correct position in the AIL. This avoids needing to do an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * insert operation on every item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * This function must be called with the AIL lock held. The lock is dropped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * before returning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) xfs_trans_ail_update_bulk(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct xfs_ail_cursor *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct xfs_log_item **log_items,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) int nr_items,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) xfs_lsn_t lsn) __releases(ailp->ail_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct xfs_log_item *mlip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) xfs_lsn_t tail_lsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) LIST_HEAD(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ASSERT(nr_items > 0); /* Not required, but true. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) mlip = xfs_ail_min(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) for (i = 0; i < nr_items; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct xfs_log_item *lip = log_items[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (test_and_set_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* check if we really need to move the item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (XFS_LSN_CMP(lsn, lip->li_lsn) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) trace_xfs_ail_move(lip, lip->li_lsn, lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (mlip == lip && !tail_lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) tail_lsn = lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) xfs_ail_delete(ailp, lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) trace_xfs_ail_insert(lip, 0, lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) lip->li_lsn = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) list_add(&lip->li_ail, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (!list_empty(&tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) xfs_ail_splice(ailp, cur, &tmp, lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) xfs_ail_update_finish(ailp, tail_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /* Insert a log item into the AIL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) xfs_trans_ail_insert(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) xfs_lsn_t lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * Delete one log item from the AIL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * If this item was at the tail of the AIL, return the LSN of the log item so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * that we can use it to check if the LSN of the tail of the log has moved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * when finishing up the AIL delete process in xfs_ail_update_finish().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) xfs_lsn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) xfs_ail_delete_one(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct xfs_log_item *mlip = xfs_ail_min(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) xfs_lsn_t lsn = lip->li_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) xfs_ail_delete(ailp, lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) clear_bit(XFS_LI_IN_AIL, &lip->li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) lip->li_lsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (mlip == lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) xfs_trans_ail_delete(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) int shutdown_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct xfs_ail *ailp = lip->li_ailp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct xfs_mount *mp = ailp->ail_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) xfs_lsn_t tail_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (!test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (shutdown_type && !XFS_FORCED_SHUTDOWN(mp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) xfs_alert_tag(mp, XFS_PTAG_AILDELETE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) "%s: attempting to delete a log item that is not in the AIL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) xfs_force_shutdown(mp, shutdown_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /* xfs_ail_update_finish() drops the AIL lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) xfs_clear_li_failed(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) tail_lsn = xfs_ail_delete_one(ailp, lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) xfs_ail_update_finish(ailp, tail_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) xfs_trans_ail_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) xfs_mount_t *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct xfs_ail *ailp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ailp = kmem_zalloc(sizeof(struct xfs_ail), KM_MAYFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (!ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ailp->ail_mount = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) INIT_LIST_HEAD(&ailp->ail_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) INIT_LIST_HEAD(&ailp->ail_cursors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) spin_lock_init(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) INIT_LIST_HEAD(&ailp->ail_buf_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) init_waitqueue_head(&ailp->ail_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ailp->ail_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ailp->ail_mount->m_super->s_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (IS_ERR(ailp->ail_task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) goto out_free_ailp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) mp->m_ail = ailp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) out_free_ailp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) kmem_free(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) xfs_trans_ail_destroy(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) xfs_mount_t *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct xfs_ail *ailp = mp->m_ail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) kthread_stop(ailp->ail_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) kmem_free(ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }