^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) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef __XFS_TRANS_PRIV_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define __XFS_TRANS_PRIV_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) struct xfs_log_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) struct xfs_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct xfs_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) struct xfs_ail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct xfs_log_vec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) void xfs_trans_init(struct xfs_mount *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) void xfs_trans_del_item(struct xfs_log_item *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) void xfs_trans_committed_bulk(struct xfs_ail *ailp, struct xfs_log_vec *lv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) xfs_lsn_t commit_lsn, bool aborted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * AIL traversal cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Rather than using a generation number for detecting changes in the ail, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * a cursor that is protected by the ail lock. The aild cursor exists in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * struct xfs_ail, but other traversals can declare it on the stack and link it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * to the ail list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * When an object is deleted from or moved int the AIL, the cursor list is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * searched to see if the object is a designated cursor item. If it is, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * deleted from the cursor so that the next time the cursor is used traversal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * will return to the start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * This means a traversal colliding with a removal will cause a restart of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * list scan, rather than any insertion or deletion anywhere in the list. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * low bit of the item pointer is set if the cursor has been invalidated so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * that we can tell the difference between invalidation and reaching the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * of the list to trigger traversal restarts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct xfs_ail_cursor {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct xfs_log_item *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Private AIL structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Eventually we need to drive the locking in here as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct xfs_ail {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct xfs_mount *ail_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct task_struct *ail_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct list_head ail_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) xfs_lsn_t ail_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) xfs_lsn_t ail_target_prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct list_head ail_cursors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) spinlock_t ail_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) xfs_lsn_t ail_last_pushed_lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int ail_log_flush;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct list_head ail_buf_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) wait_queue_head_t ail_empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * From xfs_trans_ail.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void xfs_trans_ail_update_bulk(struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct xfs_ail_cursor *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct xfs_log_item **log_items, int nr_items,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) xfs_lsn_t lsn) __releases(ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Return a pointer to the first item in the AIL. If the AIL is empty, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * return NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static inline struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) xfs_ail_min(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct xfs_ail *ailp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return list_first_entry_or_null(&ailp->ail_head, struct xfs_log_item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) li_ail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) xfs_trans_ail_update(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) xfs_lsn_t lsn) __releases(ailp->ail_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) void xfs_trans_ail_insert(struct xfs_ail *ailp, struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) xfs_lsn_t lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) xfs_lsn_t xfs_ail_delete_one(struct xfs_ail *ailp, struct xfs_log_item *lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) void xfs_ail_update_finish(struct xfs_ail *ailp, xfs_lsn_t old_lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) __releases(ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void xfs_trans_ail_delete(struct xfs_log_item *lip, int shutdown_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) void xfs_ail_push(struct xfs_ail *, xfs_lsn_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void xfs_ail_push_all(struct xfs_ail *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) void xfs_ail_push_all_sync(struct xfs_ail *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct xfs_log_item *xfs_ail_min(struct xfs_ail *ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) xfs_lsn_t xfs_ail_min_lsn(struct xfs_ail *ailp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct xfs_log_item * xfs_trans_ail_cursor_first(struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct xfs_ail_cursor *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) xfs_lsn_t lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct xfs_log_item * xfs_trans_ail_cursor_last(struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct xfs_ail_cursor *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) xfs_lsn_t lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct xfs_log_item * xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct xfs_ail_cursor *cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void xfs_trans_ail_cursor_done(struct xfs_ail_cursor *cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #if BITS_PER_LONG != 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) xfs_trans_ail_copy_lsn(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) xfs_lsn_t *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) xfs_lsn_t *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ASSERT(sizeof(xfs_lsn_t) == 8); /* don't lock if it shrinks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) spin_lock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *dst = *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) spin_unlock(&ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) xfs_trans_ail_copy_lsn(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct xfs_ail *ailp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) xfs_lsn_t *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) xfs_lsn_t *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ASSERT(sizeof(xfs_lsn_t) == 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *dst = *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) xfs_clear_li_failed(
^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) struct xfs_buf *bp = lip->li_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) lockdep_assert_held(&lip->li_ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (test_and_clear_bit(XFS_LI_FAILED, &lip->li_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) lip->li_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) xfs_buf_rele(bp);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) xfs_set_li_failed(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct xfs_buf *bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) lockdep_assert_held(&lip->li_ailp->ail_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (!test_and_set_bit(XFS_LI_FAILED, &lip->li_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) xfs_buf_hold(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) lip->li_buf = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #endif /* __XFS_TRANS_PRIV_H__ */