예제 #1
0
/*
 * Set the he range [start, stop) in the directory freemap.
 *
 * Returns 1 if there is a conflict or 0 if everything's good.
 *
 * Within a char, the lowest bit of the char represents the byte with
 * the smallest address
 */
static int
set_da_freemap(xfs_mount_t *mp, da_freemap_t *map, int start, int stop)
{
	const da_freemap_t mask = 0x1;
	int i;

	if (start > stop)  {
		/*
		 * allow == relation since [x, x) claims 1 byte
		 */
		do_warn(_("bad range claimed [%d, %d) in da block\n"),
			start, stop);
		return(1);
	}

	if (stop > mp->m_sb.sb_blocksize)  {
		do_warn(
	_("byte range end [%d %d) in da block larger than blocksize %d\n"),
			start, stop, mp->m_sb.sb_blocksize);
		return(1);
	}

	for (i = start; i < stop; i ++)  {
		if (map[i / NBBY] & (mask << i % NBBY))  {
			do_warn(_("multiply claimed byte %d in da block\n"), i);
			return(1);
		}
		map[i / NBBY] |= (mask << i % NBBY);
	}

	return(0);
}
예제 #2
0
파일: phase1.c 프로젝트: brkt/fuse-xfs
void
no_sb(void)
{
	do_warn(_("Sorry, could not find valid secondary superblock\n"));
	do_warn(_("Exiting now.\n"));
	exit(1);
}
예제 #3
0
void
read_wbuf(int fd, wbuf *buf, xfs_mount_t *mp)
{
	int		res = 0;
	xfs_off_t	lres = 0;
	xfs_off_t	newpos;
	size_t		diff;

	newpos = rounddown(buf->position, (xfs_off_t) buf->min_io_size);

	if (newpos != buf->position)  {
		diff = buf->position - newpos;
		buf->position = newpos;

		buf->length += diff;
	}

	if (source_position != buf->position)  {
		lres = lseek64(fd, buf->position, SEEK_SET);
		if (lres < 0LL)  {
			do_warn(_("%s:  lseek64 failure at offset %lld\n"),
				progname, source_position);
			die_perror();
		}
		source_position = buf->position;
	}

	ASSERT(source_position % source_sectorsize == 0);

	/* round up length for direct I/O if necessary */

	if (buf->length % buf->min_io_size != 0)
		buf->length = roundup(buf->length, buf->min_io_size);

	if (buf->length > buf->size)  {
		do_warn(_("assert error:  buf->length = %d, buf->size = %d\n"),
			buf->length, buf->size);
		killall();
		abort();
	}

	if ((res = read(fd, buf->data, buf->length)) < 0)  {
		do_warn(_("%s:  read failure at offset %lld\n"),
				progname, source_position);
		die_perror();
	}

	if (res < buf->length &&
	    source_position + res == mp->m_sb.sb_dblocks * source_blocksize)
		res = buf->length;
	else
		ASSERT(res == buf->length);
	source_position += res;
	buf->length = res;
}
예제 #4
0
static int
process_leaf_attr_local(
	struct xfs_mount	*mp,
	xfs_attr_leafblock_t	*leaf,
	int			i,
	xfs_attr_leaf_entry_t	*entry,
	xfs_dahash_t		last_hashval,
	xfs_dablk_t		da_bno,
	xfs_ino_t		ino)
{
	xfs_attr_leaf_name_local_t *local;

	local = xfs_attr3_leaf_name_local(leaf, i);
	if (local->namelen == 0 || namecheck((char *)&local->nameval[0],
							local->namelen)) {
		do_warn(
	_("attribute entry %d in attr block %u, inode %" PRIu64 " has bad name (namelen = %d)\n"),
			i, da_bno, ino, local->namelen);
		return -1;
	}

	/* Check on the hash value. Checking order of values
	 * is not necessary, since one wrong clears the whole
	 * fork. If the ordering's wrong, it's caught here or
	 * the kernel code has a bug with transaction logging
	 * or attributes itself. Being paranoid, let's check
	 * ordering anyway in case both the name value and the
	 * hashvalue were wrong but matched. Unlikely, however.
	 */
	if (be32_to_cpu(entry->hashval) != libxfs_da_hashname(
				&local->nameval[0], local->namelen) ||
				be32_to_cpu(entry->hashval) < last_hashval) {
		do_warn(
	_("bad hashvalue for attribute entry %d in attr block %u, inode %" PRIu64 "\n"),
			i, da_bno, ino);
		return -1;
	}

	/* Only check values for root security attributes */
	if (entry->flags & XFS_ATTR_ROOT) {
		if (valuecheck(mp, (char *)&local->nameval[0], NULL,
				local->namelen, be16_to_cpu(local->valuelen))) {
			do_warn(
	_("bad security value for attribute entry %d in attr block %u, inode %" PRIu64 "\n"),
				i, da_bno, ino);
			return -1;
		}
	}
	return xfs_attr_leaf_entsize_local(local->namelen,
						be16_to_cpu(local->valuelen));
}
예제 #5
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);
}
예제 #6
0
int
verify_set_agheader(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb,
	xfs_agf_t *agf, xfs_agi_t *agi, xfs_agnumber_t i)
{
	int rval = 0;
	int status = XR_OK;
	int status_sb = XR_OK;

	status = verify_sb(sb, (i == 0));

	if (status != XR_OK)  {
		do_warn(_("bad on-disk superblock %d - %s\n"),
			i, err_string(status));
	}

	status_sb = compare_sb(mp, sb);

	if (status_sb != XR_OK)  {
		do_warn(_("primary/secondary superblock %d conflict - %s\n"),
			i, err_string(status_sb));
	}

	if (status != XR_OK || status_sb != XR_OK)  {
		if (!no_modify)  {
			*sb = mp->m_sb;

			/*
			 * clear the more transient fields
			 */
			sb->sb_inprogress = 1;

			sb->sb_icount = 0;
			sb->sb_ifree = 0;
			sb->sb_fdblocks = 0;
			sb->sb_frextents = 0;

			sb->sb_qflags = 0;
		}

		rval |= XR_AG_SB;
	}

	rval |= secondary_sb_wack(mp, sbuf, sb, i);

	rval |= verify_set_agf(mp, agf, i);
	rval |= verify_set_agi(mp, agi, i);

	return(rval);
}
예제 #7
0
/*
 * returns 1 if attributes got cleared
 * and 0 if things are ok.
 */
int
process_attributes(
	xfs_mount_t	*mp,
	xfs_ino_t	ino,
	xfs_dinode_t	*dip,
	blkmap_t	*blkmap,
	int		*repair)  /* returned if we did repair */
{
	int		err;
	__u8		aformat = dip->di_aformat;
#ifdef DEBUG
	xfs_attr_shortform_t *asf;

	asf = (xfs_attr_shortform_t *) XFS_DFORK_APTR(dip);
#endif

	if (aformat == XFS_DINODE_FMT_LOCAL) {
		ASSERT(be16_to_cpu(asf->hdr.totsize) <=
			XFS_DFORK_ASIZE(dip, mp));
		err = process_shortform_attr(mp, ino, dip, repair);
	} else if (aformat == XFS_DINODE_FMT_EXTENTS ||
					aformat == XFS_DINODE_FMT_BTREE)  {
			err = process_longform_attr(mp, ino, dip, blkmap,
				repair);
			/* if err, convert this to shortform and clear it */
			/* if repair and no error, it's taken care of */
	} else  {
		do_warn(_("illegal attribute format %d, ino %" PRIu64 "\n"),
			aformat, ino);
		err = 1;
	}
	return (err);  /* and repair */
}
예제 #8
0
void warn(const char *file,int line,const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  do_warn("WARNINGS", file, line, fmt, args);
  va_end(args); 
}
예제 #9
0
파일: lib.c 프로젝트: alexanderkyte/sparse
void warning(struct position pos, const char * fmt, ...)
{
	va_list args;

	if (Wsparse_error) {
		va_start(args, fmt);
		do_error(pos, fmt, args);
		va_end(args);
		return;
	}

	if (!max_warnings) {
		show_info = 0;
		return;
	}

	if (!--max_warnings) {
		show_info = 0;
		fmt = "too many warnings";
	}

	va_start(args, fmt);
	do_warn("warning: ", pos, fmt, args);
	va_end(args);
}
예제 #10
0
void warn_doc_error(const char *file,int line,const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  do_warn("WARN_IF_DOC_ERROR", file, line, fmt, args);
  va_end(args);
}
예제 #11
0
void warn_undoc(const char *file,int line,const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  do_warn("WARN_IF_UNDOCUMENTED", file, line, fmt, args);
  va_end(args);
}
예제 #12
0
파일: lib.c 프로젝트: alexanderkyte/sparse
void error_die(struct position pos, const char * fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	do_warn("error: ", pos, fmt, args);
	va_end(args);
	exit(1);
}
예제 #13
0
파일: lib.c 프로젝트: alexanderkyte/sparse
void info(struct position pos, const char * fmt, ...)
{
	va_list args;

	if (!show_info)
		return;
	va_start(args, fmt);
	do_warn("", pos, fmt, args);
	va_end(args);
}
예제 #14
0
static PyObject *
warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
                   Py_ssize_t stacklevel, PyObject *source)
/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
{
    category = get_category(message, category);
    if (category == NULL)
        return NULL;
    return do_warn(message, category, stacklevel, source);
}
예제 #15
0
static int
xfs_acl_from_disk(
	struct xfs_mount	*mp,
	struct xfs_icacl	**aclp,
	struct xfs_acl		*dacl)
{
	struct xfs_icacl	*acl;
	struct xfs_icacl_entry	*ace;
	struct xfs_acl_entry	*dace;
	int			count;
	int			i;

	count = be32_to_cpu(dacl->acl_cnt);
	if (count > XFS_ACL_MAX_ENTRIES(mp)) {
		do_warn(_("Too many ACL entries, count %d\n"), count);
		*aclp = NULL;
		return EINVAL;
	}


	acl = malloc(sizeof(struct xfs_icacl) +
		     count * sizeof(struct xfs_icacl_entry));
	if (!acl) {
		do_warn(_("cannot malloc enough for ACL attribute\n"));
		do_warn(_("SKIPPING this ACL\n"));
		*aclp = NULL;
		return ENOMEM;
	}

	acl->acl_cnt = count;
	for (i = 0; i < count; i++) {
		ace = &acl->acl_entry[i];
		dace = &dacl->acl_entry[i];

		ace->ae_tag = be32_to_cpu(dace->ae_tag);
		ace->ae_id = be32_to_cpu(dace->ae_id);
		ace->ae_perm = be16_to_cpu(dace->ae_perm);
	}

	*aclp = acl;
	return 0;
}
예제 #16
0
/*
 * Set up an inode tree record for a group of inodes that will include the
 * requested inode.
 *
 * This does NOT do error-check for duplicate records.  The caller is
 * responsible for checking that. Ino must be the start of an
 * XFS_INODES_PER_CHUNK (64) inode chunk
 *
 * Each inode resides in a 64-inode chunk which can be part one or more chunks
 * (MAX(64, inodes-per-block).  The fs allocates in chunks (as opposed to 1
 * chunk) when a block can hold more than one chunk (inodes per block > 64).
 * Allocating in one chunk pieces causes us problems when it takes more than
 * one fs block to contain an inode chunk because the chunks can start on
 * *any* block boundary. So we assume that the caller has a clue because at
 * this level, we don't.
 */
static struct ino_tree_node *
add_inode(
	struct xfs_mount	*mp,
	xfs_agnumber_t		agno,
	xfs_agino_t		agino)
{
	struct ino_tree_node	*irec;

	irec = alloc_ino_node(mp, agino);
	if (!avl_insert(inode_tree_ptrs[agno],	&irec->avl_node))
		do_warn(_("add_inode - duplicate inode range\n"));
	return irec;
}
예제 #17
0
/*
 * get a possible superblock -- don't check for internal consistency
 */
int
get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno)
{
	int error, rval;
	xfs_dsb_t *buf;

	buf = memalign(libxfs_device_alignment(), size);
	if (buf == NULL) {
		do_error(
	_("error reading superblock %u -- failed to memalign buffer\n"),
			agno);
		exit(1);
	}
	memset(buf, 0, size);

	/* try and read it first */

	if (lseek64(x.dfd, off, SEEK_SET) != off)  {
		do_warn(
	_("error reading superblock %u -- seek to offset %" PRId64 " failed\n"),
			agno, off);
		return(XR_EOF);
	}

	if ((rval = read(x.dfd, buf, size)) != size)  {
		error = errno;
		do_warn(
	_("superblock read failed, offset %" PRId64 ", size %d, ag %u, rval %d\n"),
			off, size, agno, rval);
		do_error("%s\n", strerror(error));
	}
	libxfs_sb_from_disk(sbp, buf);
	free(buf);

	return (verify_sb(sbp, 0));
}
예제 #18
0
/* check v5 metadata */
static int
__check_attr_header(
	struct xfs_mount	*mp,
	struct xfs_buf		*bp,
	xfs_ino_t		ino)
{
	struct xfs_da3_blkinfo	*info = bp->b_addr;

	if (info->hdr.magic != cpu_to_be16(XFS_ATTR3_LEAF_MAGIC) &&
	    info->hdr.magic != cpu_to_be16(XFS_DA3_NODE_MAGIC))
		return 0;

	/* verify owner */
	if (be64_to_cpu(info->owner) != ino) {
		do_warn(
_("expected owner inode %" PRIu64 ", got %llu, attr block %" PRIu64 "\n"),
			ino, be64_to_cpu(info->owner), bp->b_bn);
		return 1;
	}
	/* verify block number */
	if (be64_to_cpu(info->blkno) != bp->b_bn) {
		do_warn(
_("expected block %" PRIu64 ", got %llu, inode %" PRIu64 "attr block\n"),
			bp->b_bn, be64_to_cpu(info->blkno), ino);
		return 1;
	}
	/* verify uuid */
	if (platform_uuid_compare(&info->uuid, &mp->m_sb.sb_meta_uuid) != 0) {
		do_warn(
_("wrong FS UUID, inode %" PRIu64 " attr block %" PRIu64 "\n"),
			ino, bp->b_bn);
		return 1;
	}

	return 0;
}
예제 #19
0
static int
warn_unicode(PyObject *category, PyObject *message,
             Py_ssize_t stack_level, PyObject *source)
{
    PyObject *res;

    if (category == NULL)
        category = PyExc_RuntimeWarning;

    res = do_warn(message, category, stack_level, source);
    if (res == NULL)
        return -1;
    Py_DECREF(res);

    return 0;
}
예제 #20
0
static PyObject *
warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
{
    static char *kw_list[] = { "message", "category", "stacklevel", 0 };
    PyObject *message, *category = NULL;
    Py_ssize_t stack_level = 1;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
                                     &message, &category, &stack_level))
        return NULL;

    category = get_category(message, category);
    if (category == NULL)
        return NULL;
    return do_warn(message, category, stack_level);
}
예제 #21
0
/* Function to issue a warning message; may raise an exception. */
int
PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
{
    PyObject *res;
    PyObject *message = PyString_FromString(text);
    if (message == NULL)
        return -1;

    if (category == NULL)
        category = PyExc_RuntimeWarning;

    res = do_warn(message, category, stack_level);
    Py_DECREF(message);
    if (res == NULL)
        return -1;
    Py_DECREF(res);

    return 0;
}
예제 #22
0
파일: lib.c 프로젝트: alexanderkyte/sparse
static void do_error(struct position pos, const char * fmt, va_list args)
{
	static int errors = 0;
        die_if_error = 1;
	show_info = 1;
	/* Shut up warnings after an error */
	max_warnings = 0;
	if (errors > 100) {
		static int once = 0;
		show_info = 0;
		if (once)
			return;
		fmt = "too many errors";
		once = 1;
	}

	do_warn("error: ", pos, fmt, args);
	errors++;
}	
예제 #23
0
파일: phase2.c 프로젝트: brkt/fuse-xfs
static void
zero_log(xfs_mount_t *mp)
{
	int error;
	xlog_t	log;
	xfs_daddr_t head_blk, tail_blk;
	dev_t logdev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev;

	memset(&log, 0, sizeof(log));
	if (!x.logdev)
		x.logdev = x.ddev;
	x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
	x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);

	log.l_dev = logdev;
	log.l_logsize = BBTOB(x.logBBsize);
	log.l_logBBsize = x.logBBsize;
	log.l_logBBstart = x.logBBstart;
	log.l_mp = mp;
	if (xfs_sb_version_hassector(&mp->m_sb)) {
		log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
		ASSERT(log.l_sectbb_log <= mp->m_sectbb_log);
		/* for larger sector sizes, must have v2 or external log */
		ASSERT(log.l_sectbb_log == 0 ||
			log.l_logBBstart == 0 ||
			xfs_sb_version_haslogv2(&mp->m_sb));
		ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT);
	}
	log.l_sectbb_mask = (1 << log.l_sectbb_log) - 1;

	if ((error = xlog_find_tail(&log, &head_blk, &tail_blk))) {
		do_warn(_("zero_log: cannot find log head/tail "
			  "(xlog_find_tail=%d), zeroing it anyway\n"),
			error);
	} else {
		if (verbose) {
			do_warn(_("zero_log: head block %lld tail block %lld\n"),
				head_blk, tail_blk);
		}
		if (head_blk != tail_blk) {
			if (zap_log) {
				do_warn(_(
"ALERT: The filesystem has valuable metadata changes in a log which is being\n"
"destroyed because the -L option was used.\n"));
			} else {
				do_warn(_(
"ERROR: The filesystem has valuable metadata changes in a log which needs to\n"
"be replayed.  Mount the filesystem to replay the log, and unmount it before\n"
"re-running xfs_repair.  If you are unable to mount the filesystem, then use\n"
"the -L option to destroy the log and attempt a repair.\n"
"Note that destroying the log may cause corruption -- please attempt a mount\n"
"of the filesystem before doing this.\n"));
				exit(2);
			}
		}
	}

	libxfs_log_clear(logdev,
		XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
		(xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
		&mp->m_sb.sb_uuid,
		xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1,
		mp->m_sb.sb_logsunit, XLOG_FMT);
}
예제 #24
0
파일: phase2.c 프로젝트: brkt/fuse-xfs
void
phase2(
	struct xfs_mount	*mp,
	int			scan_threads)
{
	int			j;
	ino_tree_node_t		*ino_rec;

	/* now we can start using the buffer cache routines */
	set_mp(mp);

	/* Check whether this fs has internal or external log */
	if (mp->m_sb.sb_logstart == 0) {
		if (!x.logname)
			do_error(_("This filesystem has an external log.  "
				   "Specify log device with the -l option.\n"));

		do_log(_("Phase 2 - using external log on %s\n"), x.logname);
	} else
		do_log(_("Phase 2 - using internal log\n"));

	/* Zero log if applicable */
	if (!no_modify)  {
		do_log(_("        - zero log...\n"));
		zero_log(mp);
	}

	do_log(_("        - scan filesystem freespace and inode maps...\n"));

	bad_ino_btree = 0;

	set_progress_msg(PROG_FMT_SCAN_AG, (__uint64_t) glob_agcount);

	scan_ags(mp, scan_threads);

	print_final_rpt();

	/*
	 * make sure we know about the root inode chunk
	 */
	if ((ino_rec = find_inode_rec(0, mp->m_sb.sb_rootino)) == NULL)  {
		ASSERT(mp->m_sb.sb_rbmino == mp->m_sb.sb_rootino + 1 &&
			mp->m_sb.sb_rsumino == mp->m_sb.sb_rootino + 2);
		do_warn(_("root inode chunk not found\n"));

		/*
		 * mark the first 3 used, the rest are free
		 */
		ino_rec = set_inode_used_alloc(0,
				(xfs_agino_t) mp->m_sb.sb_rootino);
		set_inode_used(ino_rec, 1);
		set_inode_used(ino_rec, 2);

		for (j = 3; j < XFS_INODES_PER_CHUNK; j++)
			set_inode_free(ino_rec, j);

		/*
		 * also mark blocks
		 */
		set_bmap_ext(0, XFS_INO_TO_AGBNO(mp, mp->m_sb.sb_rootino),
			     mp->m_ialloc_blks, XR_E_INO);
	} else  {
		do_log(_("        - found root inode chunk\n"));

		/*
		 * blocks are marked, just make sure they're in use
		 */
		if (is_inode_free(ino_rec, 0))  {
			do_warn(_("root inode marked free, "));
			set_inode_used(ino_rec, 0);
			if (!no_modify)
				do_warn(_("correcting\n"));
			else
				do_warn(_("would correct\n"));
		}

		if (is_inode_free(ino_rec, 1))  {
			do_warn(_("realtime bitmap inode marked free, "));
			set_inode_used(ino_rec, 1);
			if (!no_modify)
				do_warn(_("correcting\n"));
			else
				do_warn(_("would correct\n"));
		}

		if (is_inode_free(ino_rec, 2))  {
			do_warn(_("realtime summary inode marked free, "));
			set_inode_used(ino_rec, 2);
			if (!no_modify)
				do_warn(_("correcting\n"));
			else
				do_warn(_("would correct\n"));
		}
	}
}
예제 #25
0
파일: phase2.c 프로젝트: hyakki-/sgi
void
phase2(xfs_mount_t *mp, libxfs_init_t *args)
{
    xfs_agnumber_t		i;
    xfs_agblock_t		b;
    int			j;
    ino_tree_node_t		*ino_rec;

    /* now we can start using the buffer cache routines */
    set_mp(mp);

    /* Check whether this fs has internal or external log */
    if (mp->m_sb.sb_logstart == 0) {
        if (!args->logname) {
            fprintf (stderr,
                     "This filesystem has an external log.  "
                     "Specify log device with the -l option.\n");
            exit (1);
        }

        fprintf (stderr, "Phase 2 - using external log on %s\n",
                 args->logname);
    } else
        fprintf (stderr, "Phase 2 - using internal log\n");

    /* Zero log if applicable */
    if (!no_modify)  {
        do_log("        - zero log...\n");
        zero_log(mp, args);
    }

    do_log("        - scan filesystem freespace and inode maps...\n");

    /*
     * account for space used by ag headers and log if internal
     */
    set_bmap_log(mp);
    set_bmap_fs(mp);

    bad_ino_btree = 0;

    for (i = 0; i < mp->m_sb.sb_agcount; i++)  {
        scan_ag(i);
#ifdef XR_INODE_TRACE
        print_inode_list(i);
#endif
    }

    /*
     * make sure we know about the root inode chunk
     */
    if ((ino_rec = find_inode_rec(0, mp->m_sb.sb_rootino)) == NULL)  {
        ASSERT(mp->m_sb.sb_rbmino == mp->m_sb.sb_rootino + 1 &&
               mp->m_sb.sb_rsumino == mp->m_sb.sb_rootino + 2);
        do_warn("root inode chunk not found\n");

        /*
         * mark the first 3 used, the rest are free
         */
        ino_rec = set_inode_used_alloc(0,
                                       (xfs_agino_t) mp->m_sb.sb_rootino);
        set_inode_used(ino_rec, 1);
        set_inode_used(ino_rec, 2);

        for (j = 3; j < XFS_INODES_PER_CHUNK; j++)
            set_inode_free(ino_rec, j);

        /*
         * also mark blocks
         */
        for (b = 0; b < mp->m_ialloc_blks; b++)  {
            set_agbno_state(mp, 0,
                            b + XFS_INO_TO_AGBNO(mp, mp->m_sb.sb_rootino),
                            XR_E_INO);
        }
    } else  {
        do_log("        - found root inode chunk\n");

        /*
         * blocks are marked, just make sure they're in use
         */
        if (is_inode_free(ino_rec, 0))  {
            do_warn("root inode marked free, ");
            set_inode_used(ino_rec, 0);
            if (!no_modify)
                do_warn("correcting\n");
            else
                do_warn("would correct\n");
        }

        if (is_inode_free(ino_rec, 1))  {
            do_warn("realtime bitmap inode marked free, ");
            set_inode_used(ino_rec, 1);
            if (!no_modify)
                do_warn("correcting\n");
            else
                do_warn("would correct\n");
        }

        if (is_inode_free(ino_rec, 2))  {
            do_warn("realtime summary inode marked free, ");
            set_inode_used(ino_rec, 2);
            if (!no_modify)
                do_warn("correcting\n");
            else
                do_warn("would correct\n");
        }
    }
}
예제 #26
0
void
handler(int sig)
{
	pid_t	pid = getpid();
	int	status, i;

	pid = wait(&status);

	kids--;

	for (i = 0; i < num_targets; i++)  {
		if (target[i].pid == pid)  {
			if (target[i].state == INACTIVE)  {
				/* thread got an I/O error */

				if (target[i].err_type == 0)  {
					do_warn(
		_("%s:  write error on target %d \"%s\" at offset %lld\n"),
						progname, i, target[i].name,
						target[i].position);
				} else  {
					do_warn(
		_("%s:  lseek64 error on target %d \"%s\" at offset %lld\n"),
						progname, i, target[i].name,
						target[i].position);
				}

				do_vfatal(target[i].error,
					_("Aborting target %d - reason"), i);

				if (kids == 0)  {
					do_log(
				_("Aborting XFS copy - no more targets.\n"));
					check_errors();
					pthread_exit(NULL);
				}

				signal(SIGCHLD, handler);
				return;
			} else  {
				/* it just croaked it bigtime, log it */

				do_warn(
	_("%s:  thread %d died unexpectedly, target \"%s\" incomplete\n"),
					progname, i, target[i].name);
				do_warn(_("%s:  offset was probably %lld\n"),
					progname, target[i].position);
				do_fatal(target[i].error,
					_("Aborting XFS copy - reason"));
				pthread_exit(NULL);
			}
		}
	}

	/* unknown child -- something very wrong */

	do_warn(_("%s: Unknown child died (should never happen!)\n"), progname);
	die_perror();
	pthread_exit(NULL);
	signal(SIGCHLD, handler);
}
예제 #27
0
파일: versions.c 프로젝트: Fleurer/xfsprogs
void
update_sb_version(xfs_mount_t *mp)
{
	xfs_sb_t	*sb;
	__uint16_t	vn;

	sb = &mp->m_sb;

	if (fs_attributes && !xfs_sb_version_hasattr(sb))  {
		ASSERT(fs_attributes_allowed);
		xfs_sb_version_addattr(sb);
	}

	if (fs_attributes2 && !xfs_sb_version_hasattr2(sb))  {
		ASSERT(fs_attributes2_allowed);
		xfs_sb_version_addattr2(sb);
	}

	if (fs_inode_nlink && !xfs_sb_version_hasnlink(sb))  {
		ASSERT(fs_inode_nlink_allowed);
		xfs_sb_version_addnlink(sb);
	}

	/*
	 * fix up the superblock version number and feature bits,
	 * turn off quota bits and flags if the filesystem doesn't
	 * have quotas.
	 */
	if (fs_quotas)  {
		if (!xfs_sb_version_hasquota(sb))  {
			ASSERT(fs_quotas_allowed);
			xfs_sb_version_addquota(sb);
		}

		/*
		 * protect against stray bits in the quota flag field
		 */
		if (sb->sb_qflags & ~XFS_MOUNT_QUOTA_ALL) {
			/*
			 * update the incore superblock, if we're in
			 * no_modify mode, it'll never get flushed out
			 * so this is ok.
			 */
			do_warn(_("bogus quota flags 0x%x set in superblock"),
				sb->sb_qflags & ~XFS_MOUNT_QUOTA_ALL);

			sb->sb_qflags &= XFS_MOUNT_QUOTA_ALL;

			if (!no_modify)
				do_warn(_(", bogus flags will be cleared\n"));
			else
				do_warn(_(", bogus flags would be cleared\n"));
		}
	} else  {
		sb->sb_qflags = 0;

		if (xfs_sb_version_hasquota(sb))  {
			lost_quotas = 1;
			vn = sb->sb_versionnum;
			vn &= ~XFS_SB_VERSION_QUOTABIT;

			if (!(vn & XFS_SB_VERSION_ALLFBITS))
				vn = xfs_sb_version_toold(vn);

			ASSERT(vn != 0);
			sb->sb_versionnum = vn;
		}
	}

	if (!fs_aligned_inodes && xfs_sb_version_hasalign(sb))  
		sb->sb_versionnum &= ~XFS_SB_VERSION_ALIGNBIT;
}
예제 #28
0
파일: versions.c 프로젝트: Fleurer/xfsprogs
/*
 * returns 0 if things are fine, 1 if we don't understand
 * this superblock version.  Sets superblock geometry-dependent
 * global variables.
 */
int
parse_sb_version(xfs_sb_t *sb)
{
	int issue_warning;

	fs_attributes = 0;
	fs_attributes2 = 0;
	fs_inode_nlink = 0;
	fs_quotas = 0;
	fs_aligned_inodes = 0;
	fs_sb_feature_bits = 0;
	fs_ino_alignment = 0;
	fs_has_extflgbit = 0;
	have_uquotino = 0;
	have_gquotino = 0;
	have_pquotino = 0;
	issue_warning = 0;

	/*
	 * ok, check to make sure that the sb isn't newer
	 * than we are
	 */
	if (xfs_sb_version_hasextflgbit(sb))  {
		fs_has_extflgbit = 1;
		if (!fs_has_extflgbit_allowed)  {
			issue_warning = 1;
			do_warn(
			_("This filesystem has uninitialized extent flags.\n"));
		}
	}

	if (xfs_sb_version_hasshared(sb))  {
		fs_shared = 1;
		if (!fs_shared_allowed)  {
			issue_warning = 1;
			do_warn(_("This filesystem is marked shared.\n"));
		}
	}

	if (issue_warning)  {
		do_warn(
_("This filesystem uses feature(s) not yet supported in this release.\n"
  "Please run a more recent version of xfs_repair.\n"));
		return(1);
	}

	if (!xfs_sb_good_version(sb))  {
		do_warn(_("WARNING:  unknown superblock version %d\n"),
			XFS_SB_VERSION_NUM(sb));
		do_warn(
_("This filesystem contains features not understood by this program.\n"));
		return(1);
	}

	if (XFS_SB_VERSION_NUM(sb) >= XFS_SB_VERSION_4)  {
		if (!fs_sb_feature_bits_allowed)  {
			if (!no_modify)  {
				do_warn(
_("WARNING:  you have disallowed superblock-feature-bits-allowed\n"
  "\tbut this superblock has feature bits.  The superblock\n"
  "\twill be downgraded.  This may cause loss of filesystem meta-data\n"));
			} else   {
				do_warn(
_("WARNING:  you have disallowed superblock-feature-bits-allowed\n"
  "\tbut this superblock has feature bits.  The superblock\n"
  "\twould be downgraded.  This might cause loss of filesystem\n"
  "\tmeta-data.\n"));
			}
		} else   {
			fs_sb_feature_bits = 1;
		}
	}

	if (xfs_sb_version_hasattr(sb))  {
		if (!fs_attributes_allowed)  {
			if (!no_modify)  {
				do_warn(
_("WARNING:  you have disallowed attributes but this filesystem\n"
  "\thas attributes.  The filesystem will be downgraded and\n"
  "\tall attributes will be removed.\n"));
			} else  {
				do_warn(
_("WARNING:  you have disallowed attributes but this filesystem\n"
  "\thas attributes.  The filesystem would be downgraded and\n"
  "\tall attributes would be removed.\n"));
			}
		} else   {
			fs_attributes = 1;
		}
	}

	if (xfs_sb_version_hasattr2(sb))  {
		if (!fs_attributes2_allowed)  {
			if (!no_modify)  {
				do_warn(
_("WARNING:  you have disallowed attr2 attributes but this filesystem\n"
  "\thas attributes.  The filesystem will be downgraded and\n"
  "\tall attr2 attributes will be removed.\n"));
			} else  {
				do_warn(
_("WARNING:  you have disallowed attr2 attributes but this filesystem\n"
  "\thas attributes.  The filesystem would be downgraded and\n"
  "\tall attr2 attributes would be removed.\n"));
			}
		} else   {
			fs_attributes2 = 1;
		}
	}

	if (xfs_sb_version_hasnlink(sb))  {
		if (!fs_inode_nlink_allowed)  {
			if (!no_modify)  {
				do_warn(
_("WARNING:  you have disallowed version 2 inodes but this filesystem\n"
  "\thas version 2 inodes.  The filesystem will be downgraded and\n"
  "\tall version 2 inodes will be converted to version 1 inodes.\n"
  "\tThis may cause some hard links to files to be destroyed\n"));
			} else  {
				do_warn(
_("WARNING:  you have disallowed version 2 inodes but this filesystem\n"
  "\thas version 2 inodes.  The filesystem would be downgraded and\n"
  "\tall version 2 inodes would be converted to version 1 inodes.\n"
  "\tThis might cause some hard links to files to be destroyed\n"));
			}
		} else   {
			fs_inode_nlink = 1;
		}
	}

	if (xfs_sb_version_hasquota(sb))  {
		if (!fs_quotas_allowed)  {
			if (!no_modify)  {
				do_warn(
_("WARNING:  you have disallowed quotas but this filesystem\n"
  "\thas quotas.  The filesystem will be downgraded and\n"
  "\tall quota information will be removed.\n"));
			} else  {
				do_warn(
_("WARNING:  you have disallowed quotas but this filesystem\n"
  "\thas quotas.  The filesystem would be downgraded and\n"
  "\tall quota information would be removed.\n"));
			}
		} else   {
			fs_quotas = 1;

			if (sb->sb_uquotino != 0 &&
					sb->sb_uquotino != NULLFSINO)
				have_uquotino = 1;

			if (sb->sb_gquotino != 0 &&
					sb->sb_gquotino != NULLFSINO)
				have_gquotino = 1;

			if (sb->sb_pquotino != 0 &&
					sb->sb_pquotino != NULLFSINO)
				have_pquotino = 1;
		}
	}

	if (xfs_sb_version_hasalign(sb))  {
		if (fs_aligned_inodes_allowed)  {
			fs_aligned_inodes = 1;
			fs_ino_alignment = sb->sb_inoalignmt;
		} else   {
			if (!no_modify)  {
				do_warn(
_("WARNING:  you have disallowed aligned inodes but this filesystem\n"
  "\thas aligned inodes.  The filesystem will be downgraded.\n"
  "\tThis will permanently degrade the performance of this filesystem.\n"));
			} else  {
				do_warn(
_("WARNING:  you have disallowed aligned inodes but this filesystem\n"
  "\thas aligned inodes.  The filesystem would be downgraded.\n"
  "\tThis would permanently degrade the performance of this filesystem.\n"));
			}
		}
	}

	/*
	 * calculate maximum file offset for this geometry
	 */
	fs_max_file_offset = 0x7fffffffffffffffLL >> sb->sb_blocklog;

	return(0);
}
예제 #29
0
/*
 * find a secondary superblock, copy it into the sb buffer
 */
int
find_secondary_sb(xfs_sb_t *rsb)
{
	xfs_off_t	off;
	xfs_sb_t	*sb;
	xfs_sb_t	bufsb;
	char		*c_bufsb;
	int		done;
	int		i;
	int		dirty;
	int		retval;
	int		bsize;

	do_warn(_("\nattempting to find secondary superblock...\n"));

	sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE);
	if (!sb) {
		do_error(
	_("error finding secondary superblock -- failed to memalign buffer\n"));
		exit(1);
	}

	memset(&bufsb, 0, sizeof(xfs_sb_t));
	retval = 0;
	dirty = 0;
	bsize = 0;

	/*
	 * skip first sector since we know that's bad
	 */
	for (done = 0, off = XFS_AG_MIN_BYTES; !done ; off += bsize)  {
		/*
		 * read disk 1 MByte at a time.
		 */
		if (lseek64(x.dfd, off, SEEK_SET) != off)  {
			done = 1;
		}

		if (!done && (bsize = read(x.dfd, sb, BSIZE)) <= 0)  {
			done = 1;
		}

		do_warn(".");

		/*
		 * check the buffer 512 bytes at a time since
		 * we don't know how big the sectors really are.
		 */
		for (i = 0; !done && i < bsize; i += BBSIZE)  {
			c_bufsb = (char *)sb + i;
			libxfs_sb_from_disk(&bufsb, (xfs_dsb_t *)c_bufsb);

			if (verify_sb(&bufsb, 0) != XR_OK)
				continue;

			do_warn(_("found candidate secondary superblock...\n"));

			/*
			 * found one.  now verify it by looking
			 * for other secondaries.
			 */
			memmove(rsb, &bufsb, sizeof(xfs_sb_t));
			rsb->sb_inprogress = 0;
			clear_sunit = 1;

			if (verify_set_primary_sb(rsb, 0, &dirty) == XR_OK)  {
				do_warn(
			_("verified secondary superblock...\n"));
				done = 1;
				retval = 1;
			} else  {
				do_warn(
			_("unable to verify superblock, continuing...\n"));
			}
		}
	}

	free(sb);
	return(retval);
}
예제 #30
0
/*
 * the way to verify that a primary sb is consistent with the
 * filesystem is find the secondaries given the info in the
 * primary and compare the geometries in the secondaries against
 * the geometry indicated by the primary.
 *
 * returns 1 if bad, 0 if ok
 */
int
verify_set_primary_sb(xfs_sb_t		*rsb,
			int		sb_index,
			int		*sb_modified)
{
	xfs_off_t	off;
	fs_geometry_t	geo;
	xfs_sb_t	*sb;
	fs_geo_list_t	*list;
	fs_geo_list_t	*current;
	char		*checked;
	xfs_agnumber_t	agno;
	int		num_sbs;
	int		skip;
	int		size;
	int		num_ok;
	int		retval;
	int		round;

	/*
	 * select the number of secondaries to try for
	 */
	num_sbs = MIN(NUM_SBS, rsb->sb_agcount);
	skip = howmany(num_sbs, rsb->sb_agcount);

	/*
	 * We haven't been able to validate the sector size yet properly
	 * (e.g. in the case of repairing an image in a file), so we need to
	 * take into account sector mismatches and so use the maximum possible
	 * sector size rather than the sector size in @rsb.
	 */
	size = NUM_AGH_SECTS * (1 << (XFS_MAX_SECTORSIZE_LOG));
	retval = 0;
	list = NULL;
	num_ok = 0;
	*sb_modified = 0;

	sb = (xfs_sb_t *) alloc_ag_buf(size);
	checked = calloc(rsb->sb_agcount, sizeof(char));
	if (!checked) {
		do_error(_("calloc failed in verify_set_primary_sb\n"));
		exit(1);
	}

	/*
	 * put the primary sb geometry info onto the geometry list
	 */
	checked[sb_index] = 1;
	get_sb_geometry(&geo, rsb);
	list = add_geo(list, &geo, sb_index);

	/*
	 * grab N secondaries.  check them off as we get them
	 * so we only process each one once
	 */
	for (round = 0; round < skip; round++)  {
		for (agno = round; agno < rsb->sb_agcount; agno += skip)  {
			if (checked[agno])
				continue;

			off = (xfs_off_t)agno * rsb->sb_agblocks << rsb->sb_blocklog;

			checked[agno] = 1;

			if (get_sb(sb, off, size, agno) == XR_EOF)  {
				retval = 1;
				goto out;
			}

			if (verify_sb(sb, 0) == XR_OK)  {
				/*
				 * save away geometry info.
				 * don't bother checking the sb
				 * against the agi/agf as the odds
				 * of the sb being corrupted in a way
				 * that it is internally consistent
				 * but not consistent with the rest
				 * of the filesystem is really really low.
				 */
				get_sb_geometry(&geo, sb);
				list = add_geo(list, &geo, agno);
				num_ok++;
			}
		}
	}

	/*
	 * see if we have enough superblocks to bother with
	 */
	if (num_ok < num_sbs / 2)
		return(XR_INSUFF_SEC_SB);

	current = get_best_geo(list);

	/*
	 * check that enough sbs agree that we're willing to
	 * go with this geometry.  if not, print out the
	 * geometry and a message about the force option.
	 */
	switch (num_sbs)  {
	case 2:
		/*
		 * If we only have two allocation groups, and the superblock
		 * in the second allocation group differs from the primary
		 * superblock we can't verify the geometry information.
		 * Warn the user about this situation and get out unless
		 * explicitly overridden.
		 */
		if (current->refs != 2)  {
			if (!force_geo)  {
				do_warn(
	_("Only two AGs detected and they do not match - "
	  "cannot validate filesystem geometry.\n"
	  "Use the -o force_geometry option to proceed.\n"));
				exit(1);
			}
		}
		goto out_free_list;
	case 1:
		/*
		 * If we only have a single allocation group there is no
		 * secondary superblock that we can use to verify the geometry
		 * information.  Warn the user about this situation and get
		 * out unless explicitly overridden.
		 */
		if (!force_geo)  {
			do_warn(
	_("Only one AG detected - "
	  "cannot validate filesystem geometry.\n"
	  "Use the -o force_geometry option to proceed.\n"));
			exit(1);
		}
		goto out_free_list;
	default:
		/*
		 * at least half of the probed superblocks have
		 * to agree.  if they don't, this fs is probably
		 * too far gone anyway considering the fact that
		 * XFS normally doesn't alter the secondary superblocks.
		 */
		if (current->refs < num_sbs / 2)  {
			do_warn(
		_("Not enough matching superblocks - cannot proceed.\n"));
			exit(1);
		}
	}

	/*
	 * set the geometry into primary superblock if necessary.
	 */

	if (current->index != sb_index)  {
		*sb_modified = 1;
		off = (xfs_off_t)current->index * current->geo.sb_agblocks
			* current->geo.sb_blocksize;
		if (get_sb(sb, off, current->geo.sb_sectsize,
				current->index) != XR_OK)
			do_error(_("could not read superblock\n"));

		copy_sb(sb, rsb);

		/*
		 * turn off inprogress bit since this is the primary.
		 * also save away values that we need to ensure are
		 * consistent in the other secondaries.
		 */
		rsb->sb_inprogress = 0;
		sb_inoalignmt = sb->sb_inoalignmt;
		sb_unit = sb->sb_unit;
		sb_width = sb->sb_width;
	}

out_free_list:
	free_geo(list);
out:
	free(sb);
	free(checked);
	return(retval);
}