ocfs2-devel.oss.oracle.com archive mirror
 help / color / mirror / Atom feed
* [Ocfs2-devel] [PATCH 0/3] Ocfs2: Adding new codes 'OCFS2_INFO_FREEINODE' and 'OCFS2_INFO_FREEFRAG' for o2info ioctl V2.
@ 2010-11-16 10:13 Tristan Ye
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler Tristan Ye
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Tristan Ye @ 2010-11-16 10:13 UTC (permalink / raw)
  To: ocfs2-devel

This set of patch series includes three patches:

1. Using marco to simplize duplicated codes.

2. Adding new code 'OCFS2_INODE_FREEINODE'

3. Adding new code 'OCFS2_INFO_FREEFRAG'

Changes since v1:

1. Incorporate Joel's comments to take cluster coherency into account when
   lookuping the inode/inode_blkno.

2. Using helpers somewhere to improve the readability of codes.



Tristan.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2010-11-16 10:13 [Ocfs2-devel] [PATCH 0/3] Ocfs2: Adding new codes 'OCFS2_INFO_FREEINODE' and 'OCFS2_INFO_FREEFRAG' for o2info ioctl V2 Tristan Ye
@ 2010-11-16 10:13 ` Tristan Ye
  2010-12-07  1:04   ` Joel Becker
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 2/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEINODE' for o2info ioctl Tristan Ye
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 3/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEFRAG' " Tristan Ye
  2 siblings, 1 reply; 19+ messages in thread
From: Tristan Ye @ 2010-11-16 10:13 UTC (permalink / raw)
  To: ocfs2-devel

It's a best-effort attempt to simplize duplicated codes here.

Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
---
 fs/ocfs2/ioctl.c |   38 ++++++++++++++++++++++++++++++--------
 1 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
index 7a48681..731cf46 100644
--- a/fs/ocfs2/ioctl.c
+++ b/fs/ocfs2/ioctl.c
@@ -46,6 +46,22 @@ static inline void __o2info_set_request_error(struct ocfs2_info_request *kreq,
 #define o2info_set_request_error(a, b) \
 		__o2info_set_request_error((struct ocfs2_info_request *)&(a), b)
 
+static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
+{
+	req->ir_flags |= OCFS2_INFO_FL_FILLED;
+}
+
+#define o2info_set_request_filled(a) \
+		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
+
+static inline void __o2info_clear_request_filled(struct ocfs2_info_request *req)
+{
+	req->ir_flags &= ~OCFS2_INFO_FL_FILLED;
+}
+
+#define o2info_clear_request_filled(a) \
+		__o2info_clear_request_filled((struct ocfs2_info_request *)&(a))
+
 static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
 {
 	int status;
@@ -139,7 +155,8 @@ int ocfs2_info_handle_blocksize(struct inode *inode,
 		goto bail;
 
 	oib.ib_blocksize = inode->i_sb->s_blocksize;
-	oib.ib_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oib);
 
 	if (o2info_to_user(oib, req))
 		goto bail;
@@ -163,7 +180,8 @@ int ocfs2_info_handle_clustersize(struct inode *inode,
 		goto bail;
 
 	oic.ic_clustersize = osb->s_clustersize;
-	oic.ic_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oic);
 
 	if (o2info_to_user(oic, req))
 		goto bail;
@@ -187,7 +205,8 @@ int ocfs2_info_handle_maxslots(struct inode *inode,
 		goto bail;
 
 	oim.im_max_slots = osb->max_slots;
-	oim.im_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oim);
 
 	if (o2info_to_user(oim, req))
 		goto bail;
@@ -211,7 +230,8 @@ int ocfs2_info_handle_label(struct inode *inode,
 		goto bail;
 
 	memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
-	oil.il_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oil);
 
 	if (o2info_to_user(oil, req))
 		goto bail;
@@ -235,7 +255,8 @@ int ocfs2_info_handle_uuid(struct inode *inode,
 		goto bail;
 
 	memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1);
-	oiu.iu_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oiu);
 
 	if (o2info_to_user(oiu, req))
 		goto bail;
@@ -261,7 +282,8 @@ int ocfs2_info_handle_fs_features(struct inode *inode,
 	oif.if_compat_features = osb->s_feature_compat;
 	oif.if_incompat_features = osb->s_feature_incompat;
 	oif.if_ro_compat_features = osb->s_feature_ro_compat;
-	oif.if_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oif);
 
 	if (o2info_to_user(oif, req))
 		goto bail;
@@ -286,7 +308,7 @@ int ocfs2_info_handle_journal_size(struct inode *inode,
 
 	oij.ij_journal_size = osb->journal->j_inode->i_size;
 
-	oij.ij_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+	o2info_set_request_filled(oij);
 
 	if (o2info_to_user(oij, req))
 		goto bail;
@@ -308,7 +330,7 @@ int ocfs2_info_handle_unknown(struct inode *inode,
 	if (o2info_from_user(oir, req))
 		goto bail;
 
-	oir.ir_flags &= ~OCFS2_INFO_FL_FILLED;
+	o2info_clear_request_filled(oir);
 
 	if (o2info_to_user(oir, req))
 		goto bail;
-- 
1.5.5

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 2/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEINODE' for o2info ioctl.
  2010-11-16 10:13 [Ocfs2-devel] [PATCH 0/3] Ocfs2: Adding new codes 'OCFS2_INFO_FREEINODE' and 'OCFS2_INFO_FREEFRAG' for o2info ioctl V2 Tristan Ye
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler Tristan Ye
@ 2010-11-16 10:13 ` Tristan Ye
  2010-12-07  1:07   ` Joel Becker
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 3/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEFRAG' " Tristan Ye
  2 siblings, 1 reply; 19+ messages in thread
From: Tristan Ye @ 2010-11-16 10:13 UTC (permalink / raw)
  To: ocfs2-devel

The new code is dedicated to calculate free inodes number of all inode_allocs,
then return the info to userpace in terms of an array.

Specially, flag 'OCFS2_INFO_FL_NON_COHERENT', manipulated by '--cluster-coherent'
from userspace, is now going to be involved. setting the flag on means no cluster
coherency considered, usually, userspace tools choose none-coherency strategy by
default for the sake of performace.

Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
---
 fs/ocfs2/ioctl.c       |  122 ++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/ocfs2_ioctl.h |   11 ++++
 2 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
index 731cf46..18812be 100644
--- a/fs/ocfs2/ioctl.c
+++ b/fs/ocfs2/ioctl.c
@@ -23,6 +23,9 @@
 #include "ioctl.h"
 #include "resize.h"
 #include "refcounttree.h"
+#include "sysfile.h"
+#include "dir.h"
+#include "buffer_head_io.h"
 
 #include <linux/ext2_fs.h>
 
@@ -62,6 +65,13 @@ static inline void __o2info_clear_request_filled(struct ocfs2_info_request *req)
 #define o2info_clear_request_filled(a) \
 		__o2info_clear_request_filled((struct ocfs2_info_request *)&(a))
 
+static inline int __o2info_coherent(struct ocfs2_info_request *req)
+{
+	return (!(req->ir_flags & OCFS2_INFO_FL_NON_COHERENT));
+}
+
+#define o2info_coherent(a) __o2info_coherent((struct ocfs2_info_request *)&(a))
+
 static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
 {
 	int status;
@@ -321,6 +331,114 @@ bail:
 	return status;
 }
 
+int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb,
+				struct inode *inode_alloc, u64 blkno,
+				struct ocfs2_info_freeinode *fi, u32 slot)
+{
+	int status = 0, unlock = 0;
+
+	struct buffer_head *bh = NULL;
+	struct ocfs2_dinode *dinode_alloc = NULL;
+
+	if (inode_alloc)
+		mutex_lock(&inode_alloc->i_mutex);
+
+	if (o2info_coherent(*fi)) {
+		status = ocfs2_inode_lock(inode_alloc, &bh, 0);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		unlock = 1;
+	} else {
+		status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	dinode_alloc = (struct ocfs2_dinode *)bh->b_data;
+
+	fi->ifi_stat[slot].lfi_total =
+		le32_to_cpu(dinode_alloc->id1.bitmap1.i_total);
+	fi->ifi_stat[slot].lfi_free =
+		le32_to_cpu(dinode_alloc->id1.bitmap1.i_total) -
+		le32_to_cpu(dinode_alloc->id1.bitmap1.i_used);
+
+bail:
+	if (unlock)
+		ocfs2_inode_unlock(inode_alloc, 0);
+
+	if (inode_alloc)
+		mutex_unlock(&inode_alloc->i_mutex);
+
+	if (inode_alloc)
+		iput(inode_alloc);
+
+	brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_info_handle_freeinode(struct inode *inode,
+				struct ocfs2_info_request __user *req)
+{
+	u32 i;
+	u64 blkno = -1;
+	char namebuf[40];
+	int status = -EFAULT, type = INODE_ALLOC_SYSTEM_INODE;
+	struct ocfs2_info_freeinode oifi;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct inode *inode_alloc = NULL;
+
+	if (o2info_from_user(oifi, req))
+		goto bail;
+
+	oifi.ifi_slotnum = osb->max_slots;
+
+	for (i = 0; i < oifi.ifi_slotnum; i++) {
+		if (o2info_coherent(oifi)) {
+			inode_alloc = ocfs2_get_system_file_inode(osb, type, i);
+			if (!inode_alloc) {
+				mlog(ML_ERROR, "unable to get alloc inode in "
+				    "slot %u\n", i);
+				status = -EIO;
+				goto bail;
+			}
+		} else {
+			ocfs2_sprintf_system_inode_name(namebuf,
+							sizeof(namebuf),
+							type, i);
+			status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
+							    namebuf,
+							    strlen(namebuf),
+							    &blkno);
+			if (status < 0) {
+				status = -ENOENT;
+				goto bail;
+			}
+		}
+
+		status = ocfs2_info_scan_inode_alloc(osb, inode_alloc, blkno, &oifi, i);
+		if (status < 0)
+			goto bail;
+	}
+
+	o2info_set_request_filled(oifi);
+
+	if (o2info_to_user(oifi, req))
+		goto bail;
+
+	status = 0;
+bail:
+	if (status)
+		o2info_set_request_error(oifi, req);
+
+	return status;
+}
+
 int ocfs2_info_handle_unknown(struct inode *inode,
 			      struct ocfs2_info_request __user *req)
 {
@@ -392,6 +510,10 @@ int ocfs2_info_handle_request(struct inode *inode,
 		if (oir.ir_size == sizeof(struct ocfs2_info_journal_size))
 			status = ocfs2_info_handle_journal_size(inode, req);
 		break;
+	case OCFS2_INFO_FREEINODE:
+		if (oir.ir_size == sizeof(struct ocfs2_info_freeinode))
+			status = ocfs2_info_handle_freeinode(inode, req);
+		break;
 	default:
 		status = ocfs2_info_handle_unknown(inode, req);
 		break;
diff --git a/fs/ocfs2/ocfs2_ioctl.h b/fs/ocfs2/ocfs2_ioctl.h
index b46f39b..6b4b39a 100644
--- a/fs/ocfs2/ocfs2_ioctl.h
+++ b/fs/ocfs2/ocfs2_ioctl.h
@@ -142,6 +142,16 @@ struct ocfs2_info_journal_size {
 	__u64 ij_journal_size;
 };
 
+struct ocfs2_info_freeinode {
+	struct ocfs2_info_request ifi_req;
+	struct ocfs2_info_local_freeinode {
+		__u64 lfi_total;
+		__u64 lfi_free;
+	} ifi_stat[OCFS2_MAX_SLOTS];
+	__u32 ifi_slotnum; /* out */
+	__u32 ifi_pad;
+};
+
 /* Codes for ocfs2_info_request */
 enum ocfs2_info_type {
 	OCFS2_INFO_CLUSTERSIZE = 1,
@@ -151,6 +161,7 @@ enum ocfs2_info_type {
 	OCFS2_INFO_UUID,
 	OCFS2_INFO_FS_FEATURES,
 	OCFS2_INFO_JOURNAL_SIZE,
+	OCFS2_INFO_FREEINODE,
 	OCFS2_INFO_NUM_TYPES
 };
 
-- 
1.5.5

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 3/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEFRAG' for o2info ioctl.
  2010-11-16 10:13 [Ocfs2-devel] [PATCH 0/3] Ocfs2: Adding new codes 'OCFS2_INFO_FREEINODE' and 'OCFS2_INFO_FREEFRAG' for o2info ioctl V2 Tristan Ye
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler Tristan Ye
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 2/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEINODE' for o2info ioctl Tristan Ye
@ 2010-11-16 10:13 ` Tristan Ye
  2010-12-07  1:11   ` Joel Becker
  2 siblings, 1 reply; 19+ messages in thread
From: Tristan Ye @ 2010-11-16 10:13 UTC (permalink / raw)
  To: ocfs2-devel

This new code is a bit more complicated than former ones, the goal is to
show user all statistics required to take a deep insight into filesystem
on how the disk is being fragmentaed.

The goal is achieved by scaning global bitmap from (cluster)group to group
to figure out following factors in the filesystem:

        - How many free chunks in a fixed size as user requested.
        - How many real free chunks in all size.
        - Min/Max/Avg size(in) clusters of free chunks.
        - How do free chunks distribute(in size) in terms of a histogram,
          just like following:
          ---------------------------------------------------------
          Extent Size Range :  Free extents  Free Clusters  Percent
             32K...   64K-  :             1             1    0.00%
              1M...    2M-  :             9           288    0.03%
              8M...   16M-  :             2           831    0.09%
             32M...   64M-  :             1          2047    0.23%
            128M...  256M-  :             1          8191    0.92%
            256M...  512M-  :             2         21706    2.43%
            512M... 1024M-  :            27        858623   96.29%
          ---------------------------------------------------------

Userspace ioctl() call eventually gets the above info returned by passing
a 'struct ocfs2_info_freefrag' with the chunk_size being specified first.

Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
---
 fs/ocfs2/ioctl.c       |  283 ++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ocfs2/ocfs2_ioctl.h |   23 ++++
 2 files changed, 306 insertions(+), 0 deletions(-)

diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
index 18812be..c796860 100644
--- a/fs/ocfs2/ioctl.c
+++ b/fs/ocfs2/ioctl.c
@@ -26,6 +26,7 @@
 #include "sysfile.h"
 #include "dir.h"
 #include "buffer_head_io.h"
+#include "suballoc.h"
 
 #include <linux/ext2_fs.h>
 
@@ -439,6 +440,284 @@ bail:
 	return status;
 }
 
+static void o2ffg_update_histogram(struct ocfs2_info_free_chunk_list *hist,
+				   unsigned int chunksize)
+{
+	int index;
+
+	index = __ilog2_u32(chunksize);
+	if (index >= OCFS2_INFO_MAX_HIST)
+		index = OCFS2_INFO_MAX_HIST - 1;
+
+	hist->fc_chunks[index]++;
+	hist->fc_clusters[index] += chunksize;
+}
+
+static void o2ffg_update_stats(struct ocfs2_info_freefrag_stats *stats,
+			       unsigned int chunksize)
+{
+	if (chunksize > stats->ffs_max)
+		stats->ffs_max = chunksize;
+
+	if (chunksize < stats->ffs_min)
+		stats->ffs_min = chunksize;
+
+	stats->ffs_avg += chunksize;
+	stats->ffs_free_chunks_real++;
+}
+
+void ocfs2_info_update_ffg(struct ocfs2_info_freefrag *ffg,
+			   unsigned int chunksize)
+{
+	o2ffg_update_histogram(&(ffg->iff_ffs.ffs_fc_hist), chunksize);
+	o2ffg_update_stats(&(ffg->iff_ffs), chunksize);
+}
+
+int ocfs2_info_freefrag_scan_chain(struct ocfs2_super *osb,
+				   struct inode *gb_inode,
+				   struct ocfs2_dinode *gb_dinode,
+				   struct ocfs2_chain_rec *rec,
+				   struct ocfs2_info_freefrag *ffg,
+				   u32 chunks_in_group)
+{
+	int status = 0, used;
+	u64 blkno;
+
+	struct buffer_head *bh = NULL;
+	struct ocfs2_group_desc *bg = NULL;
+
+	unsigned int max_bits, num_clusters;
+	unsigned int offset = 0, cluster, chunk;
+	unsigned int chunk_free, last_chunksize = 0;
+
+	if (!le32_to_cpu(rec->c_free))
+		goto bail;
+
+	do {
+		if (!bg)
+			blkno = le64_to_cpu(rec->c_blkno);
+		else
+			blkno = le64_to_cpu(bg->bg_next_group);
+
+		if (bh) {
+			brelse(bh);
+			bh = NULL;
+		}
+
+		if (o2info_coherent(*ffg))
+			status = ocfs2_read_group_descriptor(gb_inode,
+							     gb_dinode,
+							     blkno, &bh);
+		else
+			status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
+
+		if (status < 0) {
+			mlog(ML_ERROR, "Can't read the group descriptor # "
+			     "%llu from device.", (unsigned long long)blkno);
+			status = -EIO;
+			goto bail;
+		}
+
+		bg = (struct ocfs2_group_desc *)bh->b_data;
+
+		if (!le16_to_cpu(bg->bg_free_bits_count))
+			continue;
+
+		max_bits = le16_to_cpu(bg->bg_bits);
+		offset = 0;
+
+		for (chunk = 0; chunk < chunks_in_group; chunk++) {
+			/*
+			 * last chunk may be not an entire one.
+			 */
+			if ((offset + ffg->iff_chunksize) > max_bits)
+				num_clusters = max_bits - offset;
+			else
+				num_clusters = ffg->iff_chunksize;
+
+			chunk_free = 0;
+			for (cluster = 0; cluster < num_clusters; cluster++) {
+				used = ocfs2_test_bit(offset,
+						(unsigned long *)bg->bg_bitmap);
+				/*
+				 * - chunk_free counts free clusters in #N chunk.
+				 * - last_chunksize records the size(in) clusters
+				 *   for the last real free chunk being counted.
+				 */
+				if (!used) {
+					last_chunksize++;
+					chunk_free++;
+				}
+
+				if (used && last_chunksize) {
+					ocfs2_info_update_ffg(ffg,
+							      last_chunksize);
+					last_chunksize = 0;
+				}
+
+				offset++;
+			}
+
+			if (chunk_free == ffg->iff_chunksize)
+				ffg->iff_ffs.ffs_free_chunks++;
+		}
+
+		/*
+		 * need to update the info for last free chunk.
+		 */
+		if (last_chunksize)
+			ocfs2_info_update_ffg(ffg, last_chunksize);
+
+	} while (le64_to_cpu(bg->bg_next_group));
+
+bail:
+	brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_info_freefrag_scan_bitmap(struct ocfs2_super *osb,
+				    struct inode *gb_inode, u64 blkno,
+				    struct ocfs2_info_freefrag *ffg)
+{
+	u32 chunks_in_group;
+	int status = 0, unlock = 0, i;
+
+	struct buffer_head *bh = NULL;
+	struct ocfs2_chain_list *cl = NULL;
+	struct ocfs2_chain_rec *rec = NULL;
+	struct ocfs2_dinode *gb_dinode = NULL;
+
+	if (gb_inode)
+		mutex_lock(&gb_inode->i_mutex);
+
+	if (o2info_coherent(*ffg)) {
+		status = ocfs2_inode_lock(gb_inode, &bh, 0);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		unlock = 1;
+	} else {
+		status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	gb_dinode = (struct ocfs2_dinode *)bh->b_data;
+	cl = &(gb_dinode->id2.i_chain);
+
+	/* 
+	 * Chunksize(in) clusters from userspace should be
+	 * less than clusters in a group.
+	 */
+	if (ffg->iff_chunksize > le16_to_cpu(cl->cl_cpg)) {
+		status = -EINVAL;
+		goto bail;
+	}
+
+	memset(&ffg->iff_ffs, 0, sizeof(struct ocfs2_info_freefrag_stats));
+
+	ffg->iff_ffs.ffs_min = ~0U;
+	ffg->iff_ffs.ffs_clusters =
+			le32_to_cpu(gb_dinode->id1.bitmap1.i_total);
+	ffg->iff_ffs.ffs_free_clusters = ffg->iff_ffs.ffs_clusters -
+			le32_to_cpu(gb_dinode->id1.bitmap1.i_used);
+
+	chunks_in_group = le16_to_cpu(cl->cl_cpg) / ffg->iff_chunksize + 1;
+
+	for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i++) {
+		rec = &(cl->cl_recs[i]);
+		status = ocfs2_info_freefrag_scan_chain(osb, gb_inode,
+							gb_dinode,
+							rec, ffg,
+							chunks_in_group);
+		if (status)
+			goto bail;
+	}
+
+	if (ffg->iff_ffs.ffs_free_chunks_real)
+		ffg->iff_ffs.ffs_avg = (ffg->iff_ffs.ffs_avg /
+					ffg->iff_ffs.ffs_free_chunks_real);
+bail:
+	if (unlock)
+		ocfs2_inode_unlock(gb_inode, 0);
+
+	if (gb_inode)
+		mutex_unlock(&gb_inode->i_mutex);
+
+	if (gb_inode)
+		iput(gb_inode);
+
+	brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_info_handle_freefrag(struct inode *inode,
+			       struct ocfs2_info_request __user *req)
+{
+	u64 blkno = -1;
+	char namebuf[40];
+	int status = -EFAULT, type = GLOBAL_BITMAP_SYSTEM_INODE;
+
+	struct ocfs2_info_freefrag oiff;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct inode *gb_inode = NULL;
+
+	if (o2info_from_user(oiff, req))
+		goto bail;
+	/*
+	 * chunksize from userspace should be power of 2.
+	 */
+	if ((oiff.iff_chunksize & (oiff.iff_chunksize - 1)) ||
+	    (!oiff.iff_chunksize)) {
+		status = -EINVAL;
+		goto bail;
+	}
+
+	if (o2info_coherent(oiff)) {
+		gb_inode = ocfs2_get_system_file_inode(osb, type,
+						       OCFS2_INVALID_SLOT);
+		if (!gb_inode) {
+			mlog(ML_ERROR, "unable to get global_bitmap inode\n");
+			status = -EIO;
+			goto bail;
+		}
+	} else {
+		ocfs2_sprintf_system_inode_name(namebuf, sizeof(namebuf), type,
+						OCFS2_INVALID_SLOT);
+		status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
+						    namebuf,
+						    strlen(namebuf),
+						    &blkno);
+		if (status < 0) {
+			status = -ENOENT;
+			goto bail;
+		}
+	}
+
+	status = ocfs2_info_freefrag_scan_bitmap(osb, gb_inode, blkno, &oiff);
+	if (status < 0)
+		goto bail;
+
+	o2info_set_request_filled(oiff);
+
+	if (o2info_to_user(oiff, req))
+		goto bail;
+
+	status = 0;
+bail:
+	if (status)
+		o2info_set_request_error(oiff, req);
+
+	return status;
+}
+
 int ocfs2_info_handle_unknown(struct inode *inode,
 			      struct ocfs2_info_request __user *req)
 {
@@ -514,6 +793,10 @@ int ocfs2_info_handle_request(struct inode *inode,
 		if (oir.ir_size == sizeof(struct ocfs2_info_freeinode))
 			status = ocfs2_info_handle_freeinode(inode, req);
 		break;
+	case OCFS2_INFO_FREEFRAG:
+		if (oir.ir_size == sizeof(struct ocfs2_info_freefrag))
+			status = ocfs2_info_handle_freefrag(inode, req);
+		break;
 	default:
 		status = ocfs2_info_handle_unknown(inode, req);
 		break;
diff --git a/fs/ocfs2/ocfs2_ioctl.h b/fs/ocfs2/ocfs2_ioctl.h
index 6b4b39a..18b6770 100644
--- a/fs/ocfs2/ocfs2_ioctl.h
+++ b/fs/ocfs2/ocfs2_ioctl.h
@@ -152,6 +152,28 @@ struct ocfs2_info_freeinode {
 	__u32 ifi_pad;
 };
 
+#define OCFS2_INFO_MAX_HIST     (32)
+
+struct ocfs2_info_freefrag {
+	struct ocfs2_info_request iff_req;
+	struct ocfs2_info_freefrag_stats { /* (out) */
+		struct ocfs2_info_free_chunk_list {
+			__u32 fc_chunks[OCFS2_INFO_MAX_HIST];
+			__u32 fc_clusters[OCFS2_INFO_MAX_HIST];
+		} ffs_fc_hist;
+		__u32 ffs_clusters;
+		__u32 ffs_free_clusters;
+		__u32 ffs_free_chunks;
+		__u32 ffs_free_chunks_real;
+		__u32 ffs_min; /* Minimum free chunksize in clusters */
+		__u32 ffs_max;
+		__u32 ffs_avg;
+		__u32 ffs_pad;
+	} iff_ffs;
+	__u32 iff_chunksize; /* chunksize in clusters(in) */
+	__u32 iff_pad;
+};
+
 /* Codes for ocfs2_info_request */
 enum ocfs2_info_type {
 	OCFS2_INFO_CLUSTERSIZE = 1,
@@ -162,6 +184,7 @@ enum ocfs2_info_type {
 	OCFS2_INFO_FS_FEATURES,
 	OCFS2_INFO_JOURNAL_SIZE,
 	OCFS2_INFO_FREEINODE,
+	OCFS2_INFO_FREEFRAG,
 	OCFS2_INFO_NUM_TYPES
 };
 
-- 
1.5.5

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler Tristan Ye
@ 2010-12-07  1:04   ` Joel Becker
  0 siblings, 0 replies; 19+ messages in thread
From: Joel Becker @ 2010-12-07  1:04 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Nov 16, 2010 at 06:13:40PM +0800, Tristan Ye wrote:
> @@ -139,7 +155,8 @@ int ocfs2_info_handle_blocksize(struct inode *inode,
>  		goto bail;
>  
>  	oib.ib_blocksize = inode->i_sb->s_blocksize;
> -	oib.ib_req.ir_flags |= OCFS2_INFO_FL_FILLED;
> +
> +	o2info_set_request_filled(oib);

	There's no need to add the extra line of whitespace for all of
these.  They're quite readable.

Joel

-- 

To spot the expert, pick the one who predicts the job will take the
longest and cost the most.

Joel Becker
Senior Development Manager
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 2/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEINODE' for o2info ioctl.
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 2/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEINODE' for o2info ioctl Tristan Ye
@ 2010-12-07  1:07   ` Joel Becker
  2010-12-07  1:46     ` Tristan Ye
  0 siblings, 1 reply; 19+ messages in thread
From: Joel Becker @ 2010-12-07  1:07 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Nov 16, 2010 at 06:13:41PM +0800, Tristan Ye wrote:
> +	if (inode_alloc)
> +		iput(inode_alloc);

	Do the iput up in the calling function where it matches the
get_system_file_inode() call.  This just makes it easier to spot the
get/put pair.

Joel

-- 

"Under capitalism, man exploits man.  Under Communism, it's just 
   the opposite."
				 - John Kenneth Galbraith

Joel Becker
Senior Development Manager
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 3/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEFRAG' for o2info ioctl.
  2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 3/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEFRAG' " Tristan Ye
@ 2010-12-07  1:11   ` Joel Becker
  2010-12-07  1:45     ` Tristan Ye
  0 siblings, 1 reply; 19+ messages in thread
From: Joel Becker @ 2010-12-07  1:11 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Nov 16, 2010 at 06:13:42PM +0800, Tristan Ye wrote:
> +static void o2ffg_update_histogram(struct ocfs2_info_free_chunk_list *hist,
> +				   unsigned int chunksize)
> +{
> +	int index;
> +
> +	index = __ilog2_u32(chunksize);
> +	if (index >= OCFS2_INFO_MAX_HIST)
> +		index = OCFS2_INFO_MAX_HIST - 1;
> +
> +	hist->fc_chunks[index]++;
> +	hist->fc_clusters[index] += chunksize;
> +}
> +
> +static void o2ffg_update_stats(struct ocfs2_info_freefrag_stats *stats,
> +			       unsigned int chunksize)
> +{
> +	if (chunksize > stats->ffs_max)
> +		stats->ffs_max = chunksize;
> +
> +	if (chunksize < stats->ffs_min)
> +		stats->ffs_min = chunksize;
> +
> +	stats->ffs_avg += chunksize;
> +	stats->ffs_free_chunks_real++;
> +}

	MUCH more readable.

> +int ocfs2_info_freefrag_scan_bitmap(struct ocfs2_super *osb,
> +				    struct inode *gb_inode, u64 blkno,
> +				    struct ocfs2_info_freefrag *ffg)
> +{
> +	u32 chunks_in_group;
> +	int status = 0, unlock = 0, i;
> +
> +	struct buffer_head *bh = NULL;
> +	struct ocfs2_chain_list *cl = NULL;
> +	struct ocfs2_chain_rec *rec = NULL;
> +	struct ocfs2_dinode *gb_dinode = NULL;
> +
> +	if (gb_inode)
> +		mutex_lock(&gb_inode->i_mutex);
> +
> +	if (o2info_coherent(*ffg)) {
> +		status = ocfs2_inode_lock(gb_inode, &bh, 0);
> +		if (status < 0) {
> +			mlog_errno(status);
> +			goto bail;
> +		}
> +		unlock = 1;
> +	} else {
> +		status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
> +		if (status < 0) {
> +			mlog_errno(status);
> +			goto bail;
> +		}
> +	}
> +
> +	gb_dinode = (struct ocfs2_dinode *)bh->b_data;
> +	cl = &(gb_dinode->id2.i_chain);

	This is safe because we never remove a chain entry from an
inode.  However, if we ever shrink disks, we'll need to coordinate with
this code.  Perhaps we should comment that.

Joel

-- 

"Also, all of life's big problems include the words 'indictment' or
	'inoperable.' Everything else is small stuff."
	- Alton Brown

Joel Becker
Senior Development Manager
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 3/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEFRAG' for o2info ioctl.
  2010-12-07  1:11   ` Joel Becker
@ 2010-12-07  1:45     ` Tristan Ye
  2010-12-07  3:36       ` Joel Becker
  0 siblings, 1 reply; 19+ messages in thread
From: Tristan Ye @ 2010-12-07  1:45 UTC (permalink / raw)
  To: ocfs2-devel

Joel Becker wrote:
> On Tue, Nov 16, 2010 at 06:13:42PM +0800, Tristan Ye wrote:
>> +static void o2ffg_update_histogram(struct ocfs2_info_free_chunk_list *hist,
>> +				   unsigned int chunksize)
>> +{
>> +	int index;
>> +
>> +	index = __ilog2_u32(chunksize);
>> +	if (index >= OCFS2_INFO_MAX_HIST)
>> +		index = OCFS2_INFO_MAX_HIST - 1;
>> +
>> +	hist->fc_chunks[index]++;
>> +	hist->fc_clusters[index] += chunksize;
>> +}
>> +
>> +static void o2ffg_update_stats(struct ocfs2_info_freefrag_stats *stats,
>> +			       unsigned int chunksize)
>> +{
>> +	if (chunksize > stats->ffs_max)
>> +		stats->ffs_max = chunksize;
>> +
>> +	if (chunksize < stats->ffs_min)
>> +		stats->ffs_min = chunksize;
>> +
>> +	stats->ffs_avg += chunksize;
>> +	stats->ffs_free_chunks_real++;
>> +}
>
> 	MUCH more readable.
>
>> +int ocfs2_info_freefrag_scan_bitmap(struct ocfs2_super *osb,
>> +				    struct inode *gb_inode, u64 blkno,
>> +				    struct ocfs2_info_freefrag *ffg)
>> +{
>> +	u32 chunks_in_group;
>> +	int status = 0, unlock = 0, i;
>> +
>> +	struct buffer_head *bh = NULL;
>> +	struct ocfs2_chain_list *cl = NULL;
>> +	struct ocfs2_chain_rec *rec = NULL;
>> +	struct ocfs2_dinode *gb_dinode = NULL;
>> +
>> +	if (gb_inode)
>> +		mutex_lock(&gb_inode->i_mutex);
>> +
>> +	if (o2info_coherent(*ffg)) {
>> +		status = ocfs2_inode_lock(gb_inode, &bh, 0);
>> +		if (status < 0) {
>> +			mlog_errno(status);
>> +			goto bail;
>> +		}
>> +		unlock = 1;
>> +	} else {
>> +		status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
>> +		if (status < 0) {
>> +			mlog_errno(status);
>> +			goto bail;
>> +		}
>> +	}
>> +
>> +	gb_dinode = (struct ocfs2_dinode *)bh->b_data;
>> +	cl = &(gb_dinode->id2.i_chain);
>
> 	This is safe because we never remove a chain entry from an
> inode.  However, if we ever shrink disks, we'll need to coordinate with
> this code.  Perhaps we should comment that.

    Alright, and the recoordination only would be needed for 
none-coherency case, right?

Fully-coherent case will be holding the inode lock, and never allow disk 
to be shrinked during the inquiry.

    Oh, Wait, an arbitrary 'fdisk' can shrink the disk regardless of 
cluster-coherency.

>
> Joel
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 2/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEINODE' for o2info ioctl.
  2010-12-07  1:07   ` Joel Becker
@ 2010-12-07  1:46     ` Tristan Ye
  0 siblings, 0 replies; 19+ messages in thread
From: Tristan Ye @ 2010-12-07  1:46 UTC (permalink / raw)
  To: ocfs2-devel

Joel Becker wrote:
> On Tue, Nov 16, 2010 at 06:13:41PM +0800, Tristan Ye wrote:
>> +	if (inode_alloc)
>> +		iput(inode_alloc);
>
> 	Do the iput up in the calling function where it matches the
> get_system_file_inode() call.  This just makes it easier to spot the
> get/put pair.

    It makes sense;)

>
> Joel
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 3/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEFRAG' for o2info ioctl.
  2010-12-07  1:45     ` Tristan Ye
@ 2010-12-07  3:36       ` Joel Becker
  0 siblings, 0 replies; 19+ messages in thread
From: Joel Becker @ 2010-12-07  3:36 UTC (permalink / raw)
  To: ocfs2-devel

On Tue, Dec 07, 2010 at 09:45:38AM +0800, Tristan Ye wrote:
> >>+	gb_dinode = (struct ocfs2_dinode *)bh->b_data;
> >>+	cl = &(gb_dinode->id2.i_chain);
> >
> >	This is safe because we never remove a chain entry from an
> >inode.  However, if we ever shrink disks, we'll need to coordinate with
> >this code.  Perhaps we should comment that.
> 
>    Alright, and the recoordination only would be needed for
> none-coherency case, right?
> 
> Fully-coherent case will be holding the inode lock, and never allow
> disk to be shrinked during the inquiry.

	You are correct.

>    Oh, Wait, an arbitrary 'fdisk' can shrink the disk regardless of
> cluster-coherency.

	We're not worried about that.  That's a mistake made by the
sysadmin, and there is no way to prevent it.  I'm only talking about a
tunefs operation that validly shrinks the ocfs2 filesystem.  We don't do
it today, but if we ever do this dirty read has to know about it.  Not
for accuracy, just not to crash.

Joel

-- 

"What no boss of a programmer can ever understand is that a programmer
 is working when he's staring out of the window"
	- With apologies to Burton Rascoe

Joel Becker
Senior Development Manager
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-01-30  6:25 [Ocfs2-devel] [PATCH 0/3] Ocfs2: Adding new codes 'OCFS2_INFO_FREEINODE' and 'OCFS2_INFO_FREEFRAG' for o2info ioctl V2 Tristan Ye
@ 2011-01-30  6:25 ` Tristan Ye
  2011-01-31 22:15   ` Mark Fasheh
  2011-02-20 12:08   ` Joel Becker
  0 siblings, 2 replies; 19+ messages in thread
From: Tristan Ye @ 2011-01-30  6:25 UTC (permalink / raw)
  To: ocfs2-devel

It's a best-effort attempt to simplize duplicated codes here.

Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
---
 fs/ocfs2/ioctl.c |   38 ++++++++++++++++++++++++++++++--------
 1 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
index 7a48681..731cf46 100644
--- a/fs/ocfs2/ioctl.c
+++ b/fs/ocfs2/ioctl.c
@@ -46,6 +46,22 @@ static inline void __o2info_set_request_error(struct ocfs2_info_request *kreq,
 #define o2info_set_request_error(a, b) \
 		__o2info_set_request_error((struct ocfs2_info_request *)&(a), b)
 
+static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
+{
+	req->ir_flags |= OCFS2_INFO_FL_FILLED;
+}
+
+#define o2info_set_request_filled(a) \
+		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
+
+static inline void __o2info_clear_request_filled(struct ocfs2_info_request *req)
+{
+	req->ir_flags &= ~OCFS2_INFO_FL_FILLED;
+}
+
+#define o2info_clear_request_filled(a) \
+		__o2info_clear_request_filled((struct ocfs2_info_request *)&(a))
+
 static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
 {
 	int status;
@@ -139,7 +155,8 @@ int ocfs2_info_handle_blocksize(struct inode *inode,
 		goto bail;
 
 	oib.ib_blocksize = inode->i_sb->s_blocksize;
-	oib.ib_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oib);
 
 	if (o2info_to_user(oib, req))
 		goto bail;
@@ -163,7 +180,8 @@ int ocfs2_info_handle_clustersize(struct inode *inode,
 		goto bail;
 
 	oic.ic_clustersize = osb->s_clustersize;
-	oic.ic_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oic);
 
 	if (o2info_to_user(oic, req))
 		goto bail;
@@ -187,7 +205,8 @@ int ocfs2_info_handle_maxslots(struct inode *inode,
 		goto bail;
 
 	oim.im_max_slots = osb->max_slots;
-	oim.im_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oim);
 
 	if (o2info_to_user(oim, req))
 		goto bail;
@@ -211,7 +230,8 @@ int ocfs2_info_handle_label(struct inode *inode,
 		goto bail;
 
 	memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
-	oil.il_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oil);
 
 	if (o2info_to_user(oil, req))
 		goto bail;
@@ -235,7 +255,8 @@ int ocfs2_info_handle_uuid(struct inode *inode,
 		goto bail;
 
 	memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1);
-	oiu.iu_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oiu);
 
 	if (o2info_to_user(oiu, req))
 		goto bail;
@@ -261,7 +282,8 @@ int ocfs2_info_handle_fs_features(struct inode *inode,
 	oif.if_compat_features = osb->s_feature_compat;
 	oif.if_incompat_features = osb->s_feature_incompat;
 	oif.if_ro_compat_features = osb->s_feature_ro_compat;
-	oif.if_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+	o2info_set_request_filled(oif);
 
 	if (o2info_to_user(oif, req))
 		goto bail;
@@ -286,7 +308,7 @@ int ocfs2_info_handle_journal_size(struct inode *inode,
 
 	oij.ij_journal_size = osb->journal->j_inode->i_size;
 
-	oij.ij_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+	o2info_set_request_filled(oij);
 
 	if (o2info_to_user(oij, req))
 		goto bail;
@@ -308,7 +330,7 @@ int ocfs2_info_handle_unknown(struct inode *inode,
 	if (o2info_from_user(oir, req))
 		goto bail;
 
-	oir.ir_flags &= ~OCFS2_INFO_FL_FILLED;
+	o2info_clear_request_filled(oir);
 
 	if (o2info_to_user(oir, req))
 		goto bail;
-- 
1.5.5

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-01-30  6:25 ` [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler Tristan Ye
@ 2011-01-31 22:15   ` Mark Fasheh
  2011-02-01  1:10     ` Joel Becker
  2011-02-01  7:48     ` Tristan Ye
  2011-02-20 12:08   ` Joel Becker
  1 sibling, 2 replies; 19+ messages in thread
From: Mark Fasheh @ 2011-01-31 22:15 UTC (permalink / raw)
  To: ocfs2-devel

On Sun, Jan 30, 2011 at 02:25:59PM +0800, Tristan Ye wrote:
> It's a best-effort attempt to simplize duplicated codes here.

Nice cleanup. I have only one issue with it:


> Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
> ---
>  fs/ocfs2/ioctl.c |   38 ++++++++++++++++++++++++++++++--------
>  1 files changed, 30 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
> index 7a48681..731cf46 100644
> --- a/fs/ocfs2/ioctl.c
> +++ b/fs/ocfs2/ioctl.c
> @@ -46,6 +46,22 @@ static inline void __o2info_set_request_error(struct ocfs2_info_request *kreq,
>  #define o2info_set_request_error(a, b) \
>  		__o2info_set_request_error((struct ocfs2_info_request *)&(a), b)
>  
> +static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
> +{
> +	req->ir_flags |= OCFS2_INFO_FL_FILLED;
> +}
> +
> +#define o2info_set_request_filled(a) \
> +		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))

The macro here (and below) casts it's argument, thus defeating any
typechecking we would have gotten from the function call. Can you
pleaseremove the macro, rename the functions (take out the __) and use them
directly? I know we might then want to deref the i*_req field in the
handlers below but I don't think that's a big deal for what we gain.
	--Mark


--
Mark Fasheh

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-01-31 22:15   ` Mark Fasheh
@ 2011-02-01  1:10     ` Joel Becker
  2011-02-01  3:06       ` Mark Fasheh
  2011-02-01  7:48     ` Tristan Ye
  1 sibling, 1 reply; 19+ messages in thread
From: Joel Becker @ 2011-02-01  1:10 UTC (permalink / raw)
  To: ocfs2-devel

On Mon, Jan 31, 2011 at 02:15:47PM -0800, Mark Fasheh wrote:
> > +static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
> > +{
> > +	req->ir_flags |= OCFS2_INFO_FL_FILLED;
> > +}
> > +
> > +#define o2info_set_request_filled(a) \
> > +		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
> 
> The macro here (and below) casts it's argument, thus defeating any
> typechecking we would have gotten from the function call. Can you
> pleaseremove the macro, rename the functions (take out the __) and use them
> directly? I know we might then want to deref the i*_req field in the
> handlers below but I don't think that's a big deal for what we gain.

	I'm not sure what you mean here.  Are you asking for one
set_request_filled() call per info type?

---------------------------------------------
static inline void o2info_clustersize_set_request_filled(struct ocfs2_info_clutersize *ic)
{
	ic->ic_req.ir_flags |= OCFS2_INFO_FL_FILLED;
}

static inline void o2info_blocksize_set_request_filled(struct ocfs2_info_blocksize *ib)
{
	ib->ib_req.ir_flags |= OCFS2_INFO_FL_FILLED;
}

...

---------------------------------------------

	Because that is way uglier than open-coding the |= in the
functions, IMHO.

Joel

-- 

"One of the symptoms of an approaching nervous breakdown is the
 belief that one's work is terribly important."
         - Bertrand Russell 

			http://www.jlbec.org/
			jlbec at evilplan.org

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-02-01  1:10     ` Joel Becker
@ 2011-02-01  3:06       ` Mark Fasheh
  2011-02-01  6:01         ` Joel Becker
  0 siblings, 1 reply; 19+ messages in thread
From: Mark Fasheh @ 2011-02-01  3:06 UTC (permalink / raw)
  To: ocfs2-devel

On Mon, Jan 31, 2011 at 05:10:12PM -0800, Joel Becker wrote:
> On Mon, Jan 31, 2011 at 02:15:47PM -0800, Mark Fasheh wrote:
> > > +static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
> > > +{
> > > +	req->ir_flags |= OCFS2_INFO_FL_FILLED;
> > > +}
> > > +
> > > +#define o2info_set_request_filled(a) \
> > > +		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
> > 
> > The macro here (and below) casts it's argument, thus defeating any
> > typechecking we would have gotten from the function call. Can you
> > pleaseremove the macro, rename the functions (take out the __) and use them
> > directly? I know we might then want to deref the i*_req field in the
> > handlers below but I don't think that's a big deal for what we gain.
> 
> 	I'm not sure what you mean here.  Are you asking for one
> set_request_filled() call per info type?

Oh, no!

I was asking for this:

static inline void o2info_set_request_filled(struct ocfs2_info_request *req)
{
	req->ir_flags |= OCFS2_INFO_FL_FILLED;
}

instead of the macro which is defeating type checking.

Hope that's more clear.
	--Mark

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-02-01  3:06       ` Mark Fasheh
@ 2011-02-01  6:01         ` Joel Becker
  2011-02-01  7:53           ` Tristan Ye
  2011-02-01 17:37           ` Mark Fasheh
  0 siblings, 2 replies; 19+ messages in thread
From: Joel Becker @ 2011-02-01  6:01 UTC (permalink / raw)
  To: ocfs2-devel

On Mon, Jan 31, 2011 at 07:06:18PM -0800, Mark Fasheh wrote:
> On Mon, Jan 31, 2011 at 05:10:12PM -0800, Joel Becker wrote:
> > On Mon, Jan 31, 2011 at 02:15:47PM -0800, Mark Fasheh wrote:
> > > > +static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
> > > > +{
> > > > +	req->ir_flags |= OCFS2_INFO_FL_FILLED;
> > > > +}
> > > > +
> > > > +#define o2info_set_request_filled(a) \
> > > > +		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
> > > 
> > > The macro here (and below) casts it's argument, thus defeating any
> > > typechecking we would have gotten from the function call. Can you
> > > pleaseremove the macro, rename the functions (take out the __) and use them
> > > directly? I know we might then want to deref the i*_req field in the
> > > handlers below but I don't think that's a big deal for what we gain.
> > 
> > 	I'm not sure what you mean here.  Are you asking for one
> > set_request_filled() call per info type?
> 
> Oh, no!
> 
> I was asking for this:
> 
> static inline void o2info_set_request_filled(struct ocfs2_info_request *req)
> {
> 	req->ir_flags |= OCFS2_INFO_FL_FILLED;
> }
> 
> instead of the macro which is defeating type checking.

	You want the casts or derefs forced in the caller, then?

	o2info_set_request_filled((struct ocfs2_info_request *)ic);

or:

	o2info_set_request_filled(&ic->ic_req);

Joel

-- 

Life's Little Instruction Book #80

	"Slow dance"

			http://www.jlbec.org/
			jlbec at evilplan.org

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-01-31 22:15   ` Mark Fasheh
  2011-02-01  1:10     ` Joel Becker
@ 2011-02-01  7:48     ` Tristan Ye
  1 sibling, 0 replies; 19+ messages in thread
From: Tristan Ye @ 2011-02-01  7:48 UTC (permalink / raw)
  To: ocfs2-devel

Mark Fasheh wrote:
> On Sun, Jan 30, 2011 at 02:25:59PM +0800, Tristan Ye wrote:
>> It's a best-effort attempt to simplize duplicated codes here.
>
> Nice cleanup. I have only one issue with it:
>
>
>> Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
>> ---
>>  fs/ocfs2/ioctl.c |   38 ++++++++++++++++++++++++++++++--------
>>  1 files changed, 30 insertions(+), 8 deletions(-)
>>
>> diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
>> index 7a48681..731cf46 100644
>> --- a/fs/ocfs2/ioctl.c
>> +++ b/fs/ocfs2/ioctl.c
>> @@ -46,6 +46,22 @@ static inline void __o2info_set_request_error(struct ocfs2_info_request *kreq,
>>  #define o2info_set_request_error(a, b) \
>>  		__o2info_set_request_error((struct ocfs2_info_request *)&(a), b)
>>  
>> +static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
>> +{
>> +	req->ir_flags |= OCFS2_INFO_FL_FILLED;
>> +}
>> +
>> +#define o2info_set_request_filled(a) \
>> +		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
>
> The macro here (and below) casts it's argument, thus defeating any
> typechecking we would have gotten from the function call. Can you
> pleaseremove the macro, rename the functions (take out the __) and use them
> directly? I know we might then want to deref the i*_req field in the
> handlers below but I don't think that's a big deal for what we gain.

Hi Mark,

    The reason why I used a macro is to make the life of caller as easy 
as taking the
specific info object(like ocfs2_info_blocksize, or 
ocfs2_info_clustersize etc) directly,
just for the sake of making the codes look more neat.

    That's not a big deal to use a direct inline func, while need caller 
bother to cast
the info type;-)

Tristan.

> 	--Mark
>
>
> --
> Mark Fasheh

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-02-01  6:01         ` Joel Becker
@ 2011-02-01  7:53           ` Tristan Ye
  2011-02-01 17:37           ` Mark Fasheh
  1 sibling, 0 replies; 19+ messages in thread
From: Tristan Ye @ 2011-02-01  7:53 UTC (permalink / raw)
  To: ocfs2-devel

Joel Becker wrote:
> On Mon, Jan 31, 2011 at 07:06:18PM -0800, Mark Fasheh wrote:
>> On Mon, Jan 31, 2011 at 05:10:12PM -0800, Joel Becker wrote:
>>> On Mon, Jan 31, 2011 at 02:15:47PM -0800, Mark Fasheh wrote:
>>>>> +static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
>>>>> +{
>>>>> +	req->ir_flags |= OCFS2_INFO_FL_FILLED;
>>>>> +}
>>>>> +
>>>>> +#define o2info_set_request_filled(a) \
>>>>> +		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
>>>> The macro here (and below) casts it's argument, thus defeating any
>>>> typechecking we would have gotten from the function call. Can you
>>>> pleaseremove the macro, rename the functions (take out the __) and use them
>>>> directly? I know we might then want to deref the i*_req field in the
>>>> handlers below but I don't think that's a big deal for what we gain.
>>> 	I'm not sure what you mean here.  Are you asking for one
>>> set_request_filled() call per info type?
>> Oh, no!
>>
>> I was asking for this:
>>
>> static inline void o2info_set_request_filled(struct ocfs2_info_request *req)
>> {
>> 	req->ir_flags |= OCFS2_INFO_FL_FILLED;
>> }
>>
>> instead of the macro which is defeating type checking.
>
> 	You want the casts or derefs forced in the caller, then?
>
> 	o2info_set_request_filled((struct ocfs2_info_request *)ic);
>
> or:
>
> 	o2info_set_request_filled(&ic->ic_req);
Joel,

    Indeed! and seems it will not be making caller's life that hard;-)


   
   
>
> Joel
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-02-01  6:01         ` Joel Becker
  2011-02-01  7:53           ` Tristan Ye
@ 2011-02-01 17:37           ` Mark Fasheh
  1 sibling, 0 replies; 19+ messages in thread
From: Mark Fasheh @ 2011-02-01 17:37 UTC (permalink / raw)
  To: ocfs2-devel

On Mon, Jan 31, 2011 at 10:01:27PM -0800, Joel Becker wrote:
> On Mon, Jan 31, 2011 at 07:06:18PM -0800, Mark Fasheh wrote:
> > On Mon, Jan 31, 2011 at 05:10:12PM -0800, Joel Becker wrote:
> > > On Mon, Jan 31, 2011 at 02:15:47PM -0800, Mark Fasheh wrote:
> > > > > +static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
> > > > > +{
> > > > > +	req->ir_flags |= OCFS2_INFO_FL_FILLED;
> > > > > +}
> > > > > +
> > > > > +#define o2info_set_request_filled(a) \
> > > > > +		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
> > > > 
> > > > The macro here (and below) casts it's argument, thus defeating any
> > > > typechecking we would have gotten from the function call. Can you
> > > > pleaseremove the macro, rename the functions (take out the __) and use them
> > > > directly? I know we might then want to deref the i*_req field in the
> > > > handlers below but I don't think that's a big deal for what we gain.
> > > 
> > > 	I'm not sure what you mean here.  Are you asking for one
> > > set_request_filled() call per info type?
> > 
> > Oh, no!
> > 
> > I was asking for this:
> > 
> > static inline void o2info_set_request_filled(struct ocfs2_info_request *req)
> > {
> > 	req->ir_flags |= OCFS2_INFO_FL_FILLED;
> > }
> > 
> > instead of the macro which is defeating type checking.
> 
> 	You want the casts or derefs forced in the caller, then?
> 
> 	o2info_set_request_filled((struct ocfs2_info_request *)ic);
> 
> or:
> 
> 	o2info_set_request_filled(&ic->ic_req);

Derefs in the callers would make most sense if we want to keep the type
checking in tact.
	--Mark

--
Mark Fasheh

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler.
  2011-01-30  6:25 ` [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler Tristan Ye
  2011-01-31 22:15   ` Mark Fasheh
@ 2011-02-20 12:08   ` Joel Becker
  1 sibling, 0 replies; 19+ messages in thread
From: Joel Becker @ 2011-02-20 12:08 UTC (permalink / raw)
  To: ocfs2-devel

On Sun, Jan 30, 2011 at 02:25:59PM +0800, Tristan Ye wrote:
> It's a best-effort attempt to simplize duplicated codes here.
> 
> Signed-off-by: Tristan Ye <tristan.ye@oracle.com>

	This patch is now in the merge-window branch of ocfs2.git.

Joel

-- 

"Hell is oneself, hell is alone, the other figures in it, merely projections."
        - T. S. Eliot

			http://www.jlbec.org/
			jlbec at evilplan.org

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-02-20 12:08 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-16 10:13 [Ocfs2-devel] [PATCH 0/3] Ocfs2: Adding new codes 'OCFS2_INFO_FREEINODE' and 'OCFS2_INFO_FREEFRAG' for o2info ioctl V2 Tristan Ye
2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler Tristan Ye
2010-12-07  1:04   ` Joel Becker
2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 2/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEINODE' for o2info ioctl Tristan Ye
2010-12-07  1:07   ` Joel Becker
2010-12-07  1:46     ` Tristan Ye
2010-11-16 10:13 ` [Ocfs2-devel] [PATCH 3/3] Ocfs2: Add a new code 'OCFS2_INFO_FREEFRAG' " Tristan Ye
2010-12-07  1:11   ` Joel Becker
2010-12-07  1:45     ` Tristan Ye
2010-12-07  3:36       ` Joel Becker
  -- strict thread matches above, loose matches on Subject: below --
2011-01-30  6:25 [Ocfs2-devel] [PATCH 0/3] Ocfs2: Adding new codes 'OCFS2_INFO_FREEINODE' and 'OCFS2_INFO_FREEFRAG' for o2info ioctl V2 Tristan Ye
2011-01-30  6:25 ` [Ocfs2-devel] [PATCH 1/3] Ocfs2: Using macro to set/clear *FILLED* flags in info handler Tristan Ye
2011-01-31 22:15   ` Mark Fasheh
2011-02-01  1:10     ` Joel Becker
2011-02-01  3:06       ` Mark Fasheh
2011-02-01  6:01         ` Joel Becker
2011-02-01  7:53           ` Tristan Ye
2011-02-01 17:37           ` Mark Fasheh
2011-02-01  7:48     ` Tristan Ye
2011-02-20 12:08   ` Joel Becker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).