diff options
-rw-r--r-- | fs/ocfs2/localalloc.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2_fs.h | 53 | ||||
-rw-r--r-- | fs/ocfs2/resize.c | 4 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/super.c | 2 |
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 | */ |
837 | struct ocfs2_group_desc | 847 | struct 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 | ||
858 | struct ocfs2_refcount_rec { | 890 | struct 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 | ||
1279 | static inline int ocfs2_group_bitmap_size(struct super_block *sb) | 1311 | static 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 | ||
1407 | static inline int ocfs2_group_bitmap_size(int blocksize) | 1443 | static 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) { |