Example #1
0
void btrfs_print_key(struct btrfs_disk_key *disk_key)
{
	u64 objectid = btrfs_disk_key_objectid(disk_key);
	u8 type = btrfs_disk_key_type(disk_key);
	u64 offset = btrfs_disk_key_offset(disk_key);

	printf("key (");
	print_objectid(objectid, type);
	printf(" ");
	print_key_type(objectid, type);
	switch (type) {
	case BTRFS_QGROUP_RELATION_KEY:
	case BTRFS_QGROUP_INFO_KEY:
	case BTRFS_QGROUP_LIMIT_KEY:
		printf(" %llu/%llu)", btrfs_qgroup_level(offset),
		       btrfs_qgroup_subvid(offset));
		break;
	case BTRFS_UUID_KEY_SUBVOL:
	case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
		printf(" 0x%016llx)", (unsigned long long)offset);
		break;
	default:
		if (offset == (u64)-1)
			printf(" -1)");
		else
			printf(" %llu)", (unsigned long long)offset);
		break;
	}
}
Example #2
0
static int qgroup_assign(int assign, int argc, char **argv)
{
	int ret = 0;
	int fd;
	int e;
	char *path = argv[3];
	struct btrfs_ioctl_qgroup_assign_args args;
	DIR *dirstream = NULL;

	if (check_argc_exact(argc, 4))
		return -1;

	memset(&args, 0, sizeof(args));
	args.assign = assign;
	args.src = parse_qgroupid(argv[1]);
	args.dst = parse_qgroupid(argv[2]);

	/*
	 * FIXME src should accept subvol path
	 */
	if (btrfs_qgroup_level(args.src) >= btrfs_qgroup_level(args.dst)) {
		fprintf(stderr, "ERROR: bad relation requested '%s'\n", path);
		return 1;
	}
	fd = open_file_or_dir(path, &dirstream);
	if (fd < 0) {
		fprintf(stderr, "ERROR: can't access '%s'\n", path);
		return 1;
	}

	ret = ioctl(fd, BTRFS_IOC_QGROUP_ASSIGN, &args);
	e = errno;
	close_file_or_dir(fd, dirstream);
	if (ret < 0) {
		fprintf(stderr, "ERROR: unable to assign quota group: %s\n",
			strerror(e));
		return 1;
	}
	return 0;
}
static int _cmd_qgroup_assign(int assign, int argc, char **argv,
		const char * const *usage_str)
{
	int ret = 0;
	int fd;
	int rescan = 0;
	char *path;
	struct btrfs_ioctl_qgroup_assign_args args;
	DIR *dirstream = NULL;

	if (assign) {
		while (1) {
			enum { GETOPT_VAL_RESCAN = 256, GETOPT_VAL_NO_RESCAN };
			static const struct option long_options[] = {
				{ "rescan", no_argument, NULL,
					GETOPT_VAL_RESCAN },
				{ "no-rescan", no_argument, NULL,
					GETOPT_VAL_NO_RESCAN },
				{ NULL, 0, NULL, 0 }
			};
			int c = getopt_long(argc, argv, "", long_options, NULL);

			if (c < 0)
				break;
			switch (c) {
			case GETOPT_VAL_RESCAN:
				rescan = 1;
				break;
			case GETOPT_VAL_NO_RESCAN:
				rescan = 0;
				break;
			default:
				/* Usage printed by the caller */
				return -1;
			}
		}
	} else {
		clean_args_no_options(argc, argv, usage_str);
	}

	if (check_argc_exact(argc - optind, 3))
		usage(usage_str);

	memset(&args, 0, sizeof(args));
	args.assign = assign;
	args.src = parse_qgroupid(argv[optind]);
	args.dst = parse_qgroupid(argv[optind + 1]);

	path = argv[optind + 2];

	/*
	 * FIXME src should accept subvol path
	 */
	if (btrfs_qgroup_level(args.src) >= btrfs_qgroup_level(args.dst)) {
		error("bad relation requested: %s", path);
		return 1;
	}
	fd = btrfs_open_dir(path, &dirstream, 1);
	if (fd < 0)
		return 1;

	ret = ioctl(fd, BTRFS_IOC_QGROUP_ASSIGN, &args);
	if (ret < 0) {
		error("unable to assign quota group: %s", strerror(errno));
		close_file_or_dir(fd, dirstream);
		return 1;
	}

	/*
	 * If ret > 0, it means assign caused qgroup data inconsistent state.
	 * Schedule a quota rescan if requested.
	 *
	 * The return value change only happens in newer kernel. But will not
	 * cause problem since old kernel has a bug that will never clear
	 * INCONSISTENT bit.
	 */
	if (ret > 0) {
		if (rescan) {
			struct btrfs_ioctl_quota_rescan_args qargs;

			printf("Quota data changed, rescan scheduled\n");
			memset(&qargs, 0, sizeof(qargs));
			ret = ioctl(fd, BTRFS_IOC_QUOTA_RESCAN, &qargs);
			if (ret < 0)
				error("quota rescan failed: %s",
					strerror(errno));
		} else {
			warning("quotas may be inconsistent, rescan needed");
		}
	}
	close_file_or_dir(fd, dirstream);
	return ret;
}
Example #4
0
static void print_objectid(u64 objectid, u8 type)
{
	switch (type) {
	case BTRFS_DEV_EXTENT_KEY:
		printf("%llu", (unsigned long long)objectid); /* device id */
		return;
	case BTRFS_QGROUP_RELATION_KEY:
		printf("%llu/%llu", btrfs_qgroup_level(objectid),
		       btrfs_qgroup_subvid(objectid));
		return;
	case BTRFS_UUID_KEY_SUBVOL:
	case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
		printf("0x%016llx", (unsigned long long)objectid);
		return;
	}

	switch (objectid) {
	case BTRFS_ROOT_TREE_OBJECTID:
		if (type == BTRFS_DEV_ITEM_KEY)
			printf("DEV_ITEMS");
		else
			printf("ROOT_TREE");
		break;
	case BTRFS_EXTENT_TREE_OBJECTID:
		printf("EXTENT_TREE");
		break;
	case BTRFS_CHUNK_TREE_OBJECTID:
		printf("CHUNK_TREE");
		break;
	case BTRFS_DEV_TREE_OBJECTID:
		printf("DEV_TREE");
		break;
	case BTRFS_FS_TREE_OBJECTID:
		printf("FS_TREE");
		break;
	case BTRFS_ROOT_TREE_DIR_OBJECTID:
		printf("ROOT_TREE_DIR");
		break;
	case BTRFS_CSUM_TREE_OBJECTID:
		printf("CSUM_TREE");
		break;
	case BTRFS_BALANCE_OBJECTID:
		printf("BALANCE");
		break;
	case BTRFS_ORPHAN_OBJECTID:
		printf("ORPHAN");
		break;
	case BTRFS_TREE_LOG_OBJECTID:
		printf("TREE_LOG");
		break;
	case BTRFS_TREE_LOG_FIXUP_OBJECTID:
		printf("LOG_FIXUP");
		break;
	case BTRFS_TREE_RELOC_OBJECTID:
		printf("TREE_RELOC");
		break;
	case BTRFS_DATA_RELOC_TREE_OBJECTID:
		printf("DATA_RELOC_TREE");
		break;
	case BTRFS_EXTENT_CSUM_OBJECTID:
		printf("EXTENT_CSUM");
		break;
	case BTRFS_FREE_SPACE_OBJECTID:
		printf("FREE_SPACE");
		break;
	case BTRFS_FREE_INO_OBJECTID:
		printf("FREE_INO");
		break;
	case BTRFS_QUOTA_TREE_OBJECTID:
		printf("QUOTA_TREE");
		break;
	case BTRFS_UUID_TREE_OBJECTID:
		printf("UUID_TREE");
		break;
	case BTRFS_MULTIPLE_OBJECTIDS:
		printf("MULTIPLE");
		break;
	case (u64)-1:
		printf("-1");
		break;
	case BTRFS_FIRST_CHUNK_TREE_OBJECTID:
		if (type == BTRFS_CHUNK_ITEM_KEY) {
			printf("FIRST_CHUNK_TREE");
			break;
		}
		/* fall-thru */
	default:
		printf("%llu", (unsigned long long)objectid);
	}
}