Example #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;
}
Example #2
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;
}