[Ocfs2-tools-devel] [PATCH 4/6] Ocfs2-tools: Add implementation of generic utils function to o2info.

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


Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
 o2info/o2info_utils.c |  347 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 347 insertions(+), 0 deletions(-)
 create mode 100644 o2info/o2info_utils.c

diff --git a/o2info/o2info_utils.c b/o2info/o2info_utils.c
new file mode 100644
index 0000000..68f7137
--- /dev/null
+++ b/o2info/o2info_utils.c
@@ -0,0 +1,347 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * o2info_utils.c
+ *
+ * utility functions for o2info
+ *
+ * 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 as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * 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.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#include "o2info_utils.h"
+
+int max_str_len(const char *strs[], int count)
+{
+	int i, max = 0;
+	
+	for (i = 0; i < count; i++) {
+		if (strlen(strs[i]) >= max)
+			max = strlen(strs[i]);
+	}
+
+	return max;
+}
+
+void fprintf_aligned_space(FILE *out, int max_item_len, const char *item)
+{
+	int i;
+
+	for (i = 0; i < max_item_len - strlen(item); i++)
+		fprintf(out, " ");
+}
+
+void get_incompat_flag(uint32_t flag, GString *str)
+{
+	errcode_t err;
+	char buf[PATH_MAX];
+	ocfs2_fs_options flags = {
+		.opt_incompat = flag,
+	};
+
+	*buf = '\0';
+	err = ocfs2_snprint_feature_flags(buf, PATH_MAX, &flags);
+	if (!err)
+		g_string_append(str, buf);
+	else
+		tcom_err(err, "while processing feature flags");
+}
+
+void get_compat_flag(uint32_t flag, GString *str)
+{
+	errcode_t err;
+	char buf[PATH_MAX];
+	ocfs2_fs_options flags = {
+		.opt_compat = flag,
+	};
+
+	*buf = '\0';
+	err = ocfs2_snprint_feature_flags(buf, PATH_MAX, &flags);
+	if (!err)
+		g_string_append(str, buf);
+	else
+		tcom_err(err, "while processing feature flags");
+}
+
+void get_rocompat_flag(uint32_t flag, GString *str)
+{
+	errcode_t err;
+	char buf[PATH_MAX];
+	ocfs2_fs_options flags = {
+		.opt_ro_compat = flag,
+	};
+
+	*buf = '\0';
+	err = ocfs2_snprint_feature_flags(buf, PATH_MAX, &flags);
+	if (!err)
+		g_string_append(str, buf);
+	else
+		tcom_err(err, "while processing feature flags");
+}
+
+int get_filetype(mode_t st_mode, char **filetype)
+{
+	int rc = 0;
+
+	if (S_ISREG(st_mode))
+		*filetype = strdup("regular file");
+	else if (S_ISDIR(st_mode))
+		*filetype = strdup("directory");
+	else if (S_ISCHR(st_mode))
+		*filetype = strdup("character special file");
+	else if (S_ISBLK(st_mode))
+		*filetype = strdup("block special file");
+	else if (S_ISFIFO(st_mode))
+		*filetype = strdup("FIFO");
+	else if (S_ISLNK(st_mode))
+		*filetype = strdup("symbolic link");
+	else if (S_ISSOCK(st_mode))
+		*filetype = strdup("socket");
+	else
+		rc = -1;
+
+	return rc;
+}
+
+int get_human_permission(mode_t st_mode, uint16_t *perm, char **h_perm)
+{
+	int rc = 0;
+	char tmp[11] = "----------";
+
+	*perm = (uint16_t)(st_mode & 0x00000FFF);
+
+	tmp[10] = '\0';
+	tmp[9] = (*perm & 0x0001) ? 'x' : '-';
+	tmp[8] = (*perm & 0x0002) ? 'w' : '-';
+	tmp[7] = (*perm & 0x0004) ? 'r' : '-';
+	tmp[6] = (*perm & 0x0008) ? 'x' : '-';
+	tmp[5] = (*perm & 0x0010) ? 'w' : '-';
+	tmp[4] = (*perm & 0x0020) ? 'r' : '-';
+	tmp[3] = (*perm & 0x0040) ? 'x' : '-';
+	tmp[2] = (*perm & 0x0080) ? 'w' : '-';
+	tmp[1] = (*perm & 0x0100) ? 'r' : '-';
+
+	/*
+	 * Now we handle the setuid/setgid/sticky bit,
+	 * by following the convention stat did.
+	 */
+	if (*perm & 0x0200) {
+		if (*perm & 0x0001)
+			tmp[9] = 't';
+		else
+			tmp[9] = 'T';
+	}
+
+	if (*perm & 0x0400) {
+		if (*perm & 0x0008)
+			tmp[6] = 's';
+		else
+			tmp[6] = 'S';
+	}
+
+	if (*perm & 0x0800) {
+		if (*perm & 0x0040)
+			tmp[3] = 's';
+		else
+			tmp[3] = 'S';
+	}
+
+	if (S_ISCHR(st_mode))
+		tmp[0] = 'c';
+	else if (S_ISBLK(st_mode))
+		tmp[0] = 'b';
+	else if (S_ISFIFO(st_mode))
+		tmp[0] = 'p';
+	else if (S_ISLNK(st_mode))
+		tmp[0] = 'l';
+	else if (S_ISSOCK(st_mode))
+		tmp[0] = 's';
+	else if (S_ISDIR(st_mode))
+		tmp[0] = 'd';
+
+	*h_perm = strdup(tmp);
+	if (!*h_perm) {
+		errorf("No memory to for allocation\n");
+		goto out;
+	}
+out:
+	return rc;
+}
+
+int uid2name(uid_t uid, char **uname)
+{
+	struct passwd *entry;
+	int ret = 0;
+
+	if (!(entry = getpwuid(uid))) {
+                ret = errno;
+                fprintf(stderr, "user %d does not exist!\n", uid);
+        } else 
+		*uname = strdup(entry->pw_name);
+
+	return ret;
+}
+
+int gid2name(gid_t gid, char **gname)
+{
+	struct group *group;
+	int ret = 0;
+
+	if (!(group = getgrgid(gid))) {
+		ret = errno;
+		fprintf(stderr, "group %d does not exist!\n", gid);
+	} else
+		*gname = strdup(group->gr_name);
+
+	return ret;
+}
+
+struct timespec get_stat_atime(struct stat *st)
+{
+#ifdef __USE_MISC
+	return st->st_atim;
+#else
+	struct timespec t;
+	t.tv_sec = st->st_atime;
+	t.tv_nsec = st->st_atimensec;
+#endif
+}
+
+struct timespec get_stat_mtime(struct stat *st)
+{
+#ifdef __USE_MISC
+	return st->st_mtim;
+#else
+	struct timespec t;
+	t.tv_sec = st->st_mtime;
+	t.tv_nsec = st->st_mtimensec;
+#endif
+}
+
+struct timespec get_stat_ctime(struct stat *st)
+{
+#ifdef __USE_MISC
+	return st->st_ctim;
+#else
+	struct timespec t;
+	t.tv_sec = st->st_ctime;
+	t.tv_nsec = st->st_ctimensec;
+#endif
+}
+
+char *get_human_time(struct timespec t)
+{
+	char *str; 
+	struct tm const *tm = localtime (&t.tv_sec);
+	int size;
+
+	size = strlen("YYYY-MM-DD HH:MM:SS.NNNNNNNNN +ZZZZ") + 1;
+	str = (char *)malloc(size);
+	strftime(str, size, "%Y-%m-%d %H:%M:%S.NNNNNNNNN %z", tm);
+
+	return str;
+}
+
+errcode_t calc_num_extents(ocfs2_filesys *fs,
+				  struct ocfs2_extent_list *el,
+				  uint32_t *ne)
+{
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_rec *rec;
+	errcode_t ret = 0;
+	char *buf = NULL;
+	int i;
+	uint32_t clusters;
+	uint32_t extents = 0;
+
+	*ne = 0;
+
+	for (i = 0; i < el->l_next_free_rec; ++i) {
+		rec = &(el->l_recs[i]);
+		clusters = ocfs2_rec_clusters(el->l_tree_depth, rec);
+
+		/*
+		 * In a unsuccessful insertion, we may shift a tree
+		 * add a new branch for it and do no insertion. So we
+		 * may meet a extent block which have
+		 * clusters == 0, this should only be happen
+		 * in the last extent rec. */
+		if (!clusters && i == el->l_next_free_rec - 1)
+			break;
+
+		extents = 1;
+
+		if (el->l_tree_depth) {
+			ret = ocfs2_malloc_block(fs->fs_io, &buf);
+			if (ret)
+				goto bail;
+
+			ret = ocfs2_read_extent_block(fs, rec->e_blkno, buf);
+			if (ret)
+				goto bail;
+
+			eb = (struct ocfs2_extent_block *)buf;
+
+			ret = calc_num_extents(fs, &(eb->h_list), &extents);
+			if (ret)
+				goto bail;
+
+		}		
+
+		*ne = *ne + extents;
+	}
+
+bail:
+	if (buf)
+		ocfs2_free(&buf);
+	return ret;
+}
+
+static int cal_refcounted_clusters_func(ocfs2_filesys *fs,
+					struct ocfs2_extent_rec *rec,
+					int tree_depth,
+					uint32_t ccount,
+					uint64_t ref_blkno,
+					int ref_recno,
+					void *priv_data)
+{
+
+	if (rec->e_flags & OCFS2_EXT_REFCOUNTED)
+		(*(uint32_t *)priv_data) += rec->e_leaf_clusters;
+
+	return 0;
+}
+
+errcode_t cal_clusters_refcounted(ocfs2_filesys *fs, uint64_t blkno,
+				  int flags, uint32_t *r_clusters)
+{
+
+	errcode_t ret = 0;
+	static uint32_t clusters;
+
+	ret = ocfs2_extent_iterate(fs, blkno, 0, NULL,
+				   cal_refcounted_clusters_func,
+				   (void *)&clusters);
+	if (ret)
+		goto out;
+
+	*r_clusters = clusters;
+
+out:
+	return ret;
+}
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list