linux/fs/xfs/xfs_trans_priv.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
   3 * All Rights Reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it would be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write the Free Software Foundation,
  16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17 */
  18#ifndef __XFS_TRANS_PRIV_H__
  19#define __XFS_TRANS_PRIV_H__
  20
  21struct xfs_log_item;
  22struct xfs_log_item_desc;
  23struct xfs_mount;
  24struct xfs_trans;
  25struct xfs_ail;
  26struct xfs_log_vec;
  27
  28
  29void    xfs_trans_init(struct xfs_mount *);
  30void    xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *);
  31void    xfs_trans_del_item(struct xfs_log_item *);
  32void    xfs_trans_free_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn,
  33                                bool abort);
  34void    xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp);
  35
  36void    xfs_trans_committed_bulk(struct xfs_ail *ailp, struct xfs_log_vec *lv,
  37                                xfs_lsn_t commit_lsn, int aborted);
  38/*
  39 * AIL traversal cursor.
  40 *
  41 * Rather than using a generation number for detecting changes in the ail, use
  42 * a cursor that is protected by the ail lock. The aild cursor exists in the
  43 * struct xfs_ail, but other traversals can declare it on the stack and link it
  44 * to the ail list.
  45 *
  46 * When an object is deleted from or moved int the AIL, the cursor list is
  47 * searched to see if the object is a designated cursor item. If it is, it is
  48 * deleted from the cursor so that the next time the cursor is used traversal
  49 * will return to the start.
  50 *
  51 * This means a traversal colliding with a removal will cause a restart of the
  52 * list scan, rather than any insertion or deletion anywhere in the list. The
  53 * low bit of the item pointer is set if the cursor has been invalidated so
  54 * that we can tell the difference between invalidation and reaching the end
  55 * of the list to trigger traversal restarts.
  56 */
  57struct xfs_ail_cursor {
  58        struct list_head        list;
  59        struct xfs_log_item     *item;
  60};
  61
  62/*
  63 * Private AIL structures.
  64 *
  65 * Eventually we need to drive the locking in here as well.
  66 */
  67struct xfs_ail {
  68        struct xfs_mount        *xa_mount;
  69        struct task_struct      *xa_task;
  70        struct list_head        xa_ail;
  71        xfs_lsn_t               xa_target;
  72        xfs_lsn_t               xa_target_prev;
  73        struct list_head        xa_cursors;
  74        spinlock_t              xa_lock;
  75        xfs_lsn_t               xa_last_pushed_lsn;
  76        int                     xa_log_flush;
  77        struct list_head        xa_buf_list;
  78        wait_queue_head_t       xa_empty;
  79};
  80
  81/*
  82 * From xfs_trans_ail.c
  83 */
  84void    xfs_trans_ail_update_bulk(struct xfs_ail *ailp,
  85                                struct xfs_ail_cursor *cur,
  86                                struct xfs_log_item **log_items, int nr_items,
  87                                xfs_lsn_t lsn) __releases(ailp->xa_lock);
  88/*
  89 * Return a pointer to the first item in the AIL.  If the AIL is empty, then
  90 * return NULL.
  91 */
  92static inline struct xfs_log_item *
  93xfs_ail_min(
  94        struct xfs_ail  *ailp)
  95{
  96        return list_first_entry_or_null(&ailp->xa_ail, struct xfs_log_item,
  97                                        li_ail);
  98}
  99
 100static inline void
 101xfs_trans_ail_update(
 102        struct xfs_ail          *ailp,
 103        struct xfs_log_item     *lip,
 104        xfs_lsn_t               lsn) __releases(ailp->xa_lock)
 105{
 106        xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn);
 107}
 108
 109void    xfs_trans_ail_delete_bulk(struct xfs_ail *ailp,
 110                                struct xfs_log_item **log_items, int nr_items,
 111                                int shutdown_type)
 112                                __releases(ailp->xa_lock);
 113static inline void
 114xfs_trans_ail_delete(
 115        struct xfs_ail  *ailp,
 116        xfs_log_item_t  *lip,
 117        int             shutdown_type) __releases(ailp->xa_lock)
 118{
 119        xfs_trans_ail_delete_bulk(ailp, &lip, 1, shutdown_type);
 120}
 121
 122static inline void
 123xfs_trans_ail_remove(
 124        struct xfs_log_item     *lip,
 125        int                     shutdown_type)
 126{
 127        struct xfs_ail          *ailp = lip->li_ailp;
 128
 129        spin_lock(&ailp->xa_lock);
 130        /* xfs_trans_ail_delete() drops the AIL lock */
 131        if (lip->li_flags & XFS_LI_IN_AIL)
 132                xfs_trans_ail_delete(ailp, lip, shutdown_type);
 133        else
 134                spin_unlock(&ailp->xa_lock);
 135}
 136
 137void                    xfs_ail_push(struct xfs_ail *, xfs_lsn_t);
 138void                    xfs_ail_push_all(struct xfs_ail *);
 139void                    xfs_ail_push_all_sync(struct xfs_ail *);
 140struct xfs_log_item     *xfs_ail_min(struct xfs_ail  *ailp);
 141xfs_lsn_t               xfs_ail_min_lsn(struct xfs_ail *ailp);
 142
 143struct xfs_log_item *   xfs_trans_ail_cursor_first(struct xfs_ail *ailp,
 144                                        struct xfs_ail_cursor *cur,
 145                                        xfs_lsn_t lsn);
 146struct xfs_log_item *   xfs_trans_ail_cursor_last(struct xfs_ail *ailp,
 147                                        struct xfs_ail_cursor *cur,
 148                                        xfs_lsn_t lsn);
 149struct xfs_log_item *   xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
 150                                        struct xfs_ail_cursor *cur);
 151void                    xfs_trans_ail_cursor_done(struct xfs_ail_cursor *cur);
 152
 153#if BITS_PER_LONG != 64
 154static inline void
 155xfs_trans_ail_copy_lsn(
 156        struct xfs_ail  *ailp,
 157        xfs_lsn_t       *dst,
 158        xfs_lsn_t       *src)
 159{
 160        ASSERT(sizeof(xfs_lsn_t) == 8); /* don't lock if it shrinks */
 161        spin_lock(&ailp->xa_lock);
 162        *dst = *src;
 163        spin_unlock(&ailp->xa_lock);
 164}
 165#else
 166static inline void
 167xfs_trans_ail_copy_lsn(
 168        struct xfs_ail  *ailp,
 169        xfs_lsn_t       *dst,
 170        xfs_lsn_t       *src)
 171{
 172        ASSERT(sizeof(xfs_lsn_t) == 8);
 173        *dst = *src;
 174}
 175#endif
 176#endif  /* __XFS_TRANS_PRIV_H__ */
 177