Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
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)));
}
Beispiel #4
0
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 */