[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