[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