/* * Freeing the XMI requires that we remove it from the AIL if it has already * been placed there. However, the XMI may not yet have been placed in the AIL * when called by xfs_xmi_release() from XMD processing due to the ordering of * committed vs unpin operations in bulk insert operations. Hence the reference * count to ensure only the last caller frees the XMI.
*/ STATICvoid
xfs_xmi_release( struct xfs_xmi_log_item *xmi_lip)
{
ASSERT(atomic_read(&xmi_lip->xmi_refcount) > 0); if (atomic_dec_and_test(&xmi_lip->xmi_refcount)) {
xfs_trans_ail_delete(&xmi_lip->xmi_item, 0);
xfs_xmi_item_free(xmi_lip);
}
}
STATICvoid
xfs_xmi_item_size( struct xfs_log_item *lip, int *nvecs, int *nbytes)
{
*nvecs += 1;
*nbytes += sizeof(struct xfs_xmi_log_format);
}
/* * This is called to fill in the vector of log iovecs for the given xmi log * item. We use only 1 iovec, and we point that at the xmi_log_format structure * embedded in the xmi item.
*/ STATICvoid
xfs_xmi_item_format( struct xfs_log_item *lip, struct xfs_log_vec *lv)
{ struct xfs_xmi_log_item *xmi_lip = XMI_ITEM(lip); struct xfs_log_iovec *vecp = NULL;
/* * The unpin operation is the last place an XMI is manipulated in the log. It * is either inserted in the AIL or aborted in the event of a log I/O error. In * either case, the XMI transaction has been successfully committed to make it * this far. Therefore, we expect whoever committed the XMI to either construct * and commit the XMD or drop the XMD's reference in the event of error. Simply * drop the log's XMI reference now that the log is done with it.
*/ STATICvoid
xfs_xmi_item_unpin( struct xfs_log_item *lip, int remove)
{ struct xfs_xmi_log_item *xmi_lip = XMI_ITEM(lip);
xfs_xmi_release(xmi_lip);
}
/* * The XMI has been either committed or aborted if the transaction has been * cancelled. If the transaction was cancelled, an XMD isn't going to be * constructed and thus we free the XMI here directly.
*/ STATICvoid
xfs_xmi_item_release( struct xfs_log_item *lip)
{
xfs_xmi_release(XMI_ITEM(lip));
}
/* Allocate and initialize an xmi item. */ STATICstruct xfs_xmi_log_item *
xfs_xmi_init( struct xfs_mount *mp)
STATICvoid
xfs_xmd_item_size( struct xfs_log_item *lip, int *nvecs, int *nbytes)
{
*nvecs += 1;
*nbytes += sizeof(struct xfs_xmd_log_format);
}
/* * This is called to fill in the vector of log iovecs for the given xmd log * item. We use only 1 iovec, and we point that at the xmd_log_format structure * embedded in the xmd item.
*/ STATICvoid
xfs_xmd_item_format( struct xfs_log_item *lip, struct xfs_log_vec *lv)
{ struct xfs_xmd_log_item *xmd_lip = XMD_ITEM(lip); struct xfs_log_iovec *vecp = NULL;
/* * The XMD is either committed or aborted if the transaction is cancelled. If * the transaction is cancelled, drop our reference to the XMI and free the * XMD.
*/ STATICvoid
xfs_xmd_item_release( struct xfs_log_item *lip)
{ struct xfs_xmd_log_item *xmd_lip = XMD_ITEM(lip);
/* Process a deferred file mapping exchange. */ STATICint
xfs_exchmaps_finish_item( struct xfs_trans *tp, struct xfs_log_item *done, struct list_head *item, struct xfs_btree_cur **state)
{ struct xfs_exchmaps_intent *xmi = xmi_entry(item); int error;
/* * Exchange one more mappings between two files. If there's still more * work to do, we want to requeue ourselves after all other pending * deferred operations have finished. This includes all of the dfops * that we queued directly as well as any new ones created in the * process of finishing the others. Doing so prevents us from queuing * a large number of XMI log items in kernel memory, which in turn * prevents us from pinning the tail of the log (while logging those * new XMI items) until the first XMI items can be processed.
*/
error = xfs_exchmaps_finish_one(tp, xmi); if (error != -EAGAIN)
xfs_exchmaps_cancel_item(item); return error;
}
/* * Use the recovered log state to create a new request, estimate resource * requirements, and create a new incore intent state.
*/ STATICstruct xfs_exchmaps_intent *
xfs_xmi_item_recover_intent( struct xfs_mount *mp, struct xfs_defer_pending *dfp, conststruct xfs_xmi_log_format *xlf, struct xfs_exchmaps_req *req, struct xfs_inode **ipp1, struct xfs_inode **ipp2)
{ struct xfs_inode *ip1, *ip2; struct xfs_exchmaps_intent *xmi; int error;
/* * Grab both inodes and set IRECOVERY to prevent trimming of post-eof * mappings and freeing of unlinked inodes until we're totally done * processing files. The ondisk format of this new log item contains * file handle information, which is why recovery for other items do * not check the inode generation number.
*/
error = xlog_recover_iget_handle(mp, xlf->xmi_inode1, xlf->xmi_igen1,
&ip1); if (error) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, xlf, sizeof(*xlf)); return ERR_PTR(error);
}
/* * Commit transaction, which frees the transaction and saves the inodes * for later replay activities.
*/
error = xfs_defer_ops_capture_and_commit(tp, capture_list); goto err_unlock;
/* * This routine is called to create an in-core file mapping exchange item from * the xmi format structure which was logged on disk. It allocates an in-core * xmi, copies the exchange information from the format structure into it, and * adds the xmi to the AIL with the given LSN.
*/ STATICint
xlog_recover_xmi_commit_pass2( struct xlog *log, struct list_head *buffer_list, struct xlog_recover_item *item,
xfs_lsn_t lsn)
{ struct xfs_mount *mp = log->l_mp; struct xfs_xmi_log_item *xmi_lip; struct xfs_xmi_log_format *xmi_formatp;
size_t len;
len = sizeof(struct xfs_xmi_log_format); if (item->ri_buf[0].iov_len != len) {
XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); return -EFSCORRUPTED;
}
/* * This routine is called when an XMD format structure is found in a committed * transaction in the log. Its purpose is to cancel the corresponding XMI if it * was still in the log. To do this it searches the AIL for the XMI with an id * equal to that in the XMD format structure. If we find it we drop the XMD * reference, which removes the XMI from the AIL and frees it.
*/ STATICint
xlog_recover_xmd_commit_pass2( struct xlog *log, struct list_head *buffer_list, struct xlog_recover_item *item,
xfs_lsn_t lsn)
{ struct xfs_xmd_log_format *xmd_formatp;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.