/* * This is called to create a new transaction which will share the * permanent log reservation of the given transaction. The remaining * unused block and rt extent reservations are also inherited. This * implies that the original transaction is no longer allowed to allocate * blocks. Locks and log items, however, are no inherited. They must * be added to the new transaction explicitly. */ xfs_trans_t * xfs_trans_dup( xfs_trans_t *tp) { xfs_trans_t *ntp; ntp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP); /* * Initialize the new transaction structure. */ ntp->t_magic = XFS_TRANS_MAGIC; ntp->t_type = tp->t_type; ntp->t_mountp = tp->t_mountp; ntp->t_items_free = XFS_LIC_NUM_SLOTS; ntp->t_busy_free = XFS_LBC_NUM_SLOTS; XFS_LIC_INIT(&(ntp->t_items)); XFS_LBC_INIT(&(ntp->t_busy)); ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); ASSERT(tp->t_ticket != NULL); ntp->t_flags = XFS_TRANS_PERM_LOG_RES | (tp->t_flags & XFS_TRANS_RESERVE); ntp->t_ticket = tp->t_ticket; ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used; tp->t_blk_res = tp->t_blk_res_used; ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; tp->t_rtx_res = tp->t_rtx_res_used; PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags); XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp); atomic_inc(&tp->t_mountp->m_active_trans); return ntp; }
xfs_trans_t * _xfs_trans_alloc( xfs_mount_t *mp, uint type) { xfs_trans_t *tp; atomic_inc(&mp->m_active_trans); tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP); tp->t_magic = XFS_TRANS_MAGIC; tp->t_type = type; tp->t_mountp = mp; tp->t_items_free = XFS_LIC_NUM_SLOTS; tp->t_busy_free = XFS_LBC_NUM_SLOTS; XFS_LIC_INIT(&(tp->t_items)); XFS_LBC_INIT(&(tp->t_busy)); return tp; }
xfs_trans_t * _xfs_trans_alloc( xfs_mount_t *mp, uint type) { xfs_trans_t *tp; ASSERT(xfs_trans_zone != NULL); tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP); /* * Initialize the transaction structure. */ tp->t_magic = XFS_TRANS_MAGIC; tp->t_type = type; tp->t_mountp = mp; tp->t_items_free = XFS_LIC_NUM_SLOTS; tp->t_busy_free = XFS_LBC_NUM_SLOTS; XFS_LIC_INIT(&(tp->t_items)); XFS_LBC_INIT(&(tp->t_busy)); return (tp); }
void xfs_lic_init(xfs_log_item_chunk_t *cp) { XFS_LIC_INIT(cp); }
/* * This is called to add the given log item to the transaction's * list of log items. It must find a free log item descriptor * or allocate a new one and add the item to that descriptor. * The function returns a pointer to item descriptor used to point * to the new item. The log item will now point to its new descriptor * with its li_desc field. */ xfs_log_item_desc_t * xfs_trans_add_item(xfs_trans_t *tp, xfs_log_item_t *lip) { xfs_log_item_desc_t *lidp; xfs_log_item_chunk_t *licp; int i=0; /* * If there are no free descriptors, allocate a new chunk * of them and put it at the front of the chunk list. */ if (tp->t_items_free == 0) { licp = (xfs_log_item_chunk_t*) kmem_alloc(sizeof(xfs_log_item_chunk_t), KM_SLEEP); ASSERT(licp != NULL); /* * Initialize the chunk, and then * claim the first slot in the newly allocated chunk. */ XFS_LIC_INIT(licp); XFS_LIC_CLAIM(licp, 0); licp->lic_unused = 1; XFS_LIC_INIT_SLOT(licp, 0); lidp = XFS_LIC_SLOT(licp, 0); /* * Link in the new chunk and update the free count. */ licp->lic_next = tp->t_items.lic_next; tp->t_items.lic_next = licp; tp->t_items_free = XFS_LIC_NUM_SLOTS - 1; /* * Initialize the descriptor and the generic portion * of the log item. * * Point the new slot at this item and return it. * Also point the log item at its currently active * descriptor and set the item's mount pointer. */ lidp->lid_item = lip; lidp->lid_flags = 0; lidp->lid_size = 0; lip->li_desc = lidp; lip->li_mountp = tp->t_mountp; return lidp; } /* * Find the free descriptor. It is somewhere in the chunklist * of descriptors. */ licp = &tp->t_items; while (licp != NULL) { if (XFS_LIC_VACANCY(licp)) { if (licp->lic_unused <= XFS_LIC_MAX_SLOT) { i = licp->lic_unused; ASSERT(XFS_LIC_ISFREE(licp, i)); break; } for (i = 0; i <= XFS_LIC_MAX_SLOT; i++) { if (XFS_LIC_ISFREE(licp, i)) break; } ASSERT(i <= XFS_LIC_MAX_SLOT); break; } licp = licp->lic_next; } ASSERT(licp != NULL); /* * If we find a free descriptor, claim it, * initialize it, and return it. */ XFS_LIC_CLAIM(licp, i); if (licp->lic_unused <= i) { licp->lic_unused = i + 1; XFS_LIC_INIT_SLOT(licp, i); } lidp = XFS_LIC_SLOT(licp, i); tp->t_items_free--; lidp->lid_item = lip; lidp->lid_flags = 0; lidp->lid_size = 0; lip->li_desc = lidp; lip->li_mountp = tp->t_mountp; return lidp; }