Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
0004  * All Rights Reserved.
0005  */
0006 #ifndef __XFS_TRANS_PRIV_H__
0007 #define __XFS_TRANS_PRIV_H__
0008 
0009 struct xlog;
0010 struct xfs_log_item;
0011 struct xfs_mount;
0012 struct xfs_trans;
0013 struct xfs_ail;
0014 struct xfs_log_vec;
0015 
0016 
0017 void    xfs_trans_init(struct xfs_mount *);
0018 void    xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *);
0019 void    xfs_trans_del_item(struct xfs_log_item *);
0020 void    xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp);
0021 
0022 void    xfs_trans_committed_bulk(struct xfs_ail *ailp,
0023                 struct list_head *lv_chain,
0024                 xfs_lsn_t commit_lsn, bool aborted);
0025 /*
0026  * AIL traversal cursor.
0027  *
0028  * Rather than using a generation number for detecting changes in the ail, use
0029  * a cursor that is protected by the ail lock. The aild cursor exists in the
0030  * struct xfs_ail, but other traversals can declare it on the stack and link it
0031  * to the ail list.
0032  *
0033  * When an object is deleted from or moved int the AIL, the cursor list is
0034  * searched to see if the object is a designated cursor item. If it is, it is
0035  * deleted from the cursor so that the next time the cursor is used traversal
0036  * will return to the start.
0037  *
0038  * This means a traversal colliding with a removal will cause a restart of the
0039  * list scan, rather than any insertion or deletion anywhere in the list. The
0040  * low bit of the item pointer is set if the cursor has been invalidated so
0041  * that we can tell the difference between invalidation and reaching the end
0042  * of the list to trigger traversal restarts.
0043  */
0044 struct xfs_ail_cursor {
0045     struct list_head    list;
0046     struct xfs_log_item *item;
0047 };
0048 
0049 /*
0050  * Private AIL structures.
0051  *
0052  * Eventually we need to drive the locking in here as well.
0053  */
0054 struct xfs_ail {
0055     struct xlog     *ail_log;
0056     struct task_struct  *ail_task;
0057     struct list_head    ail_head;
0058     xfs_lsn_t       ail_target;
0059     xfs_lsn_t       ail_target_prev;
0060     struct list_head    ail_cursors;
0061     spinlock_t      ail_lock;
0062     xfs_lsn_t       ail_last_pushed_lsn;
0063     int         ail_log_flush;
0064     struct list_head    ail_buf_list;
0065     wait_queue_head_t   ail_empty;
0066 };
0067 
0068 /*
0069  * From xfs_trans_ail.c
0070  */
0071 void    xfs_trans_ail_update_bulk(struct xfs_ail *ailp,
0072                 struct xfs_ail_cursor *cur,
0073                 struct xfs_log_item **log_items, int nr_items,
0074                 xfs_lsn_t lsn) __releases(ailp->ail_lock);
0075 /*
0076  * Return a pointer to the first item in the AIL.  If the AIL is empty, then
0077  * return NULL.
0078  */
0079 static inline struct xfs_log_item *
0080 xfs_ail_min(
0081     struct xfs_ail  *ailp)
0082 {
0083     return list_first_entry_or_null(&ailp->ail_head, struct xfs_log_item,
0084                     li_ail);
0085 }
0086 
0087 static inline void
0088 xfs_trans_ail_update(
0089     struct xfs_ail      *ailp,
0090     struct xfs_log_item *lip,
0091     xfs_lsn_t       lsn) __releases(ailp->ail_lock)
0092 {
0093     xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn);
0094 }
0095 
0096 void xfs_trans_ail_insert(struct xfs_ail *ailp, struct xfs_log_item *lip,
0097         xfs_lsn_t lsn);
0098 
0099 xfs_lsn_t xfs_ail_delete_one(struct xfs_ail *ailp, struct xfs_log_item *lip);
0100 void xfs_ail_update_finish(struct xfs_ail *ailp, xfs_lsn_t old_lsn)
0101             __releases(ailp->ail_lock);
0102 void xfs_trans_ail_delete(struct xfs_log_item *lip, int shutdown_type);
0103 
0104 void            xfs_ail_push(struct xfs_ail *, xfs_lsn_t);
0105 void            xfs_ail_push_all(struct xfs_ail *);
0106 void            xfs_ail_push_all_sync(struct xfs_ail *);
0107 struct xfs_log_item *xfs_ail_min(struct xfs_ail  *ailp);
0108 xfs_lsn_t       xfs_ail_min_lsn(struct xfs_ail *ailp);
0109 
0110 struct xfs_log_item *   xfs_trans_ail_cursor_first(struct xfs_ail *ailp,
0111                     struct xfs_ail_cursor *cur,
0112                     xfs_lsn_t lsn);
0113 struct xfs_log_item *   xfs_trans_ail_cursor_last(struct xfs_ail *ailp,
0114                     struct xfs_ail_cursor *cur,
0115                     xfs_lsn_t lsn);
0116 struct xfs_log_item *   xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
0117                     struct xfs_ail_cursor *cur);
0118 void            xfs_trans_ail_cursor_done(struct xfs_ail_cursor *cur);
0119 
0120 #if BITS_PER_LONG != 64
0121 static inline void
0122 xfs_trans_ail_copy_lsn(
0123     struct xfs_ail  *ailp,
0124     xfs_lsn_t   *dst,
0125     xfs_lsn_t   *src)
0126 {
0127     ASSERT(sizeof(xfs_lsn_t) == 8); /* don't lock if it shrinks */
0128     spin_lock(&ailp->ail_lock);
0129     *dst = *src;
0130     spin_unlock(&ailp->ail_lock);
0131 }
0132 #else
0133 static inline void
0134 xfs_trans_ail_copy_lsn(
0135     struct xfs_ail  *ailp,
0136     xfs_lsn_t   *dst,
0137     xfs_lsn_t   *src)
0138 {
0139     ASSERT(sizeof(xfs_lsn_t) == 8);
0140     *dst = *src;
0141 }
0142 #endif
0143 
0144 static inline void
0145 xfs_clear_li_failed(
0146     struct xfs_log_item *lip)
0147 {
0148     struct xfs_buf  *bp = lip->li_buf;
0149 
0150     ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags));
0151     lockdep_assert_held(&lip->li_ailp->ail_lock);
0152 
0153     if (test_and_clear_bit(XFS_LI_FAILED, &lip->li_flags)) {
0154         lip->li_buf = NULL;
0155         xfs_buf_rele(bp);
0156     }
0157 }
0158 
0159 static inline void
0160 xfs_set_li_failed(
0161     struct xfs_log_item *lip,
0162     struct xfs_buf      *bp)
0163 {
0164     lockdep_assert_held(&lip->li_ailp->ail_lock);
0165 
0166     if (!test_and_set_bit(XFS_LI_FAILED, &lip->li_flags)) {
0167         xfs_buf_hold(bp);
0168         lip->li_buf = bp;
0169     }
0170 }
0171 
0172 #endif  /* __XFS_TRANS_PRIV_H__ */