aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/localalloc.c2
-rw-r--r--fs/ocfs2/ocfs2_fs.h53
-rw-r--r--fs/ocfs2/resize.c4
-rw-r--r--fs/ocfs2/suballoc.c2
-rw-r--r--fs/ocfs2/super.c2
5 files changed, 51 insertions, 12 deletions
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 63c41e206792..9538bbe028d4 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -122,7 +122,7 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb)
122 struct super_block *sb = osb->sb; 122 struct super_block *sb = osb->sb;
123 123
124 gd_mb = ocfs2_clusters_to_megabytes(osb->sb, 124 gd_mb = ocfs2_clusters_to_megabytes(osb->sb,
125 8 * ocfs2_group_bitmap_size(sb)); 125 8 * ocfs2_group_bitmap_size(sb, 0));
126 126
127 /* 127 /*
128 * This takes care of files systems with very small group 128 * This takes care of files systems with very small group
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index d61a1521b10e..448aa8d11a97 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -165,6 +165,9 @@
165/* Refcount tree support */ 165/* Refcount tree support */
166#define OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE 0x1000 166#define OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE 0x1000
167 167
168/* Discontigous block groups */
169#define OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG 0x2000
170
168/* 171/*
169 * backup superblock flag is used to indicate that this volume 172 * backup superblock flag is used to indicate that this volume
170 * has backup superblocks. 173 * has backup superblocks.
@@ -832,6 +835,13 @@ struct ocfs2_dx_leaf {
832}; 835};
833 836
834/* 837/*
838 * Largest bitmap for a block (suballocator) group in bytes. This limit
839 * does not affect cluster groups (global allocator). Cluster group
840 * bitmaps run to the end of the block.
841 */
842#define OCFS2_MAX_BG_BITMAP_SIZE 256
843
844/*
835 * On disk allocator group structure for OCFS2 845 * On disk allocator group structure for OCFS2
836 */ 846 */
837struct ocfs2_group_desc 847struct ocfs2_group_desc
@@ -852,7 +862,29 @@ struct ocfs2_group_desc
852 __le64 bg_blkno; /* Offset on disk, in blocks */ 862 __le64 bg_blkno; /* Offset on disk, in blocks */
853/*30*/ struct ocfs2_block_check bg_check; /* Error checking */ 863/*30*/ struct ocfs2_block_check bg_check; /* Error checking */
854 __le64 bg_reserved2; 864 __le64 bg_reserved2;
855/*40*/ __u8 bg_bitmap[0]; 865/*40*/ union {
866 __u8 bg_bitmap[0];
867 struct {
868 /*
869 * Block groups may be discontiguous when
870 * OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG is set.
871 * The extents of a discontigous block group are
872 * stored in bg_list. It is a flat list.
873 * l_tree_depth must always be zero. A
874 * discontiguous group is signified by a non-zero
875 * bg_list->l_next_free_rec. Only block groups
876 * can be discontiguous; Cluster groups cannot.
877 * We've never made a block group with more than
878 * 2048 blocks (256 bytes of bg_bitmap). This
879 * codifies that limit so that we can fit bg_list.
880 * bg_size of a discontiguous block group will
881 * be 256 to match bg_bitmap_filler.
882 */
883 __u8 bg_bitmap_filler[OCFS2_MAX_BG_BITMAP_SIZE];
884/*140*/ struct ocfs2_extent_list bg_list;
885 };
886 };
887/* Actual on-disk size is one block */
856}; 888};
857 889
858struct ocfs2_refcount_rec { 890struct ocfs2_refcount_rec {
@@ -1276,12 +1308,16 @@ static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
1276 return size; 1308 return size;
1277} 1309}
1278 1310
1279static inline int ocfs2_group_bitmap_size(struct super_block *sb) 1311static inline int ocfs2_group_bitmap_size(struct super_block *sb,
1312 int suballocator)
1280{ 1313{
1281 int size; 1314 int size;
1282 1315
1283 size = sb->s_blocksize - 1316 if (suballocator)
1284 offsetof(struct ocfs2_group_desc, bg_bitmap); 1317 size = OCFS2_MAX_BG_BITMAP_SIZE;
1318 else
1319 size = sb->s_blocksize -
1320 offsetof(struct ocfs2_group_desc, bg_bitmap);
1285 1321
1286 return size; 1322 return size;
1287} 1323}
@@ -1404,12 +1440,15 @@ static inline int ocfs2_local_alloc_size(int blocksize)
1404 return size; 1440 return size;
1405} 1441}
1406 1442
1407static inline int ocfs2_group_bitmap_size(int blocksize) 1443static inline int ocfs2_group_bitmap_size(int blocksize, int suballocator)
1408{ 1444{
1409 int size; 1445 int size;
1410 1446
1411 size = blocksize - 1447 if (suballocator)
1412 offsetof(struct ocfs2_group_desc, bg_bitmap); 1448 size = OCFS2_MAX_BG_BITMAP_SIZE;
1449 else
1450 size = blocksize -
1451 offsetof(struct ocfs2_group_desc, bg_bitmap);
1413 1452
1414 return size; 1453 return size;
1415} 1454}
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c
index a821f667b5c4..5bbfc123781f 100644
--- a/fs/ocfs2/resize.c
+++ b/fs/ocfs2/resize.c
@@ -315,7 +315,7 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters)
315 BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); 315 BUG_ON(!OCFS2_IS_VALID_DINODE(fe));
316 316
317 if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != 317 if (le16_to_cpu(fe->id2.i_chain.cl_cpg) !=
318 ocfs2_group_bitmap_size(osb->sb) * 8) { 318 ocfs2_group_bitmap_size(osb->sb, 0) * 8) {
319 mlog(ML_ERROR, "The disk is too old and small. " 319 mlog(ML_ERROR, "The disk is too old and small. "
320 "Force to do offline resize."); 320 "Force to do offline resize.");
321 ret = -EINVAL; 321 ret = -EINVAL;
@@ -496,7 +496,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
496 fe = (struct ocfs2_dinode *)main_bm_bh->b_data; 496 fe = (struct ocfs2_dinode *)main_bm_bh->b_data;
497 497
498 if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != 498 if (le16_to_cpu(fe->id2.i_chain.cl_cpg) !=
499 ocfs2_group_bitmap_size(osb->sb) * 8) { 499 ocfs2_group_bitmap_size(osb->sb, 0) * 8) {
500 mlog(ML_ERROR, "The disk is too old and small." 500 mlog(ML_ERROR, "The disk is too old and small."
501 " Force to do offline resize."); 501 " Force to do offline resize.");
502 ret = -EINVAL; 502 ret = -EINVAL;
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 667d622b3659..1070f79fa068 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -360,7 +360,7 @@ static int ocfs2_block_group_fill(handle_t *handle,
360 memset(bg, 0, sb->s_blocksize); 360 memset(bg, 0, sb->s_blocksize);
361 strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE); 361 strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE);
362 bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation); 362 bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation);
363 bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb)); 363 bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb, 1));
364 bg->bg_bits = cpu_to_le16(ocfs2_bits_per_group(cl)); 364 bg->bg_bits = cpu_to_le16(ocfs2_bits_per_group(cl));
365 bg->bg_chain = cpu_to_le16(my_chain); 365 bg->bg_chain = cpu_to_le16(my_chain);
366 bg->bg_next_group = cl->cl_recs[my_chain].c_blkno; 366 bg->bg_next_group = cl->cl_recs[my_chain].c_blkno;
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 12c2203a62fe..59930ee4fe2e 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -2277,7 +2277,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
2277 osb->osb_clusters_at_boot = OCFS2_I(inode)->ip_clusters; 2277 osb->osb_clusters_at_boot = OCFS2_I(inode)->ip_clusters;
2278 iput(inode); 2278 iput(inode);
2279 2279
2280 osb->bitmap_cpg = ocfs2_group_bitmap_size(sb) * 8; 2280 osb->bitmap_cpg = ocfs2_group_bitmap_size(sb, 0) * 8;
2281 2281
2282 status = ocfs2_init_slot_info(osb); 2282 status = ocfs2_init_slot_info(osb);
2283 if (status < 0) { 2283 if (status < 0) {