Exemplo n.º 1
0
/*
 * This function is called to verify that our callers have logged
 * all the bytes that they changed.
 *
 * It does this by comparing the original copy of the buffer stored in
 * the buf log item's bli_orig array to the current copy of the buffer
 * and ensuring that all bytes which mismatch are set in the bli_logged
 * array of the buf log item.
 */
STATIC void
xfs_buf_item_log_check(
    xfs_buf_log_item_t	*bip)
{
    char		*orig;
    char		*buffer;
    int		x;
    xfs_buf_t	*bp;

    ASSERT(bip->bli_orig != NULL);
    ASSERT(bip->bli_logged != NULL);

    bp = bip->bli_buf;
    ASSERT(XFS_BUF_COUNT(bp) > 0);
    ASSERT(XFS_BUF_PTR(bp) != NULL);
    orig = bip->bli_orig;
    buffer = XFS_BUF_PTR(bp);
    for (x = 0; x < XFS_BUF_COUNT(bp); x++) {
        if (orig[x] != buffer[x] && !btst(bip->bli_logged, x)) {
            xfs_emerg(bp->b_mount,
                      "%s: bip %x buffer %x orig %x index %d",
                      __func__, bip, bp, orig, x);
            ASSERT(0);
        }
    }
}
Exemplo n.º 2
0
static int
newfile(
	xfs_trans_t	*tp,
	xfs_inode_t	*ip,
	xfs_bmap_free_t	*flist,
	xfs_fsblock_t	*first,
	int		dolocal,
	int		logit,
	char		*buf,
	int		len)
{
	xfs_buf_t	*bp;
	xfs_daddr_t	d;
	int		error;
	int		flags;
	xfs_bmbt_irec_t	map;
	xfs_mount_t	*mp;
	xfs_extlen_t	nb;
	int		nmap;

	flags = 0;
	mp = ip->i_mount;
	if (dolocal && len <= XFS_IFORK_DSIZE(ip)) {
		xfs_idata_realloc(ip, len, XFS_DATA_FORK);
		if (buf)
			memmove(ip->i_df.if_u1.if_data, buf, len);
		ip->i_d.di_size = len;
		ip->i_df.if_flags &= ~XFS_IFEXTENTS;
		ip->i_df.if_flags |= XFS_IFINLINE;
		ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
		flags = XFS_ILOG_DDATA;
	} else if (len > 0) {
		nb = XFS_B_TO_FSB(mp, len);
		nmap = 1;
		error = libxfs_bmapi(tp, ip, 0, nb, XFS_BMAPI_WRITE, first, nb,
				&map, &nmap, flist);
		if (error) {
			fail(_("error allocating space for a file"), error);
		}
		if (nmap != 1) {
			fprintf(stderr,
				_("%s: cannot allocate space for file\n"),
				progname);
			exit(1);
		}
		d = XFS_FSB_TO_DADDR(mp, map.br_startblock);
		bp = libxfs_trans_get_buf(logit ? tp : 0, mp->m_dev, d,
			nb << mp->m_blkbb_log, 0);
		memmove(XFS_BUF_PTR(bp), buf, len);
		if (len < XFS_BUF_COUNT(bp))
			memset(XFS_BUF_PTR(bp) + len, 0, XFS_BUF_COUNT(bp) - len);
		if (logit)
			libxfs_trans_log_buf(tp, bp, 0, XFS_BUF_COUNT(bp) - 1);
		else
			libxfs_writebuf(bp, LIBXFS_EXIT_ON_FAILURE);
	}
	ip->i_d.di_size = len;
	return flags;
}
Exemplo n.º 3
0
/* This routine brings in blocks from disk one by one and assembles them
 * in the value buffer. If get_bmapi gets smarter later to return an extent
 * or list of extents, that would be great. For now, we don't expect too
 * many blocks per remote value, so one by one is sufficient.
 */
static int
rmtval_get(xfs_mount_t *mp, xfs_ino_t ino, blkmap_t *blkmap,
		xfs_dablk_t blocknum, int valuelen, char* value)
{
	xfs_fsblock_t	bno;
	xfs_buf_t	*bp;
	int		clearit = 0, i = 0, length = 0, amountdone = 0;
	int		hdrsize = 0;

	if (xfs_sb_version_hascrc(&mp->m_sb))
		hdrsize = sizeof(struct xfs_attr3_rmt_hdr);

	/* ASSUMPTION: valuelen is a valid number, so use it for looping */
	/* Note that valuelen is not a multiple of blocksize */
	while (amountdone < valuelen) {
		bno = blkmap_get(blkmap, blocknum + i);
		if (bno == NULLFSBLOCK) {
			do_warn(
	_("remote block for attributes of inode %" PRIu64 " is missing\n"), ino);
			clearit = 1;
			break;
		}
		bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
				    XFS_FSB_TO_BB(mp, 1), 0,
				    &xfs_attr3_rmt_buf_ops);
		if (!bp) {
			do_warn(
	_("can't read remote block for attributes of inode %" PRIu64 "\n"), ino);
			clearit = 1;
			break;
		}

		if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) {
			do_warn(
	_("Corrupt remote block for attributes of inode %" PRIu64 "\n"), ino);
			clearit = 1;
			break;
		}

		ASSERT(mp->m_sb.sb_blocksize == XFS_BUF_COUNT(bp));

		length = MIN(XFS_BUF_COUNT(bp) - hdrsize, valuelen - amountdone);
		memmove(value, bp->b_addr + hdrsize, length);
		amountdone += length;
		value += length;
		i++;
		libxfs_putbuf(bp);
	}
	return (clearit);
}
Exemplo n.º 4
0
/*
 * Prints out an ALERT message about I/O error.
 */
void
xfs_ioerror_alert(
    char			*func,
    struct xfs_mount	*mp,
    xfs_buf_t		*bp,
    xfs_daddr_t		blkno)
{
    xfs_alert(mp,
              "I/O error occurred: meta-data dev %s block 0x%llx"
              "       (\"%s\") error %d buf count %zd",
              XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
              (__uint64_t)blkno, func,
              XFS_BUF_GETERROR(bp), XFS_BUF_COUNT(bp));
}
Exemplo n.º 5
0
/*
 * Prints out an ALERT message about I/O error.
 */
void
xfs_ioerror_alert(
	char			*func,
	struct xfs_mount	*mp,
	xfs_buf_t		*bp,
	xfs_daddr_t		blkno)
{
	cmn_err(CE_ALERT,
 "I/O error in filesystem (\"%s\") meta-data dev %s block 0x%llx"
 "       (\"%s\") error %d buf count %zd",
		(!mp || !mp->m_fsname) ? "(fs name not set)" : mp->m_fsname,
		XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
		(__uint64_t)blkno, func,
		XFS_BUF_GETERROR(bp), XFS_BUF_COUNT(bp));
}
Exemplo n.º 6
0
/*
 * This function is called to verify that our caller's have logged
 * all the bytes that they changed.
 *
 * It does this by comparing the original copy of the buffer stored in
 * the buf log item's bli_orig array to the current copy of the buffer
 * and ensuring that all bytes which miscompare are set in the bli_logged
 * array of the buf log item.
 */
STATIC void
xfs_buf_item_log_check(
	xfs_buf_log_item_t	*bip)
{
	char		*orig;
	char		*buffer;
	int		x;
	xfs_buf_t	*bp;

	ASSERT(bip->bli_orig != NULL);
	ASSERT(bip->bli_logged != NULL);

	bp = bip->bli_buf;
	ASSERT(XFS_BUF_COUNT(bp) > 0);
	ASSERT(XFS_BUF_PTR(bp) != NULL);
	orig = bip->bli_orig;
	buffer = XFS_BUF_PTR(bp);
	for (x = 0; x < XFS_BUF_COUNT(bp); x++) {
		if (orig[x] != buffer[x] && !btst(bip->bli_logged, x))
			cmn_err(CE_PANIC,
	"xfs_buf_item_log_check bip %x buffer %x orig %x index %d",
				bip, bp, orig, x);
	}
}
Exemplo n.º 7
0
/*
 * This is called to mark bytes first through last inclusive of the given
 * buffer as needing to be logged when the transaction is committed.
 * The buffer must already be associated with the given transaction.
 *
 * First and last are numbers relative to the beginning of this buffer,
 * so the first byte in the buffer is numbered 0 regardless of the
 * value of b_blkno.
 */
void
libxfs_trans_log_buf(
	xfs_trans_t		*tp,
	xfs_buf_t		*bp,
	uint			first,
	uint			last)
{
	xfs_buf_log_item_t	*bip;

	ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
	ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp)));
#ifdef XACT_DEBUG
	fprintf(stderr, "dirtied buffer %p, transaction %p\n", bp, tp);
#endif

	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);

	tp->t_flags |= XFS_TRANS_DIRTY;
	bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
	xfs_buf_item_log(bip, first, last);
}