/*ARGSUSED*/ xfs_log_item_desc_t * xfs_trans_next_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp) { xfs_log_item_chunk_t *licp; int i; licp = XFS_LIC_DESC_TO_CHUNK(lidp); /* * First search the rest of the chunk. The for loop keeps us * from referencing things beyond the end of the chunk. */ for (i = (int)XFS_LIC_DESC_TO_SLOT(lidp) + 1; i < licp->lic_unused; i++) { if (XFS_LIC_ISFREE(licp, i)) { continue; } return XFS_LIC_SLOT(licp, i); } /* * Now search the next chunk. It must be there, because the * next chunk would have been freed if it were empty. * If there is no next chunk, return NULL. */ if (licp->lic_next == NULL) { return NULL; } licp = licp->lic_next; ASSERT(!XFS_LIC_ARE_ALL_FREE(licp)); for (i = 0; i < licp->lic_unused; i++) { if (XFS_LIC_ISFREE(licp, i)) { continue; } return XFS_LIC_SLOT(licp, i); } ASSERT(0); /* NOTREACHED */ return NULL; /* keep gcc quite */ }
/* * Free the given descriptor. * * This requires setting the bit in the chunk's free mask corresponding * to the given slot. */ void xfs_trans_free_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp) { uint slot; xfs_log_item_chunk_t *licp; xfs_log_item_chunk_t **licpp; slot = XFS_LIC_DESC_TO_SLOT(lidp); licp = XFS_LIC_DESC_TO_CHUNK(lidp); XFS_LIC_RELSE(licp, slot); lidp->lid_item->li_desc = NULL; tp->t_items_free++; /* * If there are no more used items in the chunk and this is not * the chunk embedded in the transaction structure, then free * the chunk. First pull it from the chunk list and then * free it back to the heap. We didn't bother with a doubly * linked list here because the lists should be very short * and this is not a performance path. It's better to save * the memory of the extra pointer. * * Also decrement the transaction structure's count of free items * by the number in a chunk since we are freeing an empty chunk. */ if (XFS_LIC_ARE_ALL_FREE(licp) && (licp != &(tp->t_items))) { licpp = &(tp->t_items.lic_next); while (*licpp != licp) { ASSERT(*licpp != NULL); licpp = &((*licpp)->lic_next); } *licpp = licp->lic_next; kmem_free(licp, sizeof(xfs_log_item_chunk_t)); tp->t_items_free -= XFS_LIC_NUM_SLOTS; } }
int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp) { return XFS_LIC_DESC_TO_SLOT(dp); }