[Ocfs2-tools-devel] [PATCH 5/7] Ocfs2-tools: Add implementation of operations to o2info.

Sunil Mushran sunil.mushran at oracle.com
Mon Nov 30 15:58:54 PST 2009


Note my review of the kernel code vis-a-vis typedef struct.


Tristan Ye wrote:
> All of o2info's operations will be linked to a task list,
> and executed one by one later, the real running code of
> a new item for o2info is expected to be added there.
>
> Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
> ---
>  o2info/o2info_operations.c |  330 ++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 330 insertions(+), 0 deletions(-)
>  create mode 100644 o2info/o2info_operations.c
>
> diff --git a/o2info/o2info_operations.c b/o2info/o2info_operations.c
> new file mode 100644
> index 0000000..7470503
> --- /dev/null
> +++ b/o2info/o2info_operations.c
> @@ -0,0 +1,330 @@
> +/* -*- mode: c; c-basic-offset: 8; -*-
> + * vim: noexpandtab sw=8 ts=8 sts=0:
> + *
> + * o2info_operations.c
> + *
> + * Operation helpers for o2info utility
> + *
> + * Copyright (C) 2009 Oracle.  All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public
> + * License version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + */
> +
> +#include "o2info_utils.h"
> +
> +typedef struct ocfs2_info_request OIR, *POIR;
> +typedef struct ocfs2_info_request_clustersize OIRC, *POIRC;
> +typedef struct ocfs2_info_request_blocksize OIRB, *POIRB;
> +typedef struct ocfs2_info_request_slotnum OIRS, *POIRS;
> +typedef struct ocfs2_info_request_label OIRL, *POIRL;
> +typedef struct ocfs2_info_request_uuid OIRU, *POIRU;
> +typedef struct ocfs2_info_request_fs_features OIRF, *POIRF;
> +
> +static int freefrag_run(struct o2info_operation *op,
> +			struct o2info_method *om,
> +			void *arg)
> +{
> +	return 0;
> +}
> +
> +DEFINE_O2INFO_OP(freefrag,
> +		 freefrag_run,
> +		 NULL);
> +
> +static int freeinode_run(struct o2info_operation *op,
> +			 struct o2info_method *om,
> +			 void *arg)
> +{
> +	return 0;
> +}
> +
> +DEFINE_O2INFO_OP(freeinode,
> +		 freeinode_run,
> +		 NULL);
> +
> +static int filestat_run(struct o2info_operation *op,
> +			struct o2info_method *om,
> +			void *arg)
> +{
> +	return 0;
> +}
> +
> +DEFINE_O2INFO_OP(filestat,
> +		 filestat_run,
> +		 NULL);
> +
> +static int usage_run(struct o2info_operation *op,
> +		     struct o2info_method *om,
> +		     void *arg)
> +{
> +	return 0;
> +}
> +
> +DEFINE_O2INFO_OP(usage,
> +		 usage_run,
> +		 NULL);
> +
> +struct o2info_volinfo {
> +	uint32_t blocksize;
> +	uint32_t clustersize;
> +	uint16_t slotnum;
> +	uint8_t label[OCFS2_MAX_VOL_LABEL_LEN];
> +	uint8_t uuid[OCFS2_VOL_UUID_LEN];
> +};
> +
> +static int get_volinfo(struct o2info_operation *op, struct o2info_method *om,
> +		       struct o2info_volinfo *vf)
> +{
> +	int rc = 0;
> +	struct ocfs2_super_block *sb = NULL;
> +
> +	if (om->method & USE_LIBOCFS2) {
> +		sb = OCFS2_RAW_SB(om->fs->fs_super);
> +		vf->blocksize = 1 << sb->s_blocksize_bits;
> +		vf->clustersize = 1 << sb->s_clustersize_bits;
> +		vf->slotnum = sb->s_max_slots;
> +		memmove(vf->label, sb->s_label, OCFS2_MAX_VOL_LABEL_LEN);
> +		memmove(vf->uuid, sb->s_uuid, OCFS2_VOL_UUID_LEN);
> +		goto out;
> +	}
> +
> +	if (om->method & USE_IOCTL) {
> +		struct ocfs2_info_request_blocksize brq = {
> +			{	OCFS2_INFO_BLOCKSIZE,
> +				OCFS2_INFO_FL_NON_COHERENT},
> +			0
> +		};
> +
> +		struct ocfs2_info_request_clustersize crq = {
> +			{	OCFS2_INFO_CLUSTERSIZE,
> +				OCFS2_INFO_FL_NON_COHERENT},
> +			0
> +		};
> +
> +		struct ocfs2_info_request_slotnum srq = {
> +			{	OCFS2_INFO_SLOTNUM,
> +				OCFS2_INFO_FL_NON_COHERENT},
> +			0
> +		};
> +
> +		struct ocfs2_info_request_label lrq = {
> +			{	OCFS2_INFO_LABEL,
> +				OCFS2_INFO_FL_NON_COHERENT},
> +		};
> +		memset(lrq.ir_label, 0, OCFS2_MAX_VOL_LABEL_LEN);
> +
> +		struct ocfs2_info_request_uuid urq = {
> +			{	OCFS2_INFO_UUID,
> +				OCFS2_INFO_FL_NON_COHERENT},
> +		};
> +		memset(urq.ir_uuid, 0, OCFS2_VOL_UUID_LEN);
> +
> +		/*
> +		 * Note: the requests in array need to be NULL-terminated
> +		 * to let kernel understand.
> +		 */
> +		struct ocfs2_info_request *info[6] = {(POIR)&brq,
> +						      (POIR)&crq,
> +						      (POIR)&srq,
> +						      (POIR)&lrq,
> +						      (POIR)&urq,
> +						      NULL};
> +
> +		rc = ioctl(om->fd, OCFS2_IOC_INFO, info);
> +		if (rc) {
> +			rc = errno;
> +			fprintf(stderr, "ioctl failed:%d %s\n", rc,
> +				strerror(rc));
> +			goto out;
> +		}
> +
> +		if (info[0]->ir_flags & OCFS2_INFO_FL_FILLED)
> +			vf->blocksize = ((POIRB)info[0])->ir_blocksize;
> +		else
> +			vf->blocksize = 0;
> +
> +		if (info[1]->ir_flags & OCFS2_INFO_FL_FILLED)
> +			vf->clustersize = ((POIRC)info[1])->ir_clustersize;
> +		else
> +			vf->clustersize = 0;
> +
> +		if (info[2]->ir_flags & OCFS2_INFO_FL_FILLED)
> +			vf->slotnum = ((POIRS)info[2])->ir_slotnum;
> +		else
> +			vf->slotnum = 0;
> +
> +		if (info[3]->ir_flags & OCFS2_INFO_FL_FILLED)
> +			memmove(vf->label, ((POIRL)info[3])->ir_label,
> +				OCFS2_MAX_VOL_LABEL_LEN);
> +		else
> +			memset(vf->label, 0, OCFS2_MAX_VOL_LABEL_LEN);
> +
> +		if (info[4]->ir_flags & OCFS2_INFO_FL_FILLED)
> +			memmove(vf->uuid, ((POIRU)info[4])->ir_uuid,
> +				OCFS2_VOL_UUID_LEN);
> +		else
> +			memset(vf->uuid, 0, OCFS2_VOL_UUID_LEN);
> +
> +		goto out;
> +	}
> +out:
> +	return rc;
> +}
> +
> +static int volinfo_run(struct o2info_operation *op,
> +		       struct o2info_method *om,
> +		       void *arg)
> +{
> +	int i, count, max, rc = 0;
> +	struct o2info_volinfo vf;
> +
> +	const char *items[] = {
> +		"Block Size:",
> +		"Cluster Size:",
> +		"Node Slots:",
> +		"Label:",
> +		"UUID:"
> +	};
> +
> +	rc = get_volinfo(op, om, &vf);
> +	if (rc)
> +		goto out;
> +
> +	count = sizeof(items) / sizeof(char *);
> +	max = max_str_len(items, count);
> +
> +	fprintf_aligned_space(stdout, max, items[0]);
> +	fprintf(stdout, "%s %u\n", items[0], vf.blocksize);
> +	fprintf_aligned_space(stdout, max, items[1]);
> +	fprintf(stdout, "%s %u\n", items[1], vf.clustersize);
> +	fprintf_aligned_space(stdout, max, items[2]);
> +	fprintf(stdout, "%s %u\n", items[2], vf.slotnum);
> +	fprintf_aligned_space(stdout, max, items[3]);
> +	fprintf(stdout, "%s %.*s\n", items[3], OCFS2_MAX_VOL_LABEL_LEN,
> +		vf.label);
> +	fprintf_aligned_space(stdout, max, items[4]);
> +	fprintf(stdout, "%s ", items[4]);
> +	for (i = 0; i < OCFS2_VOL_UUID_LEN; i++)
> +		fprintf(stdout, "%02X", vf.uuid[i]);
> +	fprintf(stdout, "\n");
> +
> +out:
> +	return rc;
> +}
> +
> +DEFINE_O2INFO_OP(volinfo,
> +		 volinfo_run,
> +		 NULL);
> +
> +struct o2info_fs_features {
> +	uint32_t compat;
> +	uint32_t incompat;
> +	uint32_t rocompat;
> +};
> +
> +static int get_fs_features(struct o2info_operation *op,
> +			   struct o2info_method *om,
> +			   struct o2info_fs_features *ofs)
> +{
> +	int rc = 0;
> +	struct ocfs2_super_block *sb = NULL;
> +
> +	if (om->method & USE_LIBOCFS2) {
> +		sb = OCFS2_RAW_SB(om->fs->fs_super);
> +		ofs->compat = sb->s_feature_compat;
> +		ofs->incompat = sb->s_feature_incompat;
> +		ofs->rocompat = sb->s_feature_ro_compat;
> +		goto out;
> +	}
> +
> +	if (om->method & USE_IOCTL) {
> +		struct ocfs2_info_request_fs_features frq = {
> +			{	OCFS2_INFO_FS_FEATURES,
> +				OCFS2_INFO_FL_NON_COHERENT},
> +			0,
> +			0,
> +			0
> +		};
> +
> +		struct ocfs2_info_request *info[2] = {(POIR)&frq, NULL};
> +
> +		rc = ioctl(om->fd, OCFS2_IOC_INFO, info);
> +		if (rc) {
> +			rc = errno;
> +			fprintf(stderr, "ioctl failed:%d %s\n", rc,
> +				strerror(rc));
> +			goto out;
> +		}
> +
> +		if (info[0]->ir_flags & OCFS2_INFO_FL_FILLED) {
> +			ofs->compat = ((POIRF)info[0])->ir_compat_features;
> +			ofs->incompat = ((POIRF)info[0])->ir_incompat_features;
> +			ofs->rocompat = ((POIRF)info[0])->ir_ro_compat_features;
> +		} else {
> +			ofs->compat = 0;
> +			ofs->incompat = 0;
> +			ofs->rocompat = 0;
> +		}
> +	}
> +
> +out:
> +	return rc;
> +}
> +
> +static int fs_features_run(struct o2info_operation *op,
> +			   struct o2info_method *om,
> +			   void *arg)
> +{
> +	int count, max, rc = 0;
> +	struct o2info_fs_features ofs;
> +
> +	GString *compat = NULL;
> +	GString *incompat = NULL;
> +	GString *rocompat = NULL;
> +
> +	const char *items[] = {
> +		"Feature Compat:",
> +		"Feature Incompat:",
> +		"Feature RO compat:"
> +	};
> +
> +	compat = g_string_new(NULL);
> +	incompat = g_string_new(NULL);
> +	rocompat = g_string_new(NULL);
> +
> +	rc = get_fs_features(op, om, &ofs);
> +
> +	get_compat_flag(ofs.compat, compat);
> +	get_incompat_flag(ofs.incompat, incompat);
> +	get_rocompat_flag(ofs.rocompat, rocompat);
> +
> +	count = sizeof(items) / sizeof(char *);
> +	max = max_str_len(items, count);
> +
> +	fprintf_aligned_space(stdout, max, items[0]);
> +	fprintf(stdout, "%s %u %s\n", items[0], ofs.compat,
> +		compat->str);
> +	fprintf_aligned_space(stdout, max, items[1]);
> +	fprintf(stdout, "%s %u %s\n", items[1], ofs.incompat,
> +		incompat->str);
> +	fprintf_aligned_space(stdout, max, items[2]);
> +	fprintf(stdout, "%s %u %s\n", items[2], ofs.rocompat,
> +		rocompat->str);
> +
> +	g_string_free(compat, 1);
> +	g_string_free(incompat, 1);
> +	g_string_free(rocompat, 1);
> +
> +	return rc;
> +}
> +
> +DEFINE_O2INFO_OP(fs_features,
> +		 fs_features_run,
> +		 NULL);
>   




More information about the Ocfs2-tools-devel mailing list