/* * Allocate and initialize an efi item with the given number of extents. */ struct xfs_efi_log_item * xfs_efi_init( struct xfs_mount *mp, uint nextents) { struct xfs_efi_log_item *efip; uint size; ASSERT(nextents > 0); if (nextents > XFS_EFI_MAX_FAST_EXTENTS) { size = (uint)(sizeof(xfs_efi_log_item_t) + ((nextents - 1) * sizeof(xfs_extent_t))); efip = kmem_zalloc(size, KM_SLEEP); } else { efip = kmem_zone_zalloc(xfs_efi_zone, KM_SLEEP); } xfs_log_item_init(mp, &efip->efi_item, XFS_LI_EFI, &xfs_efi_item_ops); efip->efi_format.efi_nextents = nextents; efip->efi_format.efi_id = (__psint_t)(void*)efip; atomic_set(&efip->efi_next_extent, 0); return efip; }
/* * Allocate and initialize an efd item with the given number of extents. */ struct xfs_efd_log_item * xfs_efd_init( struct xfs_mount *mp, struct xfs_efi_log_item *efip, uint nextents) { struct xfs_efd_log_item *efdp; uint size; ASSERT(nextents > 0); if (nextents > XFS_EFD_MAX_FAST_EXTENTS) { size = (uint)(sizeof(xfs_efd_log_item_t) + ((nextents - 1) * sizeof(xfs_extent_t))); efdp = kmem_zalloc(size, KM_SLEEP); } else { efdp = kmem_zone_zalloc(xfs_efd_zone, KM_SLEEP); } xfs_log_item_init(mp, &efdp->efd_item, XFS_LI_EFD, &xfs_efd_item_ops); efdp->efd_efip = efip; efdp->efd_format.efd_nextents = nextents; efdp->efd_format.efd_efi_id = efip->efi_format.efi_id; return efdp; }
/* * Initialize the inode log item for a newly allocated (in-core) inode. * * Inode extents can only reside within an AG. Hence specify the starting * block for the inode chunk by offset within an AG as well as the * length of the allocated extent. * * This joins the item to the transaction and marks it dirty so * that we don't need a separate call to do this, nor does the * caller need to know anything about the icreate item. */ void xfs_icreate_log( struct xfs_trans *tp, xfs_agnumber_t agno, xfs_agblock_t agbno, unsigned int count, unsigned int inode_size, xfs_agblock_t length, unsigned int generation) { struct xfs_icreate_item *icp; icp = kmem_zone_zalloc(xfs_icreate_zone, KM_SLEEP); xfs_log_item_init(tp->t_mountp, &icp->ic_item, XFS_LI_ICREATE, &xfs_icreate_item_ops); icp->ic_format.icl_type = XFS_LI_ICREATE; icp->ic_format.icl_size = 1; /* single vector */ icp->ic_format.icl_ag = cpu_to_be32(agno); icp->ic_format.icl_agbno = cpu_to_be32(agbno); icp->ic_format.icl_count = cpu_to_be32(count); icp->ic_format.icl_isize = cpu_to_be32(inode_size); icp->ic_format.icl_length = cpu_to_be32(length); icp->ic_format.icl_gen = cpu_to_be32(generation); xfs_trans_add_item(tp, &icp->ic_item); tp->t_flags |= XFS_TRANS_DIRTY; icp->ic_item.li_desc->lid_flags |= XFS_LID_DIRTY; }
/* * Allocate a new buf log item to go with the given buffer. * Set the buffer's b_fsprivate field to point to the new * buf log item. If there are other item's attached to the * buffer (see xfs_buf_attach_iodone() below), then put the * buf log item at the front. */ void xfs_buf_item_init( xfs_buf_t *bp, xfs_mount_t *mp) { xfs_log_item_t *lip = bp->b_fspriv; xfs_buf_log_item_t *bip; int chunks; int map_size; int error; int i; /* * Check to see if there is already a buf log item for * this buffer. If there is, it is guaranteed to be * the first. If we do already have one, there is * nothing to do here so return. */ ASSERT(bp->b_target->bt_mount == mp); if (lip != NULL && lip->li_type == XFS_LI_BUF) return; bip = kmem_zone_zalloc(xfs_buf_item_zone, KM_SLEEP); xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops); bip->bli_buf = bp; xfs_buf_hold(bp); /* * chunks is the number of XFS_BLF_CHUNK size pieces the buffer * can be divided into. Make sure not to truncate any pieces. * map_size is the size of the bitmap needed to describe the * chunks of the buffer. * * Discontiguous buffer support follows the layout of the underlying * buffer. This makes the implementation as simple as possible. */ error = xfs_buf_item_get_format(bip, bp->b_map_count); ASSERT(error == 0); for (i = 0; i < bip->bli_format_count; i++) { chunks = DIV_ROUND_UP(BBTOB(bp->b_maps[i].bm_len), XFS_BLF_CHUNK); map_size = DIV_ROUND_UP(chunks, NBWORD); bip->bli_formats[i].blf_type = XFS_LI_BUF; bip->bli_formats[i].blf_blkno = bp->b_maps[i].bm_bn; bip->bli_formats[i].blf_len = bp->b_maps[i].bm_len; bip->bli_formats[i].blf_map_size = map_size; } /* * Put the buf item into the list of items attached to the * buffer at the front. */ if (bp->b_fspriv) bip->bli_item.li_bio_list = bp->b_fspriv; bp->b_fspriv = bip; }
/* * Initialize the inode log item for a newly allocated (in-core) inode. */ void xfs_inode_item_init( struct xfs_inode *ip, struct xfs_mount *mp) { struct xfs_inode_log_item *iip; ASSERT(ip->i_itemp == NULL); iip = ip->i_itemp = kmem_zone_zalloc(xfs_ili_zone, KM_SLEEP); iip->ili_inode = ip; xfs_log_item_init(mp, &iip->ili_item, XFS_LI_INODE, &xfs_inode_item_ops); }
/* * Allocate and initialize an bud item with the given number of extents. */ struct xfs_bud_log_item * xfs_bud_init( struct xfs_mount *mp, struct xfs_bui_log_item *buip) { struct xfs_bud_log_item *budp; budp = kmem_zone_zalloc(xfs_bud_zone, KM_SLEEP); xfs_log_item_init(mp, &budp->bud_item, XFS_LI_BUD, &xfs_bud_item_ops); budp->bud_buip = buip; budp->bud_format.bud_bui_id = buip->bui_format.bui_id; return budp; }
/* * Allocate and initialize an cud item with the given number of extents. */ struct xfs_cud_log_item * xfs_cud_init( struct xfs_mount *mp, struct xfs_cui_log_item *cuip) { struct xfs_cud_log_item *cudp; cudp = kmem_zone_zalloc(xfs_cud_zone, KM_SLEEP); xfs_log_item_init(mp, &cudp->cud_item, XFS_LI_CUD, &xfs_cud_item_ops); cudp->cud_cuip = cuip; cudp->cud_format.cud_cui_id = cuip->cui_format.cui_id; return cudp; }
/* * Allocate and initialize an bui item with the given number of extents. */ struct xfs_bui_log_item * xfs_bui_init( struct xfs_mount *mp) { struct xfs_bui_log_item *buip; buip = kmem_zone_zalloc(xfs_bui_zone, KM_SLEEP); xfs_log_item_init(mp, &buip->bui_item, XFS_LI_BUI, &xfs_bui_item_ops); buip->bui_format.bui_nextents = XFS_BUI_MAX_FAST_EXTENTS; buip->bui_format.bui_id = (uintptr_t)(void *)buip; atomic_set(&buip->bui_next_extent, 0); atomic_set(&buip->bui_refcount, 2); return buip; }
/* * Allocate and initialize an quotaoff item of the correct quota type(s). */ struct xfs_qoff_logitem * xfs_qm_qoff_logitem_init( struct xfs_mount *mp, struct xfs_qoff_logitem *start, uint flags) { struct xfs_qoff_logitem *qf; qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), KM_SLEEP); xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ? &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops); qf->qql_item.li_mountp = mp; qf->qql_format.qf_type = XFS_LI_QUOTAOFF; qf->qql_format.qf_flags = flags; qf->qql_start_lip = start; return qf; }
/* * Initialize the inode log item for a newly allocated (in-core) inode. */ void xfs_inode_item_init( struct xfs_inode *ip, struct xfs_mount *mp) { struct xfs_inode_log_item *iip; ASSERT(ip->i_itemp == NULL); iip = ip->i_itemp = kmem_zone_zalloc(xfs_ili_zone, KM_SLEEP); iip->ili_inode = ip; xfs_log_item_init(mp, &iip->ili_item, XFS_LI_INODE, &xfs_inode_item_ops); iip->ili_format.ilf_type = XFS_LI_INODE; iip->ili_format.ilf_ino = ip->i_ino; iip->ili_format.ilf_blkno = ip->i_imap.im_blkno; iip->ili_format.ilf_len = ip->i_imap.im_len; iip->ili_format.ilf_boffset = ip->i_imap.im_boffset; }
/* * Initialize the dquot log item for a newly allocated dquot. * The dquot isn't locked at this point, but it isn't on any of the lists * either, so we don't care. */ void xfs_qm_dquot_logitem_init( struct xfs_dquot *dqp) { struct xfs_dq_logitem *lp = &dqp->q_logitem; xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT, &xfs_dquot_item_ops); lp->qli_dquot = dqp; lp->qli_format.qlf_type = XFS_LI_DQUOT; lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id); lp->qli_format.qlf_blkno = dqp->q_blkno; lp->qli_format.qlf_len = 1; /* * This is just the offset of this dquot within its buffer * (which is currently 1 FSB and probably won't change). * Hence 32 bits for this offset should be just fine. * Alternatively, we can store (bufoffset / sizeof(xfs_dqblk_t)) * here, and recompute it at recovery time. */ lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset; }
/* * Allocate and initialize an cui item with the given number of extents. */ struct xfs_cui_log_item * xfs_cui_init( struct xfs_mount *mp, uint nextents) { struct xfs_cui_log_item *cuip; ASSERT(nextents > 0); if (nextents > XFS_CUI_MAX_FAST_EXTENTS) cuip = kmem_zalloc(xfs_cui_log_item_sizeof(nextents), KM_SLEEP); else cuip = kmem_zone_zalloc(xfs_cui_zone, KM_SLEEP); xfs_log_item_init(mp, &cuip->cui_item, XFS_LI_CUI, &xfs_cui_item_ops); cuip->cui_format.cui_nextents = nextents; cuip->cui_format.cui_id = (uintptr_t)(void *)cuip; atomic_set(&cuip->cui_next_extent, 0); atomic_set(&cuip->cui_refcount, 2); return cuip; }
/* * Allocate a new buf log item to go with the given buffer. * Set the buffer's b_fsprivate field to point to the new * buf log item. If there are other item's attached to the * buffer (see xfs_buf_attach_iodone() below), then put the * buf log item at the front. */ void xfs_buf_item_init( xfs_buf_t *bp, xfs_mount_t *mp) { xfs_log_item_t *lip = bp->b_fspriv; xfs_buf_log_item_t *bip; int chunks; int map_size; int error; int i; /* * Check to see if there is already a buf log item for * this buffer. If there is, it is guaranteed to be * the first. If we do already have one, there is * nothing to do here so return. */ ASSERT(bp->b_target->bt_mount == mp); if (lip != NULL && lip->li_type == XFS_LI_BUF) return; bip = kmem_zone_zalloc(xfs_buf_item_zone, KM_SLEEP); xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops); bip->bli_buf = bp; xfs_buf_hold(bp); /* * chunks is the number of XFS_BLF_CHUNK size pieces the buffer * can be divided into. Make sure not to truncate any pieces. * map_size is the size of the bitmap needed to describe the * chunks of the buffer. * * Discontiguous buffer support follows the layout of the underlying * buffer. This makes the implementation as simple as possible. */ error = xfs_buf_item_get_format(bip, bp->b_map_count); ASSERT(error == 0); for (i = 0; i < bip->bli_format_count; i++) { chunks = DIV_ROUND_UP(BBTOB(bp->b_maps[i].bm_len), XFS_BLF_CHUNK); map_size = DIV_ROUND_UP(chunks, NBWORD); bip->bli_formats[i].blf_type = XFS_LI_BUF; bip->bli_formats[i].blf_blkno = bp->b_maps[i].bm_bn; bip->bli_formats[i].blf_len = bp->b_maps[i].bm_len; bip->bli_formats[i].blf_map_size = map_size; } #ifdef XFS_TRANS_DEBUG /* * Allocate the arrays for tracking what needs to be logged * and what our callers request to be logged. bli_orig * holds a copy of the original, clean buffer for comparison * against, and bli_logged keeps a 1 bit flag per byte in * the buffer to indicate which bytes the callers have asked * to have logged. */ bip->bli_orig = kmem_alloc(BBTOB(bp->b_length), KM_SLEEP); memcpy(bip->bli_orig, bp->b_addr, BBTOB(bp->b_length)); bip->bli_logged = kmem_zalloc(BBTOB(bp->b_length) / NBBY, KM_SLEEP); #endif /* * Put the buf item into the list of items attached to the * buffer at the front. */ if (bp->b_fspriv) bip->bli_item.li_bio_list = bp->b_fspriv; bp->b_fspriv = bip; }