/* * Look up the inode cluster buffer and log the on-disk unlinked inode change * we need to make.
*/ staticint
xfs_iunlink_log_dinode( struct xfs_trans *tp, struct xfs_iunlink_item *iup)
{ struct xfs_inode *ip = iup->ip; struct xfs_dinode *dip; struct xfs_buf *ibp;
xfs_agino_t old_ptr; int offset; int error;
error = xfs_imap_to_bp(tp->t_mountp, tp, &ip->i_imap, &ibp); if (error) return error; /* * Don't log the unlinked field on stale buffers as this may be the * transaction that frees the inode cluster and relogging the buffer * here will incorrectly remove the stale state.
*/ if (ibp->b_flags & XBF_STALE) goto out;
dip = xfs_buf_offset(ibp, ip->i_imap.im_boffset);
/* Make sure the old pointer isn't garbage. */
old_ptr = be32_to_cpu(dip->di_next_unlinked); if (old_ptr != iup->old_agino) {
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, sizeof(*dip), __this_address);
error = -EFSCORRUPTED; goto out;
}
/* * On precommit, we grab the inode cluster buffer for the inode number we were * passed, then update the next unlinked field for that inode in the buffer and * log the buffer. This ensures that the inode cluster buffer was logged in the * correct order w.r.t. other inode cluster buffers. We can then remove the * iunlink item from the transaction and release it as it is has now served it's * purpose.
*/ staticint
xfs_iunlink_item_precommit( struct xfs_trans *tp, struct xfs_log_item *lip)
{ struct xfs_iunlink_item *iup = IUL_ITEM(lip); int error;
/* * 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 iunlink item.
*/ int
xfs_iunlink_log_inode( struct xfs_trans *tp, struct xfs_inode *ip, struct xfs_perag *pag,
xfs_agino_t next_agino)
{ struct xfs_mount *mp = tp->t_mountp; struct xfs_iunlink_item *iup;
/* * Since we're updating a linked list, we should never find that the * current pointer is the same as the new value, unless we're * terminating the list.
*/ if (ip->i_next_unlinked == next_agino) { if (next_agino != NULLAGINO) return -EFSCORRUPTED; return 0;
}
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.