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_H__
0007 #define __XFS_TRANS_H__
0008 
0009 /* kernel only transaction subsystem defines */
0010 
0011 struct xlog;
0012 struct xfs_buf;
0013 struct xfs_buftarg;
0014 struct xfs_efd_log_item;
0015 struct xfs_efi_log_item;
0016 struct xfs_inode;
0017 struct xfs_item_ops;
0018 struct xfs_log_iovec;
0019 struct xfs_mount;
0020 struct xfs_trans;
0021 struct xfs_trans_res;
0022 struct xfs_dquot_acct;
0023 struct xfs_rud_log_item;
0024 struct xfs_rui_log_item;
0025 struct xfs_btree_cur;
0026 struct xfs_cui_log_item;
0027 struct xfs_cud_log_item;
0028 struct xfs_bui_log_item;
0029 struct xfs_bud_log_item;
0030 
0031 struct xfs_log_item {
0032     struct list_head        li_ail;     /* AIL pointers */
0033     struct list_head        li_trans;   /* transaction list */
0034     xfs_lsn_t           li_lsn;     /* last on-disk lsn */
0035     struct xlog         *li_log;
0036     struct xfs_ail          *li_ailp;   /* ptr to AIL */
0037     uint                li_type;    /* item type */
0038     unsigned long           li_flags;   /* misc flags */
0039     struct xfs_buf          *li_buf;    /* real buffer pointer */
0040     struct list_head        li_bio_list;    /* buffer item list */
0041     const struct xfs_item_ops   *li_ops;    /* function list */
0042 
0043     /* delayed logging */
0044     struct list_head        li_cil;     /* CIL pointers */
0045     struct xfs_log_vec      *li_lv;     /* active log vector */
0046     struct xfs_log_vec      *li_lv_shadow;  /* standby vector */
0047     xfs_csn_t           li_seq;     /* CIL commit seq */
0048     uint32_t            li_order_id;    /* CIL commit order */
0049 };
0050 
0051 /*
0052  * li_flags use the (set/test/clear)_bit atomic interfaces because updates can
0053  * race with each other and we don't want to have to use the AIL lock to
0054  * serialise all updates.
0055  */
0056 #define XFS_LI_IN_AIL   0
0057 #define XFS_LI_ABORTED  1
0058 #define XFS_LI_FAILED   2
0059 #define XFS_LI_DIRTY    3
0060 #define XFS_LI_WHITEOUT 4
0061 
0062 #define XFS_LI_FLAGS \
0063     { (1u << XFS_LI_IN_AIL),    "IN_AIL" }, \
0064     { (1u << XFS_LI_ABORTED),   "ABORTED" }, \
0065     { (1u << XFS_LI_FAILED),    "FAILED" }, \
0066     { (1u << XFS_LI_DIRTY),     "DIRTY" }, \
0067     { (1u << XFS_LI_WHITEOUT),  "WHITEOUT" }
0068 
0069 struct xfs_item_ops {
0070     unsigned flags;
0071     void (*iop_size)(struct xfs_log_item *, int *, int *);
0072     void (*iop_format)(struct xfs_log_item *, struct xfs_log_vec *);
0073     void (*iop_pin)(struct xfs_log_item *);
0074     void (*iop_unpin)(struct xfs_log_item *, int remove);
0075     uint64_t (*iop_sort)(struct xfs_log_item *lip);
0076     int (*iop_precommit)(struct xfs_trans *tp, struct xfs_log_item *lip);
0077     void (*iop_committing)(struct xfs_log_item *lip, xfs_csn_t seq);
0078     xfs_lsn_t (*iop_committed)(struct xfs_log_item *, xfs_lsn_t);
0079     uint (*iop_push)(struct xfs_log_item *, struct list_head *);
0080     void (*iop_release)(struct xfs_log_item *);
0081     int (*iop_recover)(struct xfs_log_item *lip,
0082                struct list_head *capture_list);
0083     bool (*iop_match)(struct xfs_log_item *item, uint64_t id);
0084     struct xfs_log_item *(*iop_relog)(struct xfs_log_item *intent,
0085             struct xfs_trans *tp);
0086     struct xfs_log_item *(*iop_intent)(struct xfs_log_item *intent_done);
0087 };
0088 
0089 /*
0090  * Log item ops flags
0091  */
0092 /*
0093  * Release the log item when the journal commits instead of inserting into the
0094  * AIL for writeback tracking and/or log tail pinning.
0095  */
0096 #define XFS_ITEM_RELEASE_WHEN_COMMITTED (1 << 0)
0097 #define XFS_ITEM_INTENT         (1 << 1)
0098 #define XFS_ITEM_INTENT_DONE        (1 << 2)
0099 
0100 static inline bool
0101 xlog_item_is_intent(struct xfs_log_item *lip)
0102 {
0103     return lip->li_ops->flags & XFS_ITEM_INTENT;
0104 }
0105 
0106 static inline bool
0107 xlog_item_is_intent_done(struct xfs_log_item *lip)
0108 {
0109     return lip->li_ops->flags & XFS_ITEM_INTENT_DONE;
0110 }
0111 
0112 void    xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,
0113               int type, const struct xfs_item_ops *ops);
0114 
0115 /*
0116  * Return values for the iop_push() routines.
0117  */
0118 #define XFS_ITEM_SUCCESS    0
0119 #define XFS_ITEM_PINNED     1
0120 #define XFS_ITEM_LOCKED     2
0121 #define XFS_ITEM_FLUSHING   3
0122 
0123 /*
0124  * This is the structure maintained for every active transaction.
0125  */
0126 typedef struct xfs_trans {
0127     unsigned int        t_magic;    /* magic number */
0128     unsigned int        t_log_res;  /* amt of log space resvd */
0129     unsigned int        t_log_count;    /* count for perm log res */
0130     unsigned int        t_blk_res;  /* # of blocks resvd */
0131     unsigned int        t_blk_res_used; /* # of resvd blocks used */
0132     unsigned int        t_rtx_res;  /* # of rt extents resvd */
0133     unsigned int        t_rtx_res_used; /* # of resvd rt extents used */
0134     unsigned int        t_flags;    /* misc flags */
0135     xfs_fsblock_t       t_firstblock;   /* first block allocated */
0136     struct xlog_ticket  *t_ticket;  /* log mgr ticket */
0137     struct xfs_mount    *t_mountp;  /* ptr to fs mount struct */
0138     struct xfs_dquot_acct   *t_dqinfo;  /* acctg info for dquots */
0139     int64_t         t_icount_delta; /* superblock icount change */
0140     int64_t         t_ifree_delta;  /* superblock ifree change */
0141     int64_t         t_fdblocks_delta; /* superblock fdblocks chg */
0142     int64_t         t_res_fdblocks_delta; /* on-disk only chg */
0143     int64_t         t_frextents_delta;/* superblock freextents chg*/
0144     int64_t         t_res_frextents_delta; /* on-disk only chg */
0145     int64_t         t_dblocks_delta;/* superblock dblocks change */
0146     int64_t         t_agcount_delta;/* superblock agcount change */
0147     int64_t         t_imaxpct_delta;/* superblock imaxpct change */
0148     int64_t         t_rextsize_delta;/* superblock rextsize chg */
0149     int64_t         t_rbmblocks_delta;/* superblock rbmblocks chg */
0150     int64_t         t_rblocks_delta;/* superblock rblocks change */
0151     int64_t         t_rextents_delta;/* superblocks rextents chg */
0152     int64_t         t_rextslog_delta;/* superblocks rextslog chg */
0153     struct list_head    t_items;    /* log item descriptors */
0154     struct list_head    t_busy;     /* list of busy extents */
0155     struct list_head    t_dfops;    /* deferred operations */
0156     unsigned long       t_pflags;   /* saved process flags state */
0157 } xfs_trans_t;
0158 
0159 /*
0160  * XFS transaction mechanism exported interfaces that are
0161  * actually macros.
0162  */
0163 #define xfs_trans_set_sync(tp)      ((tp)->t_flags |= XFS_TRANS_SYNC)
0164 
0165 /*
0166  * XFS transaction mechanism exported interfaces.
0167  */
0168 int     xfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp,
0169             uint blocks, uint rtextents, uint flags,
0170             struct xfs_trans **tpp);
0171 int     xfs_trans_alloc_empty(struct xfs_mount *mp,
0172             struct xfs_trans **tpp);
0173 void        xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t);
0174 
0175 int xfs_trans_get_buf_map(struct xfs_trans *tp, struct xfs_buftarg *target,
0176         struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags,
0177         struct xfs_buf **bpp);
0178 
0179 static inline int
0180 xfs_trans_get_buf(
0181     struct xfs_trans    *tp,
0182     struct xfs_buftarg  *target,
0183     xfs_daddr_t     blkno,
0184     int         numblks,
0185     xfs_buf_flags_t     flags,
0186     struct xfs_buf      **bpp)
0187 {
0188     DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
0189     return xfs_trans_get_buf_map(tp, target, &map, 1, flags, bpp);
0190 }
0191 
0192 int     xfs_trans_read_buf_map(struct xfs_mount *mp,
0193                        struct xfs_trans *tp,
0194                        struct xfs_buftarg *target,
0195                        struct xfs_buf_map *map, int nmaps,
0196                        xfs_buf_flags_t flags,
0197                        struct xfs_buf **bpp,
0198                        const struct xfs_buf_ops *ops);
0199 
0200 static inline int
0201 xfs_trans_read_buf(
0202     struct xfs_mount    *mp,
0203     struct xfs_trans    *tp,
0204     struct xfs_buftarg  *target,
0205     xfs_daddr_t     blkno,
0206     int         numblks,
0207     xfs_buf_flags_t     flags,
0208     struct xfs_buf      **bpp,
0209     const struct xfs_buf_ops *ops)
0210 {
0211     DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
0212     return xfs_trans_read_buf_map(mp, tp, target, &map, 1,
0213                       flags, bpp, ops);
0214 }
0215 
0216 struct xfs_buf  *xfs_trans_getsb(struct xfs_trans *);
0217 
0218 void        xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *);
0219 void        xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *);
0220 void        xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *);
0221 void        xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *);
0222 void        xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
0223 void        xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
0224 void        xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
0225 bool        xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *);
0226 void        xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
0227 void        xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
0228 void        xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
0229 void        xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
0230 void        xfs_trans_log_buf(struct xfs_trans *, struct xfs_buf *, uint,
0231                   uint);
0232 void        xfs_trans_dirty_buf(struct xfs_trans *, struct xfs_buf *);
0233 bool        xfs_trans_buf_is_dirty(struct xfs_buf *bp);
0234 void        xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
0235 
0236 int     xfs_trans_commit(struct xfs_trans *);
0237 int     xfs_trans_roll(struct xfs_trans **);
0238 int     xfs_trans_roll_inode(struct xfs_trans **, struct xfs_inode *);
0239 void        xfs_trans_cancel(xfs_trans_t *);
0240 int     xfs_trans_ail_init(struct xfs_mount *);
0241 void        xfs_trans_ail_destroy(struct xfs_mount *);
0242 
0243 void        xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *,
0244                        enum xfs_blft);
0245 void        xfs_trans_buf_copy_type(struct xfs_buf *dst_bp,
0246                     struct xfs_buf *src_bp);
0247 
0248 extern struct kmem_cache    *xfs_trans_cache;
0249 
0250 static inline struct xfs_log_item *
0251 xfs_trans_item_relog(
0252     struct xfs_log_item *lip,
0253     struct xfs_trans    *tp)
0254 {
0255     return lip->li_ops->iop_relog(lip, tp);
0256 }
0257 
0258 struct xfs_dquot;
0259 
0260 int xfs_trans_alloc_inode(struct xfs_inode *ip, struct xfs_trans_res *resv,
0261         unsigned int dblocks, unsigned int rblocks, bool force,
0262         struct xfs_trans **tpp);
0263 int xfs_trans_alloc_icreate(struct xfs_mount *mp, struct xfs_trans_res *resv,
0264         struct xfs_dquot *udqp, struct xfs_dquot *gdqp,
0265         struct xfs_dquot *pdqp, unsigned int dblocks,
0266         struct xfs_trans **tpp);
0267 int xfs_trans_alloc_ichange(struct xfs_inode *ip, struct xfs_dquot *udqp,
0268         struct xfs_dquot *gdqp, struct xfs_dquot *pdqp, bool force,
0269         struct xfs_trans **tpp);
0270 int xfs_trans_alloc_dir(struct xfs_inode *dp, struct xfs_trans_res *resv,
0271         struct xfs_inode *ip, unsigned int *dblocks,
0272         struct xfs_trans **tpp, int *nospace_error);
0273 
0274 static inline void
0275 xfs_trans_set_context(
0276     struct xfs_trans    *tp)
0277 {
0278     ASSERT(current->journal_info == NULL);
0279     tp->t_pflags = memalloc_nofs_save();
0280     current->journal_info = tp;
0281 }
0282 
0283 static inline void
0284 xfs_trans_clear_context(
0285     struct xfs_trans    *tp)
0286 {
0287     if (current->journal_info == tp) {
0288         memalloc_nofs_restore(tp->t_pflags);
0289         current->journal_info = NULL;
0290     }
0291 }
0292 
0293 static inline void
0294 xfs_trans_switch_context(
0295     struct xfs_trans    *old_tp,
0296     struct xfs_trans    *new_tp)
0297 {
0298     ASSERT(current->journal_info == old_tp);
0299     new_tp->t_pflags = old_tp->t_pflags;
0300     old_tp->t_pflags = 0;
0301     current->journal_info = new_tp;
0302 }
0303 
0304 #endif  /* __XFS_TRANS_H__ */