[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