[Ocfs2-tools-devel] [PATCH 4/7] Ocfs2-tools: Add implementation of generic utils function to o2info.
Sunil Mushran
sunil.mushran at oracle.com
Mon Nov 30 15:59:20 PST 2009
Remove extra code.
Tristan Ye wrote:
> Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
> ---
> o2info/o2info_utils.c | 425 +++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 425 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..74bfcf5
> --- /dev/null
> +++ b/o2info/o2info_utils.c
> @@ -0,0 +1,425 @@
> +/* -*- mode: c; c-basic-offset: 8; -*-
> + * vim: noexpandtab sw=8 ts=8 sts=0:
> + *
> + * o2info_utils.c
> + *
> + * utility functions for o2info
> + *
> + * 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"
> +
> +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;
> +
> + entry = getpwuid(uid);
> +
> + if (!entry) {
> + 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;
> +
> + group = getgrgid(gid);
> +
> + if (!group) {
> + 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 o2info_open(const char *path, struct o2info_method *om, int flags)
> +{
> + errcode_t err = 0;
> + int fd, open_flags;
> + ocfs2_filesys *fs = NULL;
> +
> + if (om->method & USE_LIBOCFS2) {
> + open_flags = flags|OCFS2_FLAG_HEARTBEAT_DEV_OK|OCFS2_FLAG_RO;
> + err = ocfs2_open(path, open_flags, 0, 0, &fs);
> + if (err) {
> + tcom_err(err, "while opening device %s", path);
> + goto out;
> + } else
> + om->fs = fs;
> + } else {
> + open_flags = flags | O_RDONLY;
> + fd = open(path, open_flags);
> + if (fd < 0) {
> + fd = errno;
> + fprintf(stderr, "open %s failed:%d %s\n", path, fd,
> + strerror(fd));
> + err = fd;
> + goto out;
> + } else
> + om->fd = fd;
> + }
> +
> +out:
> + return err;
> +}
> +
> +errcode_t o2info_close(struct o2info_method *om)
> +{
> + errcode_t err = 0;
> + int rc = 0;
> +
> + if (om->method & USE_LIBOCFS2) {
> + if (om->fs) {
> + err = ocfs2_close(om->fs);
> + if (err) {
> + tcom_err(err, "while closing device");
> + goto out;
> + }
> + }
> + } else {
> + if (om->fd) {
> + rc = close(om->fd);
> + if (rc < 0) {
> + rc = errno;
> + fprintf(stderr, "close fd:%d failed:%d %s\n",
> + om->fd, rc, strerror(rc));
> + err = rc;
> + }
> + }
> + }
> +
> +out:
> + return err;
> +}
> +
> +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;
> +}
> +
> +int is_device(const char *path)
> +{
> + int rc;
> + struct stat st;
> +
> + rc = lstat(path, &st);
> + if (rc < 0) {
> + rc = errno;
> + fprintf(stderr, "stat error %d: \"%s\"\n", rc, strerror(rc));
> + rc = -1;
> + goto out;
> + }
> +
> + if ((S_ISBLK(st.st_mode)) || (S_ISCHR(st.st_mode)))
> + rc = 1;
> + else
> + rc = 0;
> +
> +out:
> + return rc;
> +}
>
More information about the Ocfs2-tools-devel
mailing list