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

Tristan tristan.ye at oracle.com
Mon Nov 30 18:58:01 PST 2009


Tao Ma wrote:
> Hi Tristan,
>     We normally separate a large patch into many small parts according 
> to the functionality, not file. That is to say we don't generate a 
> patch for a file. So patch 1 may touch o2info_utils.c while patch 2 
> still touch it. If the codes work for different issues, we'd better 
> integrate them into different patches.

Yes, what you're saying really makes sense:-)

The reason why I here posted patches in terms of  separated files is, 
each file could be somewhat functionality-independent(that's why I use 
these separated files), such as, main.c was used to construct the main 
framework of the process, o2info_utils.c consists of all utility funcs,  
in such a way, it may become more convenient I guess for reviewer to 
walk through the code, especially at the very beginning of tool's 
implementation.


Tristan.

>
> Regards,
> Tao
>
> Sunil Mushran wrote:
>> 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;
>>> +}
>>>   
>>
>>
>> _______________________________________________
>> Ocfs2-tools-devel mailing list
>> Ocfs2-tools-devel at oss.oracle.com
>> http://oss.oracle.com/mailman/listinfo/ocfs2-tools-devel




More information about the Ocfs2-tools-devel mailing list