[Ocfs2-tools-devel] [PATCH 1/6] ocfs2: add new ocfs2_local_alloc_rec structure

Srinivas Eeda srinivas.eeda at oracle.com
Mon May 7 16:49:05 PDT 2012


This patch adds ocfs2_local_alloc_rec structure which tracks contiguous free
chunk of space. There is a minimum of 1 record that tracks atleast one free
chunk. Total number of records are limited by the max of 1) value defined by
OCFS2_MAX_LOCAL_ALLOC_RECS, or 2) number of available bits inside bitmap(each
time a record is added some additional space is consumed by the rec structure
itself), or 3) value defined by local_alloc_default_bits.

Signed-off-by: Srinivas Eeda <srinivas.eeda at oracle.com>
---
 include/ocfs2-kernel/ocfs2_fs.h |   54 +++++++++++++++++++++++++++++++++++---
 include/ocfs2/ocfs2.h           |    8 ++++++
 libocfs2/feature_string.c       |   27 +++++++++++++++----
 libocfs2/inode.c                |   23 +++++++++++++++-
 4 files changed, 99 insertions(+), 13 deletions(-)

diff --git a/include/ocfs2-kernel/ocfs2_fs.h b/include/ocfs2-kernel/ocfs2_fs.h
index 3eafb07..b781ae6 100644
--- a/include/ocfs2-kernel/ocfs2_fs.h
+++ b/include/ocfs2-kernel/ocfs2_fs.h
@@ -102,6 +102,7 @@
 					 | OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS \
 					 | OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE \
 					 | OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG	\
+					 | OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA \
 					 | OCFS2_FEATURE_INCOMPAT_CLUSTERINFO)
 #define OCFS2_FEATURE_RO_COMPAT_SUPP	(OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
 					 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
@@ -177,6 +178,9 @@
  */
 #define OCFS2_FEATURE_INCOMPAT_CLUSTERINFO	0x4000
 
+/* Discontigous local alloc */
+#define OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA	0x8000
+
 /*
  * backup superblock flag is used to indicate that this volume
  * has backup superblocks.
@@ -672,14 +676,28 @@ struct ocfs2_super_block {
  * Local allocation bitmap for OCFS2 slots
  * Note that it exists inside an ocfs2_dinode, so all offsets are
  * relative to the start of ocfs2_dinode.id2.
+ * Each ocfs2_local_alloc_rec tracks one contigous chunk of clusters.
  */
+
+#define OCFS2_LOCAL_ALLOC_REC_SZ(la)	(la->la_rec_count *\
+					 sizeof(struct ocfs2_local_alloc_rec))
+#define OCFS2_LOCAL_ALLOC_BITMAP(la)    ((char *)(&(la->la_recs)) +\
+					 OCFS2_LOCAL_ALLOC_REC_SZ(la))
+
+/* Maximum number of local alloc records */
+#define OCFS2_MAX_LOCAL_ALLOC_REC_LIMIT	128
+
+struct ocfs2_local_alloc_rec {
+	__le32 la_start;	/* 1st cluster in this extent */
+	__le32 la_clusters;	/* Number of contiguous clusters */
+};
+
 struct ocfs2_local_alloc
 {
 /*00*/	__le32 la_bm_off;	/* Starting bit offset in main bitmap */
 	__le16 la_size;		/* Size of included bitmap, in bytes */
-	__le16 la_reserved1;
-	__le64 la_reserved2;
-/*10*/	__u8   la_bitmap[0];
+	__le16 la_rec_count;	/* Number of discontiguous records */
+	struct ocfs2_local_alloc_rec la_recs[]; /* Local alloc records */
 };
 
 /*
@@ -1389,11 +1407,23 @@ static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
 	u16 size;
 
 	size = sb->s_blocksize -
-		offsetof(struct ocfs2_dinode, id2.i_lab.la_bitmap);
+		offsetof(struct ocfs2_dinode, id2.i_lab.la_recs);
+	size -= sizeof(struct ocfs2_local_alloc_rec);
 
 	return size;
 }
 
+static inline u32 ocfs2_local_alloc_cluster_count(struct ocfs2_local_alloc *la)
+{
+	u32 clusters;
+
+	clusters = 0;
+	for (i = 0; i < la->la_rec_count; i++)
+		clusters +=  la->la_recs[i].la_clusters;
+
+	return clusters;
+}
+
 static inline int ocfs2_group_bitmap_size(struct super_block *sb,
 					  int suballocator,
 					  u32 feature_incompat)
@@ -1566,11 +1596,25 @@ static inline int ocfs2_local_alloc_size(int blocksize)
 	int size;
 
 	size = blocksize -
-		offsetof(struct ocfs2_dinode, id2.i_lab.la_bitmap);
+		offsetof(struct ocfs2_dinode, id2.i_lab.la_recs);
+	size -= sizeof(struct ocfs2_local_alloc_rec);
 
 	return size;
 }
 
+/* effectively this is also the bitmap size */
+static inline uint32_t
+ocfs2_local_alloc_cluster_count(struct ocfs2_local_alloc *la)
+{
+	uint32_t i, clusters;
+
+	clusters = 0;
+	for (i = 0; i < la->la_rec_count; i++)
+		clusters +=  la->la_recs[i].la_clusters;
+
+	return clusters;
+}
+
 static inline int ocfs2_group_bitmap_size(int blocksize,
 					  int suballocator,
 					  uint32_t feature_incompat)
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 23e854a..ecefcd4 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -1419,6 +1419,14 @@ static inline int ocfs2_supports_discontig_bg(struct ocfs2_super_block *osb)
 	return 0;
 }
 
+static inline int ocfs2_supports_discontig_la(struct ocfs2_super_block *osb)
+{
+	if (OCFS2_HAS_INCOMPAT_FEATURE(osb,
+					OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA))
+		return 1;
+	return 0;
+}
+
 /*
  * shamelessly lifted from the kernel
  *
diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
index 544cc6e..00d2312 100644
--- a/libocfs2/feature_string.c
+++ b/libocfs2/feature_string.c
@@ -68,7 +68,8 @@ static ocfs2_fs_options feature_level_defaults[] = {
 	 OCFS2_FEATURE_INCOMPAT_XATTR |
 	 OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE |
 	 OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS |
-	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG,
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG |
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_FEATURE_LEVEL_DEFAULT */
 
 	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
@@ -83,7 +84,8 @@ static ocfs2_fs_options feature_level_defaults[] = {
 	 OCFS2_FEATURE_INCOMPAT_XATTR |
 	 OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE |
 	 OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS |
-	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG,
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG |
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN |
 	 OCFS2_FEATURE_RO_COMPAT_USRQUOTA |
 	 OCFS2_FEATURE_RO_COMPAT_GRPQUOTA }, /* OCFS2_FEATURE_LEVEL_MAX_FEATURES */
@@ -97,7 +99,8 @@ static ocfs2_fs_options mkfstypes_features_defaults[] = {
 	 OCFS2_FEATURE_INCOMPAT_XATTR |
 	 OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE |
 	 OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS |
-	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG,
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG |
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_MKFSTYPE_DEFAULT */
 
 	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
@@ -107,7 +110,8 @@ static ocfs2_fs_options mkfstypes_features_defaults[] = {
 	 OCFS2_FEATURE_INCOMPAT_XATTR |
 	 OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE |
 	 OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS |
-	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG,
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG |
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_MKFSTYPE_DATAFILES */
 
 	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
@@ -117,7 +121,8 @@ static ocfs2_fs_options mkfstypes_features_defaults[] = {
 	 OCFS2_FEATURE_INCOMPAT_XATTR |
 	 OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE |
 	 OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS |
-	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG,
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG |
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_MKFSTYPE_MAIL */
 
 	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
@@ -127,7 +132,8 @@ static ocfs2_fs_options mkfstypes_features_defaults[] = {
 	 OCFS2_FEATURE_INCOMPAT_XATTR |
 	 OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE |
 	 OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS |
-	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG,
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG |
+	 OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_MKFSTYPE_VMSTORE */
 };
 
@@ -200,6 +206,11 @@ static struct fs_feature_flags ocfs2_supported_features[] = {
 		{0, OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG, 0},
 	},
 	{
+		"discontig-la",
+		{0, OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA, 0},
+		{0, OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA, 0},
+	},
+	{
 		"clusterinfo",
 		{0, OCFS2_FEATURE_INCOMPAT_CLUSTERINFO, 0},
 		{0, OCFS2_FEATURE_INCOMPAT_CLUSTERINFO, 0},
@@ -292,6 +303,10 @@ static struct feature_name ocfs2_feature_names[] = {
 		.fn_flag = {0, OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG, 0},
 	},
 	{
+		.fn_name = "discontig-la",
+		.fn_flag = {0, OCFS2_FEATURE_INCOMPAT_DISCONTIG_LA, 0},
+	},
+	{
 		.fn_name = "clusterinfo",
 		.fn_flag = {0, OCFS2_FEATURE_INCOMPAT_CLUSTERINFO, 0},
 	},
diff --git a/libocfs2/inode.c b/libocfs2/inode.c
index 3e78737..3c4b0a5 100644
--- a/libocfs2/inode.c
+++ b/libocfs2/inode.c
@@ -97,11 +97,29 @@ static void ocfs2_swap_inode_third(ocfs2_filesys *fs, struct ocfs2_dinode *di)
 			rec->t_start    = bswap_32(rec->t_start);
 			rec->t_clusters = bswap_32(rec->t_clusters);
 		}
+
+	} else if (di->i_flags & OCFS2_LOCAL_ALLOC_FL) {
+		struct ocfs2_local_alloc *la = &di->id2.i_lab;
+		uint16_t i;
+
+		for (i = 0; i < la->la_rec_count; i++) {
+			struct ocfs2_local_alloc_rec *rec =
+				&la->la_recs[i];
+
+			if (ocfs2_swap_barrier(fs, di, rec,
+					     sizeof(struct ocfs2_truncate_rec)))
+				break;
+
+			rec->la_start    = bswap_32(rec->la_start);
+			rec->la_clusters = bswap_32(rec->la_clusters);
+		}
 	}
 }
 
 static void ocfs2_swap_inode_second(struct ocfs2_dinode *di)
 {
+	__le16 i;
+
 	if (S_ISCHR(di->i_mode) || S_ISBLK(di->i_mode))
 		di->id1.dev1.i_rdev = bswap_64(di->id1.dev1.i_rdev);
 	else if (di->i_flags & OCFS2_BITMAP_FL) {
@@ -146,8 +164,9 @@ static void ocfs2_swap_inode_second(struct ocfs2_dinode *di)
 	} else if (di->i_flags & OCFS2_LOCAL_ALLOC_FL) {
 		struct ocfs2_local_alloc *la = &di->id2.i_lab;
 
-		la->la_bm_off = bswap_32(la->la_bm_off);
-		la->la_size   = bswap_16(la->la_size);
+		la->la_size      = bswap_16(la->la_size);
+		la->la_bm_off    = bswap_32(la->la_bm_off);
+		la->la_rec_count = bswap_16(la->la_rec_count);
 
 	} else if (di->i_flags & OCFS2_CHAIN_FL) {
 		struct ocfs2_chain_list *cl = &di->id2.i_chain;
-- 
1.5.4.3




More information about the Ocfs2-tools-devel mailing list