*/
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 */
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 */
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;
}
"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;
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__ */
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
#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);
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;
}
*/
kmem_zone_t *xfs_trans_zone;
-kmem_zone_t *xfs_log_item_desc_zone;
/*
* Initialize the precomputed transaction reservation values
/*
* 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);
}
/*
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);
}
/*
#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.
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);
}
/*
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;
}
/* 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)
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;
}
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)
progname);
ASSERT(0);
}
- }
+ }
}
static void
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)
struct xfs_btree_cur *cur,
xfs_fsblock_t bno)
{
- struct xfs_log_item_desc *lidp;
+ struct xfs_log_item *lip;
int i;
if (!cur)
}
/* 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;
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 *);