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

Tao Ma tao.ma at oracle.com
Mon Nov 30 18:04:45 PST 2009


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.

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