Esempio n. 1
0
/*
 * XXX: this only supports reading and writing to version 4 superblock fields.
 * V5 superblocks always define certain V4 feature bits - they are blocked from
 * being changed if a V5 sb is detected, but otherwise v5 superblock features
 * are not handled here.
 */
static int
version_f(
	int		argc,
	char		**argv)
{
	__uint16_t	version = 0;
	__uint32_t	features = 0;
	xfs_agnumber_t	ag;

	if (argc == 2) {	/* WRITE VERSION */

		if ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode) {
			dbprintf(_("%s: not in expert mode, writing disabled\n"),
				progname);
			return 0;
		}

		/* Logic here derived from the IRIX xfs_chver(1M) script. */
		if (!strcasecmp(argv[1], "extflg")) {
			switch (XFS_SB_VERSION_NUM(&mp->m_sb)) {
			case XFS_SB_VERSION_1:
				version = 0x0004 | XFS_SB_VERSION_EXTFLGBIT;
				break;
			case XFS_SB_VERSION_2:
				version = 0x0014 | XFS_SB_VERSION_EXTFLGBIT;
				break;
			case XFS_SB_VERSION_3:
				version = 0x0034 | XFS_SB_VERSION_EXTFLGBIT;
				break;
			case XFS_SB_VERSION_4:
				if (xfs_sb_version_hasextflgbit(&mp->m_sb))
					dbprintf(
		_("unwritten extents flag is already enabled\n"));
				else
					version = mp->m_sb.sb_versionnum |
						  XFS_SB_VERSION_EXTFLGBIT;
				break;
			case XFS_SB_VERSION_5:
				dbprintf(
		_("unwritten extents always enabled for v5 superblocks.\n"));
				break;
			}
		} else if (!strcasecmp(argv[1], "log2")) {
			switch (XFS_SB_VERSION_NUM(&mp->m_sb)) {
			case XFS_SB_VERSION_1:
				version = 0x0004 | XFS_SB_VERSION_LOGV2BIT;
				break;
			case XFS_SB_VERSION_2:
				version = 0x0014 | XFS_SB_VERSION_LOGV2BIT;
				break;
			case XFS_SB_VERSION_3:
				version = 0x0034 | XFS_SB_VERSION_LOGV2BIT;
				break;
			case XFS_SB_VERSION_4:
				if (xfs_sb_version_haslogv2(&mp->m_sb))
					dbprintf(
		_("version 2 log format is already in use\n"));
				else
					version = mp->m_sb.sb_versionnum |
						  XFS_SB_VERSION_LOGV2BIT;
				break;
			case XFS_SB_VERSION_5:
				dbprintf(
		_("Version 2 logs always enabled for v5 superblocks.\n"));
				break;
			}
		} else if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) {
			dbprintf(
		_("%s: Cannot change %s on v5 superblocks.\n"),
				progname, argv[1]);
			return 0;
		} else if (!strcasecmp(argv[1], "attr1")) {

			if (xfs_sb_version_hasattr2(&mp->m_sb)) {
				if (!(mp->m_sb.sb_features2 &=
						~XFS_SB_VERSION2_ATTR2BIT))
					mp->m_sb.sb_versionnum &=
						~XFS_SB_VERSION_MOREBITSBIT;
			}
			xfs_sb_version_addattr(&mp->m_sb);
			version = mp->m_sb.sb_versionnum;
			features = mp->m_sb.sb_features2;
		} else if (!strcasecmp(argv[1], "attr2")) {
			xfs_sb_version_addattr(&mp->m_sb);
			xfs_sb_version_addattr2(&mp->m_sb);
			version = mp->m_sb.sb_versionnum;
			features = mp->m_sb.sb_features2;
		} else if (!strcasecmp(argv[1], "projid32bit")) {
			xfs_sb_version_addprojid32bit(&mp->m_sb);
			version = mp->m_sb.sb_versionnum;
			features = mp->m_sb.sb_features2;
		} else {
			dbprintf(_("%s: invalid version change command \"%s\"\n"),
				progname, argv[1]);
			return 0;
		}

		if (version) {
			dbprintf(_("writing all SBs\n"));
			for (ag = 0; ag < mp->m_sb.sb_agcount; ag++)
				if (!do_version(ag, version, features)) {
					dbprintf(_("failed to set versionnum "
						 "in AG %d\n"), ag);
					break;
				}
			mp->m_sb.sb_versionnum = version;
			mp->m_sb.sb_features2 = features;
		}
	}

	if (argc == 3) {	/* VERSIONNUM + FEATURES2 */
		char	*sp;

		version = mp->m_sb.sb_versionnum;
		features = mp->m_sb.sb_features2;
		mp->m_sb.sb_versionnum = strtoul(argv[1], &sp, 0);
		mp->m_sb.sb_features2 = strtoul(argv[2], &sp, 0);
	}

	dbprintf(_("versionnum [0x%x+0x%x] = %s\n"), mp->m_sb.sb_versionnum,
			mp->m_sb.sb_features2, version_string(&mp->m_sb));

	if (argc == 3) {	/* now reset... */
		mp->m_sb.sb_versionnum = version;
		mp->m_sb.sb_features2 = features;
		return 0;
	}

	return 0;
}
Esempio n. 2
0
static char *
version_string(
	xfs_sb_t	*sbp)
{
	static char	s[1024];

	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_1)
		strcpy(s, "V1");
	else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_2)
		strcpy(s, "V2");
	else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_3)
		strcpy(s, "V3");
	else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4)
		strcpy(s, "V4");
	else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
		strcpy(s, "V5");

	/*
	 * We assume the state of these features now, so macros don't exist for
	 * them any more.
	 */
	if (sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT)
		strcat(s, ",NLINK");
	if (sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT)
		strcat(s, ",SHARED");
	if (sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT)
		strcat(s, ",DIRV2");

	if (xfs_sb_version_hasattr(sbp))
		strcat(s, ",ATTR");
	if (xfs_sb_version_hasquota(sbp))
		strcat(s, ",QUOTA");
	if (xfs_sb_version_hasalign(sbp))
		strcat(s, ",ALIGN");
	if (xfs_sb_version_hasdalign(sbp))
		strcat(s, ",DALIGN");
	if (xfs_sb_version_haslogv2(sbp))
		strcat(s, ",LOGV2");
	if (xfs_sb_version_hasextflgbit(sbp))
		strcat(s, ",EXTFLG");
	if (xfs_sb_version_hassector(sbp))
		strcat(s, ",SECTOR");
	if (xfs_sb_version_hasasciici(sbp))
		strcat(s, ",ASCII_CI");
	if (xfs_sb_version_hasmorebits(sbp))
		strcat(s, ",MOREBITS");
	if (xfs_sb_version_hasattr2(sbp))
		strcat(s, ",ATTR2");
	if (xfs_sb_version_haslazysbcount(sbp))
		strcat(s, ",LAZYSBCOUNT");
	if (xfs_sb_version_hasprojid32bit(sbp))
		strcat(s, ",PROJID32BIT");
	if (xfs_sb_version_hascrc(sbp))
		strcat(s, ",CRC");
	if (xfs_sb_version_hasftype(sbp))
		strcat(s, ",FTYPE");
	if (xfs_sb_version_hasfinobt(sbp))
		strcat(s, ",FINOBT");
	if (xfs_sb_version_hassparseinodes(sbp))
		strcat(s, ",SPARSE_INODES");
	if (xfs_sb_version_hasmetauuid(sbp))
		strcat(s, ",META_UUID");
	return s;
}
Esempio n. 3
0
/*
 * 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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/*
 * Mount structure initialization, provides a filled-in xfs_mount_t
 * such that the numerous XFS_* macros can be used.  If dev is zero,
 * no IO will be performed (no size checks, read root inodes).
 */
xfs_mount_t *
libxfs_mount(
	xfs_mount_t	*mp,
	xfs_sb_t	*sb,
	dev_t		dev,
	dev_t		logdev,
	dev_t		rtdev,
	int		flags)
{
	xfs_daddr_t	d;
	xfs_buf_t	*bp;
	xfs_sb_t	*sbp;
	int		error;

	libxfs_buftarg_init(mp, dev, logdev, rtdev);

	mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT);
	mp->m_sb = *sb;
	INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL);
	sbp = &(mp->m_sb);

	xfs_sb_mount_common(mp, sb);

	xfs_alloc_compute_maxlevels(mp);
	xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
	xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
	xfs_ialloc_compute_maxlevels(mp);

	if (sbp->sb_imax_pct) {
		/* Make sure the maximum inode count is a multiple of the
		 * units we allocate inodes in.
		 */
		mp->m_maxicount = (sbp->sb_dblocks * sbp->sb_imax_pct) / 100;
		mp->m_maxicount = ((mp->m_maxicount / mp->m_ialloc_blks) *
				  mp->m_ialloc_blks)  << sbp->sb_inopblog;
	} else
		mp->m_maxicount = 0;

	mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;

	/*
	 * Set whether we're using stripe alignment.
	 */
	if (xfs_sb_version_hasdalign(&mp->m_sb)) {
		mp->m_dalign = sbp->sb_unit;
		mp->m_swidth = sbp->sb_width;
	}

	/*
	 * Set whether we're using inode alignment.
	 */
	if (xfs_sb_version_hasalign(&mp->m_sb) &&
	    mp->m_sb.sb_inoalignmt >=
	    XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
		mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
	else
		mp->m_inoalign_mask = 0;
	/*
	 * If we are using stripe alignment, check whether
	 * the stripe unit is a multiple of the inode alignment
	 */
	if (mp->m_dalign && mp->m_inoalign_mask &&
					!(mp->m_dalign & mp->m_inoalign_mask))
		mp->m_sinoalign = mp->m_dalign;
	else
		mp->m_sinoalign = 0;

	/*
	 * Check that the data (and log if separate) are an ok size.
	 */
	d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
	if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
		fprintf(stderr, _("%s: size check failed\n"), progname);
		if (!(flags & LIBXFS_MOUNT_DEBUGGER))
			return NULL;
	}

	/*
	 * We automatically convert v1 inodes to v2 inodes now, so if
	 * the NLINK bit is not set we can't operate on the filesystem.
	 */
	if (!(sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {

		fprintf(stderr, _(
	"%s: V1 inodes unsupported. Please try an older xfsprogs.\n"),
				 progname);
		exit(1);
	}

	/* Check for supported directory formats */
	if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT)) {

		fprintf(stderr, _(
	"%s: V1 directories unsupported. Please try an older xfsprogs.\n"),
				 progname);
		exit(1);
	}

	/* check for unsupported other features */
	if (!xfs_sb_good_version(sbp)) {
		fprintf(stderr, _(
	"%s: Unsupported features detected. Please try a newer xfsprogs.\n"),
				 progname);
		exit(1);
	}

	xfs_da_mount(mp);

	if (xfs_sb_version_hasattr2(&mp->m_sb))
		mp->m_flags |= LIBXFS_MOUNT_ATTR2;

	/* Initialize the precomputed transaction reservations values */
	xfs_trans_init(mp);

	if (dev == 0)	/* maxtrres, we have no device so leave now */
		return mp;

	bp = libxfs_readbuf(mp->m_dev,
			d - XFS_FSS_TO_BB(mp, 1), XFS_FSS_TO_BB(mp, 1),
			!(flags & LIBXFS_MOUNT_DEBUGGER), NULL);
	if (!bp) {
		fprintf(stderr, _("%s: data size check failed\n"), progname);
		if (!(flags & LIBXFS_MOUNT_DEBUGGER))
			return NULL;
	} else
		libxfs_putbuf(bp);

	if (mp->m_logdev_targp->dev &&
	    mp->m_logdev_targp->dev != mp->m_ddev_targp->dev) {
		d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
		if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) ||
		     (!(bp = libxfs_readbuf(mp->m_logdev_targp,
					d - XFS_FSB_TO_BB(mp, 1),
					XFS_FSB_TO_BB(mp, 1),
					!(flags & LIBXFS_MOUNT_DEBUGGER), NULL))) ) {
			fprintf(stderr, _("%s: log size checks failed\n"),
					progname);
			if (!(flags & LIBXFS_MOUNT_DEBUGGER))
				return NULL;
		}
		if (bp)
			libxfs_putbuf(bp);
	}

	/* Initialize realtime fields in the mount structure */
	if (rtmount_init(mp, flags)) {
		fprintf(stderr, _("%s: realtime device init failed\n"),
			progname);
			return NULL;
	}

	error = libxfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
	if (error) {
		fprintf(stderr, _("%s: perag init failed\n"),
			progname);
		exit(1);
	}

	return mp;
}