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

Tristan Ye tristan.ye at oracle.com
Mon Nov 23 04:17:57 PST 2009


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 |  300 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 300 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..1d0d527
--- /dev/null
+++ b/o2info/o2info_operations.c
@@ -0,0 +1,300 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * o2info_operations.c
+ *
+ * Operation helpers for o2info utility 
+ *
+ * Copyright (C) 2008 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"
+
+static int freefrag_run(struct o2info_operation *op, ocfs2_filesys *fs, void *arg)
+{
+	return 0;
+}
+
+DEFINE_O2INFO_OP(freefrag,
+		 freefrag_run,
+		 NULL);
+
+static int freeinode_run(struct o2info_operation *op, ocfs2_filesys *fs, void *arg)
+{
+	return 0;
+}
+
+DEFINE_O2INFO_OP(freeinode,
+		 freeinode_run,
+		 NULL);
+
+static int filestat_run(struct o2info_operation *op, ocfs2_filesys *fs, void *arg)
+{
+	int rc = 0;
+	errcode_t err;
+	uint16_t perm;
+	struct stat st;
+	uint32_t clusters;
+	uint32_t extents = 0;
+	uint32_t shared_clusters;
+	int clusters_per_mb;
+	float frag, score;
+
+	char *path = NULL, *link = NULL, *filetype = NULL, *h_perm = NULL;
+	char *uname = NULL, *gname = NULL;
+	char *ah_time = NULL, *ch_time = NULL, *mh_time = NULL, *buf = NULL;
+
+	struct ocfs2_dinode *di;
+
+	path = strdup((char *)arg);
+	if (!path) {
+		errorf("No memory to for allocation.\n");
+		goto out;
+	}
+
+	rc = lstat(path, &st);
+	if (rc < 0) {
+		rc = errno;
+		fprintf(stderr, "stat error %d: \"%s\"\n", rc, strerror(rc));
+                goto out;
+	}
+
+	if (S_ISLNK(st.st_mode)) {
+		link = (char *)malloc(PATH_MAX);
+		rc = readlink((char *)arg, link, PATH_MAX);
+		if (rc < 0) {
+			fprintf(stderr, "readlink error %d: \"%s\"\n",
+				rc, strerror(rc));
+			goto out;
+		} else 
+			link[rc] = '\0';
+	
+		path = realloc(path, strlen(link) + strlen(path)  + strlen(" -> ") + 1);
+		if (!path) {
+			errorf("No memory to for allocation.\n");
+			goto out;
+		}
+
+		strcat(path, " -> ");
+		strcat(path, link);
+	}
+
+	rc = get_filetype(st.st_mode, &filetype);
+	if (rc)
+		goto out;
+
+	if (S_ISREG(st.st_mode) && st.st_size == 0)
+		strcpy(filetype, "regular empty file");
+
+	rc = uid2name(st.st_uid, &uname);
+	if (rc)
+		goto out;
+
+	rc = gid2name(st.st_gid, &gname);
+	if (rc)
+		goto out;
+	
+	rc = get_human_permission(st.st_mode, &perm, &h_perm);
+	if (rc)
+		goto out;
+
+	err = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (err) {
+		tcom_err(err, "While allocating block");
+		goto out;
+	}
+
+	err = ocfs2_read_inode(fs, st.st_ino, buf);
+	if (err) {
+		tcom_err(err, "While reading inode");
+		goto out;
+	}
+
+	di = (struct ocfs2_dinode *)buf;
+	clusters = di->i_clusters;
+
+	if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL)) {
+		err = calc_num_extents(fs, &(di->id2.i_list), &extents);
+		if (err) {
+			tcom_err(err, "While calculating extents");
+			goto out;
+		}
+	}
+
+	clusters_per_mb = ocfs2_clusters_in_bytes(fs, OCFS2_MAX_CLUSTERSIZE);
+	
+	if (clusters > 1 && extents) {
+		float e = extents, c = clusters;
+		frag = 100 * (e / c);
+	}
+	
+	score = frag * clusters_per_mb;
+
+	err = cal_clusters_refcounted(fs, st.st_ino, 0, &shared_clusters);
+	if (err) {
+		tcom_err(err, "while walking file's extents");
+		goto out;
+	}
+
+	fprintf(stdout, "  File: %s\n", path);
+	fprintf(stdout, "  Size: %-10d\tBlocks: %-10u IO Block: %-6u %s\n",
+		st.st_size, st.st_blocks, st.st_blksize, filetype);
+	 if (S_ISBLK (st.st_mode) || S_ISCHR (st.st_mode))
+		fprintf(stdout, "Device: %xh/%dd\tInode: %-10i  Links: %-5u"
+			" Device type: %u,%u\n", st.st_dev, st.st_dev,
+			st.st_ino, st.st_nlink,
+			st.st_dev >> 16UL, st.st_dev & 0x0000FFFF);
+	else
+		fprintf(stdout, "Device: %xh/%dd\tInode: %-10i  Links: %u\n",
+			st.st_dev, st.st_dev, st.st_ino, st.st_nlink);
+	fprintf(stdout, " Frag%: %-10.2f\tClusters: %-8u Extents: "
+		"%-6lu Score: %.0f\n", frag, clusters, extents, score);
+	fprintf(stdout, "Shared: %-10u\tUnwritten: \tHoles: \n", shared_clusters);
+	fprintf(stdout, "Access: (%04o/%10s)  Uid: (%5u/%8s)   Gid: (%5u/%8s)\n",
+		perm, h_perm, st.st_uid, uname, st.st_gid, gname);
+
+	ah_time = get_human_time(get_stat_atime(&st));
+	mh_time = get_human_time(get_stat_mtime(&st));
+	ch_time = get_human_time(get_stat_ctime(&st));
+
+	fprintf(stdout, "Access: %s\n", ah_time);
+	fprintf(stdout, "Modify: %s\n", mh_time);
+	fprintf(stdout, "Change: %s\n", ch_time);
+
+out:
+	if (path)
+		ocfs2_free(&path);
+	if (link)
+		ocfs2_free(&link);
+	if (filetype)
+		ocfs2_free(&filetype);
+	if (uname)
+		ocfs2_free(&uname);
+	if (gname)
+		ocfs2_free(&gname);
+	if (h_perm)
+		ocfs2_free(&h_perm);
+
+	if (ah_time)
+		ocfs2_free(&ah_time);
+
+	if (mh_time)
+		ocfs2_free(&mh_time);
+
+	if (ch_time)
+		ocfs2_free(&ch_time);
+
+	if (buf)
+		ocfs2_free(&buf);
+
+	return rc;
+}
+
+DEFINE_O2INFO_OP(filestat,
+		 filestat_run,
+		 NULL);
+
+static int usage_run(struct o2info_operation *op, ocfs2_filesys *fs, void *arg)
+{
+	return 0;
+} 
+DEFINE_O2INFO_OP(usage,
+		 usage_run,
+		 NULL);
+
+static int volinfo_run(struct o2info_operation *op, ocfs2_filesys *fs, void *arg)
+{
+	int i, count, max;
+	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);
+
+	const char *items[] = {
+		"Block Size:",
+		"Cluster Size:",
+		"Node Slots:",
+		"Label:",
+		"UUID:"
+	};
+
+	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], 1 << sb->s_blocksize_bits);
+	fprintf_aligned_space(stdout, max, items[1]);
+	fprintf(stdout, "%s %u\n", items[1], 1 << sb->s_clustersize_bits);
+	fprintf_aligned_space(stdout, max, items[2]);
+	fprintf(stdout, "%s %u\n", items[2], sb->s_max_slots);
+	fprintf_aligned_space(stdout, max, items[3]);
+	fprintf(stdout, "%s %.*s\n", items[3], OCFS2_MAX_VOL_LABEL_LEN,
+		sb->s_label);
+	fprintf_aligned_space(stdout, max, items[4]);
+	fprintf(stdout, "%s ", items[4]);
+	for (i = 0; i < 16; i++)
+		fprintf(stdout, "%02X", sb->s_uuid[i]);
+	fprintf(stdout, "\n");
+
+	return 0;
+}
+
+DEFINE_O2INFO_OP(volinfo,
+		 volinfo_run,
+		 NULL);
+
+static int fs_features_run(struct o2info_operation *op, ocfs2_filesys *fs, void *arg)
+{
+	struct ocfs2_super_block *sb;
+	GString *compat = NULL;
+	GString *incompat = NULL;
+	GString *rocompat = NULL;
+
+	const char *items[] = {
+		"Feature Compat:",
+		"Feature Incompat:",
+		"Feature RO compat:"
+        };
+
+	int count, max;
+
+	sb = OCFS2_RAW_SB(fs->fs_super);
+
+	compat = g_string_new(NULL);
+	incompat = g_string_new(NULL);
+	rocompat = g_string_new(NULL);
+
+	get_compat_flag(sb->s_feature_compat, compat);
+	get_incompat_flag(sb->s_feature_incompat, incompat);
+	get_rocompat_flag(sb->s_feature_ro_compat, 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], sb->s_feature_compat,
+		compat->str);
+	fprintf_aligned_space(stdout, max, items[1]);
+	fprintf(stdout, "%s %u %s\n", items[1], sb->s_feature_incompat,
+		incompat->str);
+	fprintf_aligned_space(stdout, max, items[2]);
+	fprintf(stdout, "%s %u %s\n", items[2], sb->s_feature_ro_compat,
+		rocompat->str);
+	
+	g_string_free(compat, 1);
+	g_string_free(incompat, 1);
+	g_string_free(rocompat, 1);
+	
+	return 0;
+}
+
+DEFINE_O2INFO_OP(fs_features,
+		 fs_features_run,
+		 NULL);
+
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list