From: Dave Chinner Date: Thu, 28 Jun 2018 20:11:55 +0000 (-0500) Subject: xfs: get rid of the log item descriptor X-Git-Tag: v4.18.0-rc0~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2fdd378ad0b31a16e66ede25d352c4b5ed88c714;p=thirdparty%2Fxfsprogs-dev.git xfs: get rid of the log item descriptor Source kernel commit: e6631f85546c8ff8842f62c73be44ff502d4287a It's just a connector between a transaction and a log item. There's a 1:1 relationship between a log item descriptor and a log item, and a 1:1 relationship between a log item descriptor and a transaction. Both relationships are created and terminated at the same time, so why do we even have the descriptor? Replace it with a specific list_head in the log item and a new log item dirtied flag to replace the XFS_LID_DIRTY flag. Signed-Off-By: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig [darrick: fix up deferred agfl intent finish_item use of LID_DIRTY] Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Signed-off-by: Eric Sandeen --- diff --git a/include/xfs_trans.h b/include/xfs_trans.h index 2a7d1edcb..55648b83c 100644 --- a/include/xfs_trans.h +++ b/include/xfs_trans.h @@ -29,12 +29,15 @@ struct xfs_buf_map; */ typedef struct xfs_log_item { - struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ + struct list_head li_trans; /* transaction list */ + xfs_lsn_t li_lsn; /* last on-disk lsn */ struct xfs_mount *li_mountp; /* ptr to fs mount */ uint li_type; /* item type */ - xfs_lsn_t li_lsn; + unsigned long li_flags; /* misc flags */ } xfs_log_item_t; +#define XFS_LI_DIRTY 3 /* log item dirty in transaction */ + typedef struct xfs_inode_log_item { xfs_log_item_t ili_item; /* common portion */ struct xfs_inode *ili_inode; /* inode pointer */ diff --git a/libxfs/init.c b/libxfs/init.c index a65c86c34..a72764b1a 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -384,7 +384,6 @@ manage_zones(int release) extern kmem_zone_t *xfs_btree_cur_zone; extern kmem_zone_t *xfs_bmap_free_item_zone; extern kmem_zone_t *xfs_trans_zone; - extern kmem_zone_t *xfs_log_item_desc_zone; extern void xfs_dir_startup(); if (release) { /* free zone allocation */ @@ -399,7 +398,6 @@ manage_zones(int release) leaked += kmem_zone_destroy(xfs_btree_cur_zone); leaked += kmem_zone_destroy(xfs_bmap_free_item_zone); leaked += kmem_zone_destroy(xfs_trans_zone); - leaked += kmem_zone_destroy(xfs_log_item_desc_zone); return leaked; } @@ -420,8 +418,6 @@ manage_zones(int release) "xfs_bmap_free_item"); xfs_trans_zone = kmem_zone_init( sizeof(struct xfs_trans), "xfs_trans"); - xfs_log_item_desc_zone = kmem_zone_init( - sizeof(struct xfs_log_item_desc), "xfs_log_item_desc"); xfs_dir_startup(); return 0; diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 4a394d946..1508d9a21 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -573,4 +573,32 @@ bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t); typedef unsigned char u8; unsigned int hweight8(unsigned int w); +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) + +static inline void set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + *p |= mask; +} + +static inline void clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + *p &= ~mask; +} + +static inline int test_bit(int nr, const volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + return *p & mask; +} + + #endif /* __LIBXFS_INTERNAL_XFS_H__ */ diff --git a/libxfs/logitem.c b/libxfs/logitem.c index 39ac19232..09db63577 100644 --- a/libxfs/logitem.c +++ b/libxfs/logitem.c @@ -46,26 +46,26 @@ xfs_trans_buf_item_match( struct xfs_buf_map *map, int nmaps) { - struct xfs_log_item_desc *lidp; - struct xfs_buf_log_item *blip; + struct xfs_log_item *lip; + struct xfs_buf_log_item *blip; int len = 0; int i; for (i = 0; i < nmaps; i++) len += map[i].bm_len; - list_for_each_entry(lidp, &tp->t_items, lid_trans) { - blip = (struct xfs_buf_log_item *)lidp->lid_item; - if (blip->bli_item.li_type == XFS_LI_BUF && + list_for_each_entry(lip, &tp->t_items, li_trans) { + blip = (struct xfs_buf_log_item *)lip; + if (blip->bli_item.li_type == XFS_LI_BUF && blip->bli_buf->b_target->dev == btp->dev && XFS_BUF_ADDR(blip->bli_buf) == map[0].bm_bn && blip->bli_buf->b_bcount == BBTOB(len)) { ASSERT(blip->bli_buf->b_map_count == nmaps); - return blip->bli_buf; + return blip->bli_buf; } - } + } - return NULL; + return NULL; } /* * The following are from fs/xfs/xfs_buf_item.c @@ -117,6 +117,7 @@ xfs_buf_item_init( #endif bip->bli_item.li_type = XFS_LI_BUF; bip->bli_item.li_mountp = mp; + INIT_LIST_HEAD(&bip->bli_item.li_trans); bip->bli_buf = bp; bip->bli_format.blf_type = XFS_LI_BUF; bip->bli_format.blf_blkno = (int64_t)XFS_BUF_ADDR(bp); @@ -162,5 +163,6 @@ xfs_inode_item_init( iip->ili_item.li_type = XFS_LI_INODE; iip->ili_item.li_mountp = mp; + INIT_LIST_HEAD(&iip->ili_item.li_trans); iip->ili_inode = ip; } diff --git a/libxfs/trans.c b/libxfs/trans.c index 67b111759..80c89315e 100644 --- a/libxfs/trans.c +++ b/libxfs/trans.c @@ -37,7 +37,6 @@ static void xfs_trans_free_items(struct xfs_trans *tp); */ kmem_zone_t *xfs_trans_zone; -kmem_zone_t *xfs_log_item_desc_zone; /* * Initialize the precomputed transaction reservation values @@ -52,34 +51,18 @@ libxfs_trans_init( /* * Add the given log item to the transaction's list of log items. - * - * The log item will now point to its new descriptor with its li_desc field. */ void libxfs_trans_add_item( struct xfs_trans *tp, struct xfs_log_item *lip) { - struct xfs_log_item_desc *lidp; - ASSERT(lip->li_mountp == tp->t_mountp); ASSERT(lip->li_ailp == tp->t_mountp->m_ail); + ASSERT(list_empty(&lip->li_trans)); + ASSERT(!test_bit(XFS_LI_DIRTY, &lip->li_flags)); - lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS); - - lidp->lid_item = lip; - lidp->lid_flags = 0; - list_add_tail(&lidp->lid_trans, &tp->t_items); - - lip->li_desc = lidp; -} - -static void -libxfs_trans_free_item_desc( - struct xfs_log_item_desc *lidp) -{ - list_del_init(&lidp->lid_trans); - kmem_zone_free(xfs_log_item_desc_zone, lidp); + list_add_tail(&lip->li_trans, &tp->t_items); } /* @@ -89,8 +72,8 @@ void libxfs_trans_del_item( struct xfs_log_item *lip) { - libxfs_trans_free_item_desc(lip->li_desc); - lip->li_desc = NULL; + clear_bit(XFS_LI_DIRTY, &lip->li_flags); + list_del_init(&lip->li_trans); } /* @@ -338,7 +321,7 @@ xfs_trans_log_inode( #endif tp->t_flags |= XFS_TRANS_DIRTY; - ip->i_itemp->ili_item.li_desc->lid_flags |= XFS_LID_DIRTY; + set_bit(XFS_LI_DIRTY, &ip->i_itemp->ili_item.li_flags); /* * Always OR in the bits from the ili_last_fields field. @@ -383,7 +366,7 @@ libxfs_trans_dirty_buf( fprintf(stderr, "dirtied buffer %p, transaction %p\n", bp, tp); #endif tp->t_flags |= XFS_TRANS_DIRTY; - bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; + set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags); } /* @@ -425,7 +408,7 @@ libxfs_trans_ordered_buf( struct xfs_buf_log_item *bip = bp->b_log_item; bool ret; - ret = (bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY); + ret = test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags); libxfs_trans_log_buf(tp, bp, 0, bp->b_bcount); return ret; } @@ -455,7 +438,7 @@ libxfs_trans_brelse( /* If dirty/stale, can't release till transaction committed */ if (bip->bli_flags & XFS_BLI_STALE) return; - if (bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY) + if (test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags)) return; xfs_trans_del_item(&bip->bli_item); if (bip->bli_flags & XFS_BLI_HOLD) @@ -485,7 +468,7 @@ libxfs_trans_binval( bip->bli_flags &= ~XFS_BLI_DIRTY; bip->bli_format.blf_flags &= ~XFS_BLF_INODE_BUF; bip->bli_format.blf_flags |= XFS_BLF_CANCEL; - bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; + set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags); tp->t_flags |= XFS_TRANS_DIRTY; } @@ -788,11 +771,9 @@ static void trans_committed( xfs_trans_t *tp) { - struct xfs_log_item_desc *lidp, *next; - - list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { - struct xfs_log_item *lip = lidp->lid_item; + struct xfs_log_item *lip, *next; + list_for_each_entry_safe(lip, next, &tp->t_items, li_trans) { xfs_trans_del_item(lip); if (lip->li_type == XFS_LI_BUF) @@ -804,7 +785,7 @@ trans_committed( progname); ASSERT(0); } - } + } } static void @@ -835,20 +816,15 @@ inode_item_unlock( iip->ili_flags = 0; } -/* - * Unlock all of the items of a transaction and free all the descriptors - * of that transaction. - */ +/* Detach and unlock all of the items in a transaction */ static void xfs_trans_free_items( struct xfs_trans *tp) { - struct xfs_log_item_desc *lidp, *next; - - list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { - struct xfs_log_item *lip = lidp->lid_item; + struct xfs_log_item *lip, *next; - xfs_trans_del_item(lip); + list_for_each_entry_safe(lip, next, &tp->t_items, li_trans) { + xfs_trans_del_item(lip); if (lip->li_type == XFS_LI_BUF) buf_item_unlock((xfs_buf_log_item_t *)lip); else if (lip->li_type == XFS_LI_INODE) diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index b1a4e0b46..ebd367142 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -237,7 +237,7 @@ xfs_bmap_get_bp( struct xfs_btree_cur *cur, xfs_fsblock_t bno) { - struct xfs_log_item_desc *lidp; + struct xfs_log_item *lip; int i; if (!cur) @@ -251,9 +251,9 @@ xfs_bmap_get_bp( } /* Chase down all the log items to see if the bp is there */ - list_for_each_entry(lidp, &cur->bc_tp->t_items, lid_trans) { - struct xfs_buf_log_item *bip; - bip = (struct xfs_buf_log_item *)lidp->lid_item; + list_for_each_entry(lip, &cur->bc_tp->t_items, li_trans) { + struct xfs_buf_log_item *bip = (struct xfs_buf_log_item *)lip; + if (bip->bli_item.li_type == XFS_LI_BUF && XFS_BUF_ADDR(bip->bli_buf) == bno) return bip->bli_buf; diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h index d0b84da0c..8efc06e62 100644 --- a/libxfs/xfs_shared.h +++ b/libxfs/xfs_shared.h @@ -57,21 +57,6 @@ extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops; extern const struct xfs_buf_ops xfs_symlink_buf_ops; extern const struct xfs_buf_ops xfs_rtbuf_ops; -/* - * This structure is used to track log items associated with - * a transaction. It points to the log item and keeps some - * flags to track the state of the log item. It also tracks - * the amount of space needed to log the item it describes - * once we get to commit processing (see xfs_trans_commit()). - */ -struct xfs_log_item_desc { - struct xfs_log_item *lid_item; - struct list_head lid_trans; - unsigned char lid_flags; -}; - -#define XFS_LID_DIRTY 0x1 - /* log size calculation functions */ int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes); int xfs_log_calc_minimum_size(struct xfs_mount *);