#include "xfs_trans_priv.h"
#include "xfs_quota.h"
#include "xfs_rw.h"
+#include "xfs_utils.h"
STATIC int xlog_find_zeroed(xlog_t *, xfs_daddr_t *);
STATIC int xlog_clear_stale_blocks(xlog_t *, xfs_lsn_t);
XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp);
xfsbdstrat(log->l_mp, bp);
- if ((error = xfs_iowait(bp)))
+ error = xfs_iowait(bp);
+ if (error)
xfs_ioerror_alert("xlog_bread", log->l_mp,
bp, XFS_BUF_ADDR(bp));
return error;
{
int b;
- cmn_err(CE_DEBUG, "%s: SB : uuid = ", __FUNCTION__);
+ cmn_err(CE_DEBUG, "%s: SB : uuid = ", __func__);
for (b = 0; b < 16; b++)
cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]);
cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT);
if (j == 0 && (start_block + endcount > ealign)) {
offset = XFS_BUF_PTR(bp);
balign = BBTOB(ealign - start_block);
- XFS_BUF_SET_PTR(bp, offset + balign, BBTOB(sectbb));
- if ((error = xlog_bread(log, ealign, sectbb, bp)))
+ error = XFS_BUF_SET_PTR(bp, offset + balign,
+ BBTOB(sectbb));
+ if (!error)
+ error = xlog_bread(log, ealign, sectbb, bp);
+ if (!error)
+ error = XFS_BUF_SET_PTR(bp, offset, bufblks);
+ if (error)
break;
- XFS_BUF_SET_PTR(bp, offset, bufblks);
}
offset = xlog_align(log, start_block, endcount, bp);
} else {
prevp->bc_next = bcp->bc_next;
}
- kmem_free(bcp,
- sizeof(xfs_buf_cancel_t));
+ kmem_free(bcp);
}
}
return 1;
* invalidate the buffer when we write it out below.
*/
imap.im_blkno = 0;
- xfs_imap(log->l_mp, NULL, ino, &imap, 0);
+ error = xfs_imap(log->l_mp, NULL, ino, &imap, 0);
+ if (error)
+ goto error;
}
/*
error:
if (need_free)
- kmem_free(in_f, sizeof(*in_f));
+ kmem_free(in_f);
return XFS_ERROR(error);
}
item = item->ri_next;
/* Free the regions in the item. */
for (i = 0; i < free_item->ri_cnt; i++) {
- kmem_free(free_item->ri_buf[i].i_addr,
- free_item->ri_buf[i].i_len);
+ kmem_free(free_item->ri_buf[i].i_addr);
}
/* Free the item itself */
- kmem_free(free_item->ri_buf,
- (free_item->ri_total * sizeof(xfs_log_iovec_t)));
- kmem_free(free_item, sizeof(xlog_recover_item_t));
+ kmem_free(free_item->ri_buf);
+ kmem_free(free_item);
} while (first_item != item);
/* Free the transaction recover structure */
- kmem_free(trans, sizeof(xlog_recover_t));
+ kmem_free(trans);
}
STATIC int
* Process an extent free intent item that was recovered from
* the log. We need to free the extents that it describes.
*/
-STATIC void
+STATIC int
xlog_recover_process_efi(
xfs_mount_t *mp,
xfs_efi_log_item_t *efip)
xfs_efd_log_item_t *efdp;
xfs_trans_t *tp;
int i;
+ int error = 0;
xfs_extent_t *extp;
xfs_fsblock_t startblock_fsb;
* free the memory associated with it.
*/
xfs_efi_release(efip, efip->efi_format.efi_nextents);
- return;
+ return XFS_ERROR(EIO);
}
}
tp = xfs_trans_alloc(mp, 0);
- xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0);
+ error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0);
+ if (error)
+ goto abort_error;
efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
for (i = 0; i < efip->efi_format.efi_nextents; i++) {
extp = &(efip->efi_format.efi_extents[i]);
- xfs_free_extent(tp, extp->ext_start, extp->ext_len);
+ error = xfs_free_extent(tp, extp->ext_start, extp->ext_len);
+ if (error)
+ goto abort_error;
xfs_trans_log_efd_extent(tp, efdp, extp->ext_start,
extp->ext_len);
}
efip->efi_flags |= XFS_EFI_RECOVERED;
- xfs_trans_commit(tp, 0);
+ error = xfs_trans_commit(tp, 0);
+ return error;
+
+abort_error:
+ xfs_trans_cancel(tp, XFS_TRANS_ABORT);
+ return error;
}
/*
* everything already in the AIL, we stop processing as soon as
* we see something other than an EFI in the AIL.
*/
-STATIC void
+STATIC int
xlog_recover_process_efis(
xlog_t *log)
{
xfs_efi_log_item_t *efip;
int gen;
xfs_mount_t *mp;
+ int error = 0;
mp = log->l_mp;
spin_lock(&mp->m_ail_lock);
}
spin_unlock(&mp->m_ail_lock);
- xlog_recover_process_efi(mp, efip);
+ error = xlog_recover_process_efi(mp, efip);
+ if (error)
+ return error;
spin_lock(&mp->m_ail_lock);
lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
}
spin_unlock(&mp->m_ail_lock);
+ return error;
}
/*
int error;
tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET);
- xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0);
-
- error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
+ error = xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0);
+ if (!error)
+ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), 0, &agibp);
- if (error) {
- xfs_trans_cancel(tp, XFS_TRANS_ABORT);
- return;
- }
+ if (error)
+ goto out_abort;
+ error = EINVAL;
agi = XFS_BUF_TO_AGI(agibp);
- if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) {
- xfs_trans_cancel(tp, XFS_TRANS_ABORT);
- return;
- }
+ if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC)
+ goto out_abort;
agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
offset = offsetof(xfs_agi_t, agi_unlinked) +
xfs_trans_log_buf(tp, agibp, offset,
(offset + sizeof(xfs_agino_t) - 1));
- (void) xfs_trans_commit(tp, 0);
+ error = xfs_trans_commit(tp, 0);
+ if (error)
+ goto out_error;
+ return;
+
+out_abort:
+ xfs_trans_cancel(tp, XFS_TRANS_ABORT);
+out_error:
+ xfs_fs_cmn_err(CE_WARN, mp, "xlog_recover_clear_agi_bucket: "
+ "failed to clear agi %d. Continuing.", agno);
+ return;
}
/*
if (ip->i_d.di_mode == 0)
xfs_iput_new(ip, 0);
else
- VN_RELE(XFS_ITOV(ip));
+ IRELE(ip);
} else {
/*
* We can't read in the inode
(!rhead->h_version ||
(be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) {
xlog_warn("XFS: %s: unrecognised log version (%d).",
- __FUNCTION__, be32_to_cpu(rhead->h_version));
+ __func__, be32_to_cpu(rhead->h_version));
return XFS_ERROR(EIO);
}
* _first_, then the log start (LR header end)
* - order is important.
*/
+ wrapped_hblks = hblks - split_hblks;
bufaddr = XFS_BUF_PTR(hbp);
- XFS_BUF_SET_PTR(hbp,
+ error = XFS_BUF_SET_PTR(hbp,
bufaddr + BBTOB(split_hblks),
BBTOB(hblks - split_hblks));
- wrapped_hblks = hblks - split_hblks;
- error = xlog_bread(log, 0, wrapped_hblks, hbp);
+ if (!error)
+ error = xlog_bread(log, 0,
+ wrapped_hblks, hbp);
+ if (!error)
+ error = XFS_BUF_SET_PTR(hbp, bufaddr,
+ BBTOB(hblks));
if (error)
goto bread_err2;
- XFS_BUF_SET_PTR(hbp, bufaddr, BBTOB(hblks));
if (!offset)
offset = xlog_align(log, 0,
wrapped_hblks, hbp);
* - order is important.
*/
bufaddr = XFS_BUF_PTR(dbp);
- XFS_BUF_SET_PTR(dbp,
+ error = XFS_BUF_SET_PTR(dbp,
bufaddr + BBTOB(split_bblks),
BBTOB(bblks - split_bblks));
- if ((error = xlog_bread(log, wrapped_hblks,
- bblks - split_bblks, dbp)))
+ if (!error)
+ error = xlog_bread(log, wrapped_hblks,
+ bblks - split_bblks,
+ dbp);
+ if (!error)
+ error = XFS_BUF_SET_PTR(dbp, bufaddr,
+ h_size);
+ if (error)
goto bread_err2;
- XFS_BUF_SET_PTR(dbp, bufaddr, h_size);
if (!offset)
offset = xlog_align(log, wrapped_hblks,
bblks - split_bblks, dbp);
error = xlog_do_recovery_pass(log, head_blk, tail_blk,
XLOG_RECOVER_PASS1);
if (error != 0) {
- kmem_free(log->l_buf_cancel_table,
- XLOG_BC_TABLE_SIZE * sizeof(xfs_buf_cancel_t*));
+ kmem_free(log->l_buf_cancel_table);
log->l_buf_cancel_table = NULL;
return error;
}
}
#endif /* DEBUG */
- kmem_free(log->l_buf_cancel_table,
- XLOG_BC_TABLE_SIZE * sizeof(xfs_buf_cancel_t*));
+ kmem_free(log->l_buf_cancel_table);
log->l_buf_cancel_table = NULL;
return error;
XFS_BUF_READ(bp);
XFS_BUF_UNASYNC(bp);
xfsbdstrat(log->l_mp, bp);
- if ((error = xfs_iowait(bp))) {
+ error = xfs_iowait(bp);
+ if (error) {
xfs_ioerror_alert("xlog_do_recover",
log->l_mp, bp, XFS_BUF_ADDR(bp));
ASSERT(0);
*/
int
xlog_recover_finish(
- xlog_t *log,
- int mfsi_flags)
+ xlog_t *log)
{
/*
* Now we're ready to do the transactions needed for the
* rather than accepting new requests.
*/
if (log->l_flags & XLOG_RECOVERY_NEEDED) {
- xlog_recover_process_efis(log);
+ int error;
+ error = xlog_recover_process_efis(log);
+ if (error) {
+ cmn_err(CE_ALERT,
+ "Failed to recover EFIs on filesystem: %s",
+ log->l_mp->m_fsname);
+ return error;
+ }
/*
* Sync the log to get all the EFIs out of the AIL.
* This isn't absolutely necessary, but it helps in
xfs_log_force(log->l_mp, (xfs_lsn_t)0,
(XFS_LOG_FORCE | XFS_LOG_SYNC));
- if ( (mfsi_flags & XFS_MFSI_NOUNLINK) == 0 ) {
- xlog_recover_process_iunlinks(log);
- }
+ xlog_recover_process_iunlinks(log);
xlog_recover_check_summary(log);