Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 229017
b: refs/heads/master
c: e2714bf
h: refs/heads/master
i:
  229015: d04fa17
v: v3
  • Loading branch information
Christoph Hellwig authored and Alex Elder committed Dec 16, 2010
1 parent 6a35fe4 commit 14e4da5
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 116 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 576ecb8e2b725726471cc62b12c01e28d33127ba
refs/heads/master: e2714bf8d5c8e131a6df6b0ea2269433e9a03a9b
155 changes: 40 additions & 115 deletions trunk/fs/xfs/xfs_log_recover.c
Original file line number Diff line number Diff line change
Expand Up @@ -1614,22 +1614,13 @@ xlog_recover_do_buffer_pass1(
xfs_buf_cancel_t *nextp;
xfs_buf_cancel_t *prevp;
xfs_buf_cancel_t **bucket;
xfs_daddr_t blkno = 0;
uint len = 0;
ushort flags = 0;

switch (buf_f->blf_type) {
case XFS_LI_BUF:
blkno = buf_f->blf_blkno;
len = buf_f->blf_len;
flags = buf_f->blf_flags;
break;
}
xfs_daddr_t blkno = buf_f->blf_blkno;
uint len = buf_f->blf_len;

/*
* If this isn't a cancel buffer item, then just return.
*/
if (!(flags & XFS_BLF_CANCEL)) {
if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
trace_xfs_log_recover_buf_not_cancel(log, buf_f);
return;
}
Expand Down Expand Up @@ -1767,77 +1758,38 @@ xlog_check_buffer_cancelled(
return 0;
}

STATIC int
xlog_recover_do_buffer_pass2(
xlog_t *log,
xfs_buf_log_format_t *buf_f)
{
xfs_daddr_t blkno = 0;
ushort flags = 0;
uint len = 0;

switch (buf_f->blf_type) {
case XFS_LI_BUF:
blkno = buf_f->blf_blkno;
flags = buf_f->blf_flags;
len = buf_f->blf_len;
break;
}

return xlog_check_buffer_cancelled(log, blkno, len, flags);
}

/*
* Perform recovery for a buffer full of inodes. In these buffers,
* the only data which should be recovered is that which corresponds
* to the di_next_unlinked pointers in the on disk inode structures.
* The rest of the data for the inodes is always logged through the
* inodes themselves rather than the inode buffer and is recovered
* in xlog_recover_do_inode_trans().
* Perform recovery for a buffer full of inodes. In these buffers, the only
* data which should be recovered is that which corresponds to the
* di_next_unlinked pointers in the on disk inode structures. The rest of the
* data for the inodes is always logged through the inodes themselves rather
* than the inode buffer and is recovered in xlog_recover_inode_pass2().
*
* The only time when buffers full of inodes are fully recovered is
* when the buffer is full of newly allocated inodes. In this case
* the buffer will not be marked as an inode buffer and so will be
* sent to xlog_recover_do_reg_buffer() below during recovery.
* The only time when buffers full of inodes are fully recovered is when the
* buffer is full of newly allocated inodes. In this case the buffer will
* not be marked as an inode buffer and so will be sent to
* xlog_recover_do_reg_buffer() below during recovery.
*/
STATIC int
xlog_recover_do_inode_buffer(
xfs_mount_t *mp,
struct xfs_mount *mp,
xlog_recover_item_t *item,
xfs_buf_t *bp,
struct xfs_buf *bp,
xfs_buf_log_format_t *buf_f)
{
int i;
int item_index;
int bit;
int nbits;
int reg_buf_offset;
int reg_buf_bytes;
int item_index = 0;
int bit = 0;
int nbits = 0;
int reg_buf_offset = 0;
int reg_buf_bytes = 0;
int next_unlinked_offset;
int inodes_per_buf;
xfs_agino_t *logged_nextp;
xfs_agino_t *buffer_nextp;
unsigned int *data_map = NULL;
unsigned int map_size = 0;

trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);

switch (buf_f->blf_type) {
case XFS_LI_BUF:
data_map = buf_f->blf_data_map;
map_size = buf_f->blf_map_size;
break;
}
/*
* Set the variables corresponding to the current region to
* 0 so that we'll initialize them on the first pass through
* the loop.
*/
reg_buf_offset = 0;
reg_buf_bytes = 0;
bit = 0;
nbits = 0;
item_index = 0;
inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog;
for (i = 0; i < inodes_per_buf; i++) {
next_unlinked_offset = (i * mp->m_sb.sb_inodesize) +
Expand All @@ -1852,18 +1804,18 @@ xlog_recover_do_inode_buffer(
* the current di_next_unlinked field.
*/
bit += nbits;
bit = xfs_next_bit(data_map, map_size, bit);
bit = xfs_next_bit(buf_f->blf_data_map,
buf_f->blf_map_size, bit);

/*
* If there are no more logged regions in the
* buffer, then we're done.
*/
if (bit == -1) {
if (bit == -1)
return 0;
}

nbits = xfs_contig_bits(data_map, map_size,
bit);
nbits = xfs_contig_bits(buf_f->blf_data_map,
buf_f->blf_map_size, bit);
ASSERT(nbits > 0);
reg_buf_offset = bit << XFS_BLF_SHIFT;
reg_buf_bytes = nbits << XFS_BLF_SHIFT;
Expand All @@ -1875,9 +1827,8 @@ xlog_recover_do_inode_buffer(
* di_next_unlinked field, then move on to the next
* di_next_unlinked field.
*/
if (next_unlinked_offset < reg_buf_offset) {
if (next_unlinked_offset < reg_buf_offset)
continue;
}

ASSERT(item->ri_buf[item_index].i_addr != NULL);
ASSERT((item->ri_buf[item_index].i_len % XFS_BLF_CHUNK) == 0);
Expand Down Expand Up @@ -1913,36 +1864,29 @@ xlog_recover_do_inode_buffer(
* given buffer. The bitmap in the buf log format structure indicates
* where to place the logged data.
*/
/*ARGSUSED*/
STATIC void
xlog_recover_do_reg_buffer(
struct xfs_mount *mp,
xlog_recover_item_t *item,
xfs_buf_t *bp,
struct xfs_buf *bp,
xfs_buf_log_format_t *buf_f)
{
int i;
int bit;
int nbits;
unsigned int *data_map = NULL;
unsigned int map_size = 0;
int error;

trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f);

switch (buf_f->blf_type) {
case XFS_LI_BUF:
data_map = buf_f->blf_data_map;
map_size = buf_f->blf_map_size;
break;
}
bit = 0;
i = 1; /* 0 is the buf format structure */
while (1) {
bit = xfs_next_bit(data_map, map_size, bit);
bit = xfs_next_bit(buf_f->blf_data_map,
buf_f->blf_map_size, bit);
if (bit == -1)
break;
nbits = xfs_contig_bits(data_map, map_size, bit);
nbits = xfs_contig_bits(buf_f->blf_data_map,
buf_f->blf_map_size, bit);
ASSERT(nbits > 0);
ASSERT(item->ri_buf[i].i_addr != NULL);
ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
Expand Down Expand Up @@ -2182,13 +2126,9 @@ xlog_recover_do_buffer_trans(
int pass)
{
xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
xfs_mount_t *mp;
xfs_mount_t *mp = log->l_mp;
xfs_buf_t *bp;
int error;
int cancel;
xfs_daddr_t blkno;
int len;
ushort flags;
uint buf_flags;

if (pass == XLOG_RECOVER_PASS1) {
Expand All @@ -2206,47 +2146,32 @@ xlog_recover_do_buffer_trans(
* we call here will tell us whether or not to
* continue with the replay of this buffer.
*/
cancel = xlog_recover_do_buffer_pass2(log, buf_f);
if (cancel) {
if (xlog_check_buffer_cancelled(log, buf_f->blf_blkno,
buf_f->blf_len, buf_f->blf_flags)) {
trace_xfs_log_recover_buf_cancel(log, buf_f);
return 0;
}
}
trace_xfs_log_recover_buf_recover(log, buf_f);
switch (buf_f->blf_type) {
case XFS_LI_BUF:
blkno = buf_f->blf_blkno;
len = buf_f->blf_len;
flags = buf_f->blf_flags;
break;
default:
xfs_fs_cmn_err(CE_ALERT, log->l_mp,
"xfs_log_recover: unknown buffer type 0x%x, logdev %s",
buf_f->blf_type, log->l_mp->m_logname ?
log->l_mp->m_logname : "internal");
XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
XFS_ERRLEVEL_LOW, log->l_mp);
return XFS_ERROR(EFSCORRUPTED);
}

mp = log->l_mp;
buf_flags = XBF_LOCK;
if (!(flags & XFS_BLF_INODE_BUF))
if (!(buf_f->blf_flags & XFS_BLF_INODE_BUF))
buf_flags |= XBF_MAPPED;

bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, buf_flags);
bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len,
buf_flags);
if (XFS_BUF_ISERROR(bp)) {
xfs_ioerror_alert("xlog_recover_do..(read#1)", log->l_mp,
bp, blkno);
xfs_ioerror_alert("xlog_recover_do..(read#1)", mp,
bp, buf_f->blf_blkno);
error = XFS_BUF_GETERROR(bp);
xfs_buf_relse(bp);
return error;
}

error = 0;
if (flags & XFS_BLF_INODE_BUF) {
if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
} else if (flags &
} else if (buf_f->blf_flags &
(XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
} else {
Expand Down

0 comments on commit 14e4da5

Please sign in to comment.