[Ocfs2-tools-devel] [PATCH 15/19] Ocfs2-tools: Add running codes for '--freeinode' in operation.c
Tristan Ye
tristan.ye at oracle.com
Tue Apr 13 19:50:15 PDT 2010
Task of '--freeinode' is expected to get free inodes info from
all node's inode allocator, it will also be capable of two
approaches, including libocfs2 and ioctl solutions.
Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
o2info/operations.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 133 insertions(+), 0 deletions(-)
diff --git a/o2info/operations.c b/o2info/operations.c
index 25b877f..10ba824 100644
--- a/o2info/operations.c
+++ b/o2info/operations.c
@@ -1093,3 +1093,136 @@ static int freefrag_run(struct o2info_operation *op,
DEFINE_O2INFO_OP(freefrag,
freefrag_run,
NULL);
+
+struct o2info_local_freeinode {
+ unsigned long total;
+ unsigned long free;
+};
+
+struct o2info_freeinode_info {
+ int slotnum;
+ struct o2info_local_freeinode fi[OCFS2_MAX_SLOTS];
+};
+
+static int get_freeinode_libocfs2(struct o2info_operation *op,
+ ocfs2_filesys *fs,
+ struct o2info_freeinode_info *info)
+{
+ int ret = 0, i, j;
+ char *block = NULL;
+ uint64_t inode_alloc;
+
+ struct ocfs2_dinode *dinode_alloc = NULL;
+ struct ocfs2_chain_list *cl = NULL;
+ struct ocfs2_chain_rec *rec = NULL;
+ struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);
+
+ info->slotnum = sb->s_max_slots;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &block);
+ if (ret) {
+ tcom_err(ret, "while allocating block buffer");
+ goto out;
+ }
+
+ dinode_alloc = (struct ocfs2_dinode *)block;
+
+ for (i = 0; i < info->slotnum; i++) {
+
+ info->fi[i].total = info->fi[i].free = 0;
+
+ ret = ocfs2_lookup_system_inode(fs, INODE_ALLOC_SYSTEM_INODE,
+ i, &inode_alloc);
+ if (ret) {
+ tcom_err(ret, "while looking up the global"
+ " bitmap inode");
+ goto out;
+ }
+
+ ret = ocfs2_read_inode(fs, inode_alloc, (char *)dinode_alloc);
+ if (ret) {
+ tcom_err(ret, "reading global_bitmap inode "
+ "%"PRIu64" for stats", inode_alloc);
+ goto out;
+ }
+
+ cl = &(dinode_alloc->id2.i_chain);
+
+ for (j = 0; j < cl->cl_next_free_rec; j++) {
+ rec = &(cl->cl_recs[j]);
+ info->fi[i].total += rec->c_total;
+ info->fi[i].free += rec->c_free;
+ }
+ }
+out:
+ if (block)
+ ocfs2_free(&block);
+
+ return ret;
+}
+
+static int get_freeinode_ioctl(struct o2info_operation *op,
+ int fd,
+ struct o2info_freeinode_info *info)
+{
+ int ret = 0;
+ struct ocfs2_info_freeinode firq;
+
+ o2info_fill_request(&firq, OCFS2_INFO_FREEINODE, no_coherency);
+
+ uint64_t reqs[1] = {(unsigned long)&firq};
+
+ struct ocfs2_info o_info = {
+ .info_requests = (uint64_t)reqs,
+ .info_count = 1,
+ };
+
+ ret = ioctl(fd, OCFS2_IOC_INFO, &o_info);
+ if (ret) {
+ ret = errno;
+ o2i_error(op, "ioctl failed: %s\n", strerror(ret));
+ ret = -1;
+ }
+
+ if (firq.ir_request.ir_flags & OCFS2_INFO_FL_FILLED) {
+ info->slotnum = firq.ir_slotnum;
+ memcpy(info->fi, firq.ir_fi_stat,
+ sizeof(struct o2info_local_freeinode) * OCFS2_MAX_SLOTS);
+ }
+
+ return ret;
+}
+
+static int freeinode_run(struct o2info_operation *op,
+ struct o2info_method *om,
+ void *arg)
+{
+ int ret = 0, i;
+
+ struct o2info_freeinode_info info;
+ unsigned long total = 0, free = 0;
+
+ if (om->om_method == O2INFO_USE_IOCTL)
+ ret = get_freeinode_ioctl(op, om->om_fd, &info);
+ else
+ ret = get_freeinode_libocfs2(op, om->om_fs, &info);
+
+ if (ret)
+ return ret;
+
+ fprintf(stdout, "Slot\t\tSpace\t\tFree\n");
+ for (i = 0; i < info.slotnum ; i++) {
+ fprintf(stdout, "%3d\t%13lu\t%12lu\n", i, info.fi[i].total,
+ info.fi[i].free);
+ total += info.fi[i].total;
+ free += info.fi[i].free;
+ }
+
+ fprintf(stdout, "Total\t%13lu\t%12lu\n", total, free);
+
+ return ret;
+}
+
+DEFINE_O2INFO_OP(freeinode,
+ freeinode_run,
+ NULL);
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list