From ec20cec7a351584ca6c70ead012e73d61f9a8e04 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Fri, 19 Mar 2010 14:13:52 -0700 Subject: ocfs2: Make ocfs2_journal_dirty() void. jbd[2]_journal_dirty_metadata() only returns 0. It's been returning 0 since before the kernel moved to git. There is no point in checking this error. ocfs2_journal_dirty() has been faithfully returning the status since the beginning. All over ocfs2, we have blocks of code checking this can't fail status. In the past few years, we've tried to avoid adding these checks, because they are pointless. But anyone who looks at our code assumes they are needed. Finally, ocfs2_journal_dirty() is made a void function. All error checking is removed from other files. We'll BUG_ON() the status of jbd2_journal_dirty_metadata() just in case they change it someday. They won't. Signed-off-by: Joel Becker --- fs/ocfs2/resize.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'fs/ocfs2/resize.c') diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index 3c3d673a4d20..a821f667b5c4 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c @@ -134,11 +134,7 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, le16_add_cpu(&group->bg_free_bits_count, -1 * backups); } - ret = ocfs2_journal_dirty(handle, group_bh); - if (ret < 0) { - mlog_errno(ret); - goto out_rollback; - } + ocfs2_journal_dirty(handle, group_bh); /* update the inode accordingly. */ ret = ocfs2_journal_access_di(handle, INODE_CACHE(bm_inode), bm_bh, @@ -545,12 +541,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) group = (struct ocfs2_group_desc *)group_bh->b_data; group->bg_next_group = cr->c_blkno; - - ret = ocfs2_journal_dirty(handle, group_bh); - if (ret < 0) { - mlog_errno(ret); - goto out_commit; - } + ocfs2_journal_dirty(handle, group_bh); ret = ocfs2_journal_access_di(handle, INODE_CACHE(main_bm_inode), main_bm_bh, OCFS2_JOURNAL_ACCESS_WRITE); -- cgit From 4cbe4249d6586d5d88ef271e07302407a14c8443 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Tue, 13 Apr 2010 14:26:12 +0800 Subject: ocfs2: Define data structures for discontiguous block groups. Defines the OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG feature bit and modifies struct ocfs2_group_desc for the feature. Signed-off-by: Joel Becker Signed-off-by: Tao Ma --- fs/ocfs2/localalloc.c | 2 +- fs/ocfs2/ocfs2_fs.h | 53 ++++++++++++++++++++++++++++++++++++++++++++------- fs/ocfs2/resize.c | 4 ++-- fs/ocfs2/suballoc.c | 2 +- fs/ocfs2/super.c | 2 +- 5 files changed, 51 insertions(+), 12 deletions(-) (limited to 'fs/ocfs2/resize.c') 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) struct super_block *sb = osb->sb; gd_mb = ocfs2_clusters_to_megabytes(osb->sb, - 8 * ocfs2_group_bitmap_size(sb)); + 8 * ocfs2_group_bitmap_size(sb, 0)); /* * 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 @@ /* Refcount tree support */ #define OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE 0x1000 +/* Discontigous block groups */ +#define OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG 0x2000 + /* * backup superblock flag is used to indicate that this volume * has backup superblocks. @@ -831,6 +834,13 @@ struct ocfs2_dx_leaf { struct ocfs2_dx_entry_list dl_list; }; +/* + * Largest bitmap for a block (suballocator) group in bytes. This limit + * does not affect cluster groups (global allocator). Cluster group + * bitmaps run to the end of the block. + */ +#define OCFS2_MAX_BG_BITMAP_SIZE 256 + /* * On disk allocator group structure for OCFS2 */ @@ -852,7 +862,29 @@ struct ocfs2_group_desc __le64 bg_blkno; /* Offset on disk, in blocks */ /*30*/ struct ocfs2_block_check bg_check; /* Error checking */ __le64 bg_reserved2; -/*40*/ __u8 bg_bitmap[0]; +/*40*/ union { + __u8 bg_bitmap[0]; + struct { + /* + * Block groups may be discontiguous when + * OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG is set. + * The extents of a discontigous block group are + * stored in bg_list. It is a flat list. + * l_tree_depth must always be zero. A + * discontiguous group is signified by a non-zero + * bg_list->l_next_free_rec. Only block groups + * can be discontiguous; Cluster groups cannot. + * We've never made a block group with more than + * 2048 blocks (256 bytes of bg_bitmap). This + * codifies that limit so that we can fit bg_list. + * bg_size of a discontiguous block group will + * be 256 to match bg_bitmap_filler. + */ + __u8 bg_bitmap_filler[OCFS2_MAX_BG_BITMAP_SIZE]; +/*140*/ struct ocfs2_extent_list bg_list; + }; + }; +/* Actual on-disk size is one block */ }; struct ocfs2_refcount_rec { @@ -1276,12 +1308,16 @@ static inline u16 ocfs2_local_alloc_size(struct super_block *sb) return size; } -static inline int ocfs2_group_bitmap_size(struct super_block *sb) +static inline int ocfs2_group_bitmap_size(struct super_block *sb, + int suballocator) { int size; - size = sb->s_blocksize - - offsetof(struct ocfs2_group_desc, bg_bitmap); + if (suballocator) + size = OCFS2_MAX_BG_BITMAP_SIZE; + else + size = sb->s_blocksize - + offsetof(struct ocfs2_group_desc, bg_bitmap); return size; } @@ -1404,12 +1440,15 @@ static inline int ocfs2_local_alloc_size(int blocksize) return size; } -static inline int ocfs2_group_bitmap_size(int blocksize) +static inline int ocfs2_group_bitmap_size(int blocksize, int suballocator) { int size; - size = blocksize - - offsetof(struct ocfs2_group_desc, bg_bitmap); + if (suballocator) + size = OCFS2_MAX_BG_BITMAP_SIZE; + else + size = blocksize - + offsetof(struct ocfs2_group_desc, bg_bitmap); return size; } 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) BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != - ocfs2_group_bitmap_size(osb->sb) * 8) { + ocfs2_group_bitmap_size(osb->sb, 0) * 8) { mlog(ML_ERROR, "The disk is too old and small. " "Force to do offline resize."); ret = -EINVAL; @@ -496,7 +496,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) fe = (struct ocfs2_dinode *)main_bm_bh->b_data; if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != - ocfs2_group_bitmap_size(osb->sb) * 8) { + ocfs2_group_bitmap_size(osb->sb, 0) * 8) { mlog(ML_ERROR, "The disk is too old and small." " Force to do offline resize."); 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, memset(bg, 0, sb->s_blocksize); strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE); bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation); - bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb)); + bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb, 1)); bg->bg_bits = cpu_to_le16(ocfs2_bits_per_group(cl)); bg->bg_chain = cpu_to_le16(my_chain); 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, osb->osb_clusters_at_boot = OCFS2_I(inode)->ip_clusters; iput(inode); - osb->bitmap_cpg = ocfs2_group_bitmap_size(sb) * 8; + osb->bitmap_cpg = ocfs2_group_bitmap_size(sb, 0) * 8; status = ocfs2_init_slot_info(osb); if (status < 0) { -- cgit From 8571882c21e5073b2f96147ec4ff9b7042339e1b Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Tue, 13 Apr 2010 14:38:06 +0800 Subject: ocfs2: ocfs2_group_bitmap_size has to handle old volume. ocfs2_group_bitmap_size has to handle the case when the volume don't have discontiguous block group support. So pass the feature_incompat in and check it. Signed-off-by: Tao Ma --- fs/ocfs2/localalloc.c | 2 +- fs/ocfs2/ocfs2_fs.h | 37 +++++++++++++++++++++++++------------ fs/ocfs2/resize.c | 6 ++++-- fs/ocfs2/suballoc.c | 3 ++- fs/ocfs2/super.c | 3 ++- 5 files changed, 34 insertions(+), 17 deletions(-) (limited to 'fs/ocfs2/resize.c') diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index aab1b634cc8e..3d7419682dc0 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) struct super_block *sb = osb->sb; gd_mb = ocfs2_clusters_to_megabytes(osb->sb, - 8 * ocfs2_group_bitmap_size(sb, 0)); + 8 * ocfs2_group_bitmap_size(sb, 0, osb->s_feature_incompat)); /* * 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 a17bce591ee3..67bb8a77e868 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h @@ -1338,15 +1338,21 @@ static inline u16 ocfs2_local_alloc_size(struct super_block *sb) } static inline int ocfs2_group_bitmap_size(struct super_block *sb, - int suballocator) + int suballocator, + u32 feature_incompat) { - int size; + int size = sb->s_blocksize - + offsetof(struct ocfs2_group_desc, bg_bitmap); - if (suballocator) + /* + * The cluster allocator uses the entire block. Suballocators have + * never used more than OCFS2_MAX_BG_BITMAP_SIZE. Unfortunately, older + * code expects bg_size set to the maximum. Thus we must keep + * bg_size as-is unless discontig_bg is enabled. + */ + if (suballocator && + (feature_incompat & OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG)) size = OCFS2_MAX_BG_BITMAP_SIZE; - else - size = sb->s_blocksize - - offsetof(struct ocfs2_group_desc, bg_bitmap); return size; } @@ -1479,15 +1485,22 @@ static inline int ocfs2_local_alloc_size(int blocksize) return size; } -static inline int ocfs2_group_bitmap_size(int blocksize, int suballocator) +static inline int ocfs2_group_bitmap_size(int blocksize, + int suballocator, + uint32_t feature_incompat) { - int size; + int size = sb->s_blocksize - + offsetof(struct ocfs2_group_desc, bg_bitmap); - if (suballocator) + /* + * The cluster allocator uses the entire block. Suballocators have + * never used more than OCFS2_MAX_BG_BITMAP_SIZE. Unfortunately, older + * code expects bg_size set to the maximum. Thus we must keep + * bg_size as-is unless discontig_bg is enabled. + */ + if (suballocator && + (feature_incompat & OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG)) size = OCFS2_MAX_BG_BITMAP_SIZE; - else - size = blocksize - - offsetof(struct ocfs2_group_desc, bg_bitmap); return size; } diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index 5bbfc123781f..dacd553d8617 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c @@ -315,7 +315,8 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != - ocfs2_group_bitmap_size(osb->sb, 0) * 8) { + ocfs2_group_bitmap_size(osb->sb, 0, + osb->s_feature_incompat) * 8) { mlog(ML_ERROR, "The disk is too old and small. " "Force to do offline resize."); ret = -EINVAL; @@ -496,7 +497,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) fe = (struct ocfs2_dinode *)main_bm_bh->b_data; if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != - ocfs2_group_bitmap_size(osb->sb, 0) * 8) { + ocfs2_group_bitmap_size(osb->sb, 0, + osb->s_feature_incompat) * 8) { mlog(ML_ERROR, "The disk is too old and small." " Force to do offline resize."); ret = -EINVAL; diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index b7491e2481ca..6f39da4a9a10 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -391,7 +391,8 @@ static int ocfs2_block_group_fill(handle_t *handle, memset(bg, 0, sb->s_blocksize); strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE); bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation); - bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb, 1)); + bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb, 1, + osb->s_feature_incompat)); bg->bg_chain = cpu_to_le16(my_chain); bg->bg_next_group = cl->cl_recs[my_chain].c_blkno; bg->bg_parent_dinode = cpu_to_le64(OCFS2_I(alloc_inode)->ip_blkno); diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 59930ee4fe2e..106becf5d00f 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -2277,7 +2277,8 @@ static int ocfs2_initialize_super(struct super_block *sb, osb->osb_clusters_at_boot = OCFS2_I(inode)->ip_clusters; iput(inode); - osb->bitmap_cpg = ocfs2_group_bitmap_size(sb, 0) * 8; + osb->bitmap_cpg = ocfs2_group_bitmap_size(sb, 0, + osb->s_feature_incompat) * 8; status = ocfs2_init_slot_info(osb); if (status < 0) { -- cgit