bool xfs_log_check_lsn( struct xfs_mount *mp, xfs_lsn_t lsn) { int cycle = CYCLE_LSN(lsn); int block = BLOCK_LSN(lsn); int max_cycle; int max_block; if (lsn == NULLCOMMITLSN) return true; pthread_mutex_lock(&libxfs_max_lsn_lock); max_cycle = CYCLE_LSN(libxfs_max_lsn); max_block = BLOCK_LSN(libxfs_max_lsn); if ((cycle > max_cycle) || (cycle == max_cycle && block > max_block)) libxfs_max_lsn = lsn; pthread_mutex_unlock(&libxfs_max_lsn_lock); return true; }
int xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head) { if (print_record_header) printf(_("\nLOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n"), CYCLE_LSN(be64_to_cpu(head->h_lsn)), BLOCK_LSN(be64_to_cpu(head->h_lsn)), CYCLE_LSN(be64_to_cpu(head->h_lsn)), BLOCK_LSN(be64_to_cpu(head->h_lsn))); if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) { printf(_("* ERROR: bad magic number in log header: 0x%x\n"), be32_to_cpu(head->h_magicno)); } else if (header_check_uuid(mp, head)) { /* failed - fall through */ } else if (be32_to_cpu(head->h_fmt) != XLOG_FMT) { printf(_("* ERROR: log format incompatible (log=%d, ours=%d)\n"), be32_to_cpu(head->h_fmt), XLOG_FMT); } else { /* everything is ok */ return 0; } /* bail out now or just carry on regardless */ if (print_exit) xlog_exit(_("Bad log")); return 0; }
void print_lsn(char *string, __be64 *lsn) { printf("%s: %u,%u", string, CYCLE_LSN(be64_to_cpu(*lsn)), BLOCK_LSN(be64_to_cpu(*lsn))); }
int xlog_print_record( struct xlog *log, int fd, int num_ops, int len, int *read_type, char **partial_buf, xlog_rec_header_t *rhead, xlog_rec_ext_header_t *xhdrs, int bad_hdr_warn) { char *buf, *ptr; int read_len, skip, lost_context = 0; int ret, n, i, j, k; if (print_no_print) return NO_ERROR; if (!len) { printf("\n"); return NO_ERROR; } /* read_len must read up to some block boundary */ read_len = (int) BBTOB(BTOBB(len)); /* read_type => don't malloc() new buffer, use old one */ if (*read_type == FULL_READ) { if ((ptr = buf = malloc(read_len)) == NULL) { fprintf(stderr, _("%s: xlog_print_record: malloc failed\n"), progname); exit(1); } } else { read_len -= *read_type; buf = (char *)((intptr_t)(*partial_buf) + (intptr_t)(*read_type)); ptr = *partial_buf; } if ((ret = (int) read(fd, buf, read_len)) == -1) { fprintf(stderr, _("%s: xlog_print_record: read error\n"), progname); exit(1); } /* Did we overflow the end? */ if (*read_type == FULL_READ && BLOCK_LSN(be64_to_cpu(rhead->h_lsn)) + BTOBB(read_len) >= logBBsize) { *read_type = BBTOB(logBBsize - BLOCK_LSN(be64_to_cpu(rhead->h_lsn))-1); *partial_buf = buf; return PARTIAL_READ; } /* Did we read everything? */ if ((ret == 0 && read_len != 0) || ret != read_len) { *read_type = ret; *partial_buf = buf; return PARTIAL_READ; } if (*read_type != FULL_READ) read_len += *read_type; /* Everything read in. Start from beginning of buffer * Unpack the data, by putting the saved cycle-data back * into the first word of each BB. * Do some checks. */ buf = ptr; for (i = 0; ptr < buf + read_len; ptr += BBSIZE, i++) { xlog_rec_header_t *rechead = (xlog_rec_header_t *)ptr; /* sanity checks */ if (be32_to_cpu(rechead->h_magicno) == XLOG_HEADER_MAGIC_NUM) { /* data should not have magicno as first word * as it should by cycle# */ free(buf); return -1; } else { /* verify cycle# * FIXME: cycle+1 should be a macro pv#900369 */ if (be32_to_cpu(rhead->h_cycle) != be32_to_cpu(*(__be32 *)ptr)) { if ((*read_type == FULL_READ) || (be32_to_cpu(rhead->h_cycle) + 1 != be32_to_cpu(*(__be32 *)ptr))) { free(buf); return -1; } } } /* copy back the data from the header */ if (i < XLOG_HEADER_CYCLE_SIZE / BBSIZE) { /* from 1st header */ *(__be32 *)ptr = rhead->h_cycle_data[i]; } else { ASSERT(xhdrs != NULL); /* from extra headers */ j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); *(__be32 *)ptr = xhdrs[j-1].xh_cycle_data[k]; } } ptr = buf; for (i=0; i<num_ops; i++) { int continued; xlog_op_header_t *op_head = (xlog_op_header_t *)ptr; print_xlog_op_line(); xlog_print_op_header(op_head, i, &ptr); continued = ((op_head->oh_flags & XLOG_WAS_CONT_TRANS) || (op_head->oh_flags & XLOG_CONTINUE_TRANS)); if (continued && be32_to_cpu(op_head->oh_len) == 0) continue; if (print_no_data) { for (n = 0; n < be32_to_cpu(op_head->oh_len); n++) { printf("0x%02x ", (unsigned int)*ptr); if (n % 16 == 15) printf("\n"); ptr++; } printf("\n"); continue; } /* print transaction data */ if (xlog_print_find_tid(be32_to_cpu(op_head->oh_tid), op_head->oh_flags & XLOG_WAS_CONT_TRANS)) { printf(_("Left over region from split log item\n")); /* Skip this leftover bit */ ptr += be32_to_cpu(op_head->oh_len); /* We've lost context; don't complain if next one looks bad too */ lost_context = 1; continue; } if (be32_to_cpu(op_head->oh_len) != 0) { if (*(uint *)ptr == XFS_TRANS_HEADER_MAGIC) { skip = xlog_print_trans_header(&ptr, be32_to_cpu(op_head->oh_len)); } else { switch (*(unsigned short *)ptr) { case XFS_LI_BUF: { skip = xlog_print_trans_buffer(&ptr, be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_ICREATE: { skip = xlog_print_trans_icreate(&ptr, be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_INODE: { skip = xlog_print_trans_inode(log, &ptr, be32_to_cpu(op_head->oh_len), &i, num_ops, continued); break; } case XFS_LI_DQUOT: { skip = xlog_print_trans_dquot(&ptr, be32_to_cpu(op_head->oh_len), &i, num_ops); break; } case XFS_LI_EFI: { skip = xlog_print_trans_efi(&ptr, be32_to_cpu(op_head->oh_len), continued); break; } case XFS_LI_EFD: { skip = xlog_print_trans_efd(&ptr, be32_to_cpu(op_head->oh_len)); break; } case XFS_LI_QUOTAOFF: { skip = xlog_print_trans_qoff(&ptr, be32_to_cpu(op_head->oh_len)); break; } case XLOG_UNMOUNT_TYPE: { printf(_("Unmount filesystem\n")); skip = 0; break; } default: { if (bad_hdr_warn && !lost_context) { fprintf(stderr, _("%s: unknown log operation type (%x)\n"), progname, *(unsigned short *)ptr); if (print_exit) { free(buf); return BAD_HEADER; } } else { printf( _("Left over region from split log item\n")); } skip = 0; ptr += be32_to_cpu(op_head->oh_len); lost_context = 0; } } /* switch */ } /* else */ if (skip != 0) xlog_print_add_to_trans(be32_to_cpu(op_head->oh_tid), skip); } } printf("\n"); free(buf); return NO_ERROR; } /* xlog_print_record */