int libxfs_bmap_finish( xfs_trans_t **tp, xfs_bmap_free_t *flist, xfs_fsblock_t firstblock, int *committed) { xfs_bmap_free_item_t *free; /* free extent list item */ xfs_bmap_free_item_t *next; /* next item on free list */ int error; xfs_trans_t *ntp; if (flist->xbf_count == 0) { *committed = 0; return 0; } for (free = flist->xbf_first; free != NULL; free = next) { next = free->xbfi_next; if (error = xfs_free_extent(*tp, free->xbfi_startblock, free->xbfi_blockcount)) return error; xfs_bmap_del_free(flist, NULL, free); } return 0; }
int libxfs_bmap_finish( struct xfs_trans **tp, struct xfs_bmap_free *flist, struct xfs_inode *ip) { xfs_bmap_free_item_t *free; /* free extent list item */ xfs_bmap_free_item_t *next; /* next item on free list */ int error; if (flist->xbf_count == 0) return 0; for (free = flist->xbf_first; free != NULL; free = next) { next = free->xbfi_next; error = xfs_free_extent(*tp, free->xbfi_startblock, free->xbfi_blockcount); if (error) return error; xfs_bmap_del_free(flist, NULL, free); } return 0; }
/* * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi * caller. Frees all the extents that need freeing, which must be done * last due to locking considerations. We never free any extents in * the first transaction. * * Return 1 if the given transaction was committed and a new one * started, and 0 otherwise in the committed parameter. */ int /* error */ xfs_bmap_finish( xfs_trans_t **tp, /* transaction pointer addr */ xfs_bmap_free_t *flist, /* i/o: list extents to free */ int *committed) /* xact committed or not */ { xfs_efd_log_item_t *efd; /* extent free data */ xfs_efi_log_item_t *efi; /* extent free intention */ int error; /* error return value */ xfs_bmap_free_item_t *free; /* free extent item */ struct xfs_trans_res tres; /* new log reservation */ xfs_mount_t *mp; /* filesystem mount structure */ xfs_bmap_free_item_t *next; /* next item on free list */ xfs_trans_t *ntp; /* new transaction pointer */ ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); if (flist->xbf_count == 0) { *committed = 0; return 0; } ntp = *tp; efi = xfs_trans_get_efi(ntp, flist->xbf_count); for (free = flist->xbf_first; free; free = free->xbfi_next) xfs_trans_log_efi_extent(ntp, efi, free->xbfi_startblock, free->xbfi_blockcount); tres.tr_logres = ntp->t_log_res; tres.tr_logcount = ntp->t_log_count; tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; ntp = xfs_trans_dup(*tp); error = xfs_trans_commit(*tp, 0); *tp = ntp; *committed = 1; /* * We have a new transaction, so we should return committed=1, * even though we're returning an error. */ if (error) return error; /* * transaction commit worked ok so we can drop the extra ticket * reference that we gained in xfs_trans_dup() */ xfs_log_ticket_put(ntp->t_ticket); error = xfs_trans_reserve(ntp, &tres, 0, 0); if (error) return error; efd = xfs_trans_get_efd(ntp, efi, flist->xbf_count); for (free = flist->xbf_first; free != NULL; free = next) { next = free->xbfi_next; if ((error = xfs_free_extent(ntp, free->xbfi_startblock, free->xbfi_blockcount))) { /* * The bmap free list will be cleaned up at a * higher level. The EFI will be canceled when * this transaction is aborted. * Need to force shutdown here to make sure it * happens, since this transaction may not be * dirty yet. */ mp = ntp->t_mountp; if (!XFS_FORCED_SHUTDOWN(mp)) xfs_force_shutdown(mp, (error == EFSCORRUPTED) ? SHUTDOWN_CORRUPT_INCORE : SHUTDOWN_META_IO_ERROR); return error; } xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, free->xbfi_blockcount); xfs_bmap_del_free(flist, NULL, free); } return 0; }