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

Tristan tristan.ye at oracle.com
Mon Nov 23 17:31:42 PST 2009


TaoMa wrote:
> Tristan Ye wrote:
>> 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, " ");
>> +}
> I just checked your following patch, it looks that you just want to 
> align all the printed strings.
> So we don't need to do such compliated.
> Just generate the format string like this:
> sprintf(format, "%%%ds\n", max_str_len);
> and then printf(format, str[0]), it should work.

Yes, It can be simplified to be more comfortable to read, my original 
intention is to figure out the space needed for alignment without 
calculating it manually.

Anyway, your way is workable if the item we printed is limited:)

>
>> +
>> +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;
> you need to return t?
>> +errcode_t calc_num_extents(ocfs2_filesys *fs,
>> + struct ocfs2_extent_list *el,
>> + uint32_t *ne)
> I don't get your point here. You want to sum up all the extent recs 
> for the extent list?
> And it looks that you calculate both the leaf extent recs and 
> branches. I have checked
> 6/6, but don't find any callers for it. So could you please explain 
> how it is used.

Yes, it may calculate all extents iteratively, the method here was right 
borrowed from debugfs.ocfs2, you can take a look at patch5/6, it was 
being used there in filestat_run().

>> +{
>> + 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);
> Oh, sorry, it is my fault. actually the extent_iterate only handle the 
> extent_list for the file.
> As for xattr stored outside, you may also need to iterate it.
Yes, I'm also thinking about this, may need to confirm with joel if we 
want ea shared clusters get calculated.

Joel,

Do we really want to calculate the EA part when displaying file 
information, such as in following properties:

Blocks: Clusters: Extents: Shared:

Or provide a option to let user decide if they really want EA get 
involved in such statistics.






>
> Regards,
> Tao




More information about the Ocfs2-tools-devel mailing list