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