Add online resize for ocfs2-tools,take 1
cover Add online resize for ocfs2-tools,take 1
Add online resize in tunefs.ocfs2 so that user can increase the volume when it is mounted.
PATCH 1/6 Move resize function out of tunefs.c, take 1
We will add online resize in tunefs.ocfs2, and it will be complicated. so add a new file resize.c in it and move all resize function out of tunefs.c.
---
tunefs.ocfs2/Makefile | 2 tunefs.ocfs2/resize.c | 320 +++++++++++++++++++++++++++++++++++++++++++++++++ tunefs.ocfs2/tunefs.c | 295 --------------------------------------------- tunefs.ocfs2/tunefs.h | 6 + 4 files changed, 328 insertions(+), 295 deletions(-) create mode 100644 tunefs.ocfs2/resize.c
755feb64b82a2c84291e713ccde2be2a5ea31f18
tunefs.ocfs2/Makefile +1 -1
@@ -31,7 +31,7 @@ DEFINES = -DOCFS2_FLAT_INCLUDES -DVERSIO MANS = tunefs.ocfs2.8 -CFILES = tunefs.c query.c remove_slot.c sparse_file.c features.c +CFILES = tunefs.c query.c remove_slot.c sparse_file.c features.c resize.c HFILES = tunefs.h OBJS = $(subst .c,.o,$(CFILES))
tunefs.ocfs2/resize.c new file +320 -0
320 lines not on this page · raw message
tunefs.ocfs2/tunefs.c +1 -294
319 lines not on this page · raw message
tunefs.ocfs2/tunefs.h +6 -0
@@ -98,6 +98,8 @@ typedef struct _ocfs2_tune_opts {time_t tune_time; } ocfs2_tune_opts; +void block_signals (int how); +void print_query (char *queryfmt);errcode_t remove_slots (ocfs2_filesys *fs);
@@ -113,4 +115,8 @@ void free_clear_ctxt(void);errcode_t feature_check (ocfs2_filesys *fs);errcode_t update_feature (ocfs2_filesys *fs); + +void get_vol_size (ocfs2_filesys *fs); +errcode_t update_volume_size (ocfs2_filesys *fs,int *changed); +int validate_vol_size (ocfs2_filesys *fs);#endif /* _TUNEFS_H */
Signature · 1 line
1.3.3
PATCH 2/6 Abstract some specific process in resize to some individual function,take 1
In reply to Tao MaSome process may be different for online and offline resize, so move them to different functions for future change.
---
tunefs.ocfs2/resize.c | 248 +++++++++++++++++++++++++++++-------------------- 1 files changed, 145 insertions(+), 103 deletions(-)
7d3f1927821cde69fa649ce6a001bba12a24251b
tunefs.ocfs2/resize.c +145 -103
@@ -85,15 +85,152 @@ int validate_vol_size(ocfs2_filesys *fs)return 0 ; } +/* +* Initalize the group descriptors in the new added cluster range. +* +* di: global_bitmap's inode info. +* first_new_cluster: the start cluster offset. +* num_new_cluster: cluster range length. +* chain: the chain position of the last group descriptor. the new +* group will be added to the chain after this one. +* total_bits and used_bits will be added according to the new groups. +*/ +static errcode_t init_new_gd (ocfs2_filesys *fs, +struct ocfs2_dinode *di, +uint32_t first_new_cluster, +uint32_t num_new_clusters, +uint16_t chain, +uint32_t *total_bits, +uint32_t *used_bits) +{ +errcode_t ret =0 ; +uint32_t cluster_chunk; +uint64_t gd_blkno =0 ; +struct ocfs2_chain_list *cl = &di->id2.i_chain; +struct ocfs2_chain_rec *cr =NULL ; +struct ocfs2_group_desc *gd =NULL ; +char *zero_buf =NULL ; +char *gd_buf =NULL ; + + ret =ocfs2_malloc_block (fs->fs_io, &gd_buf); +if (ret) { +com_err (opts.progname, ret,"while allocating a block during " +"volume resize" ); + goto bail; + } + + ret =ocfs2_malloc_blocks (fs->fs_io,ocfs2_clusters_to_blocks (fs,1 ), + &zero_buf); +if (ret) { +com_err (opts.progname, ret,"while allocating a cluster during " +"volume resize" ); + goto bail; + } + +memset (zero_buf,0 , fs->fs_clustersize); + gd = (struct ocfs2_group_desc *)gd_buf; + +while (num_new_clusters) { + gd_blkno =ocfs2_which_cluster_group (fs, cl->cl_cpg, + first_new_cluster); + cluster_chunk =MIN (num_new_clusters, cl->cl_cpg); + num_new_clusters -= cluster_chunk; + first_new_cluster += cluster_chunk; + +if (++chain >= cl->cl_count) + chain =0 ; + +ocfs2_init_group_desc (fs, gd, gd_blkno, + fs->fs_super->i_fs_generation, di->i_blkno, + (cluster_chunk *cl->cl_bpc), chain); + +/* Add group to chain */ + cr = &(cl->cl_recs[chain]); +if (chain >= cl->cl_next_free_rec) { + cl->cl_next_free_rec++; + cr->c_free =0 ; + cr->c_total =0 ; + cr->c_blkno =0 ; + } + + gd->bg_next_group = cr->c_blkno; + cr->c_blkno = gd_blkno; + cr->c_free += gd->bg_free_bits_count; + cr->c_total += gd->bg_bits; + + *used_bits += (gd->bg_bits - gd->bg_free_bits_count); + *total_bits += gd->bg_bits; + + fs->fs_clusters += cluster_chunk; + fs->fs_blocks +=ocfs2_clusters_to_blocks (fs, cluster_chunk); + +/* Initialize the first cluster in the group */ + ret =io_write_block (fs->fs_io, gd_blkno, +ocfs2_clusters_to_blocks (fs,1 ), zero_buf); +if (ret) { +com_err (opts.progname, ret,"while initializing the " +"cluster starting at block %" PRIu64" during " +"volume resize" , gd_blkno); + goto bail; + } + +/* write a new group descriptor */ + ret =ocfs2_write_group_desc (fs, gd_blkno, gd_buf); +if (ret) { +com_err (opts.progname, ret,"while writing group " +"descriptor at block %" PRIu64" during " +"volume resize" , gd_blkno); + goto bail; + } + } + +bail: +if (zero_buf) +ocfs2_free (&zero_buf); +if (gd_buf) +ocfs2_free (&gd_buf); +return ret; +} + +static errcode_t update_global_bitmap (ocfs2_filesys *fs, +struct ocfs2_dinode *di, +struct ocfs2_group_desc *lgd, +int flush_lgd) +{ +errcode_t ret =0 ; + +block_signals (SIG_BLOCK ); +/* Flush that last group descriptor we updated before the new ones */ +if (flush_lgd) { + ret =ocfs2_write_group_desc (fs, lgd->bg_blkno, (char *)lgd); +if (ret) { +com_err (opts.progname, ret,"while flushing group " +"descriptor at block %" PRIu64" during " +"volume resize" , lgd->bg_blkno); + goto bail; + } + } + +/* write the global bitmap inode */ + ret =ocfs2_write_inode (fs, di->i_blkno, (char *)di); +if (ret) { +com_err (opts.progname, ret,"while writing global bitmap " +"inode at block %" PRIu64" during volume resize" , + di->i_blkno); + } + +bail: +block_signals (SIG_UNBLOCK ); +return ret; +} +errcode_t update_volume_size (ocfs2_filesys *fs,int *changed) {errcode_t ret =0 ;struct ocfs2_dinode *di;uint64_t bm_blkno =0 ; -uint64_t gd_blkno =0 ;uint64_t lgd_blkno =0 ;char *in_buf =NULL ; -char *gd_buf =NULL ;char *lgd_buf =NULL ;struct ocfs2_chain_list *cl;struct ocfs2_chain_rec *cr;
@@ -106,7 +243,6 @@ errcode_t update_volume_size(ocfs2_filesuint32_t total_bits;uint32_t num_bits;int flush_lgd =0 ; -char *zero_buf =NULL ; ret =ocfs2_malloc_block (fs->fs_io, &in_buf);if (ret) {
@@ -115,13 +251,6 @@ errcode_t update_volume_size(ocfs2_files goto bail; } - ret =ocfs2_malloc_block (fs->fs_io, &gd_buf); -if (ret) { -com_err (opts.progname, ret,"while allocating a block during " -"volume resize" ); - goto bail; - } - ret =ocfs2_malloc_block (fs->fs_io, &lgd_buf);if (ret) { com_err(opts.progname, ret, "while allocating a block during "
@@ -129,16 +258,6 @@ errcode_t update_volume_size(ocfs2_files goto bail; } - ret =ocfs2_malloc_blocks (fs->fs_io,ocfs2_clusters_to_blocks (fs,1 ), - &zero_buf); -if (ret) { -com_err (opts.progname, ret,"while allocating a cluster during " -"volume resize" ); - goto bail; - } - -memset (zero_buf,0 , fs->fs_clustersize); -/* read global bitmap */ ret =ocfs2_lookup_system_inode (fs,GLOBAL_BITMAP_SYSTEM_INODE ,0 , &bm_blkno);
@@ -214,62 +333,10 @@ errcode_t update_volume_size(ocfs2_files/* Init the new groups and write to disk */ /* Add these groups one by one starting from the first chain after */ /* the one containing the last group */ - - gd = (struct ocfs2_group_desc *)gd_buf; - -while (num_new_clusters) { - gd_blkno =ocfs2_which_cluster_group (fs, cl->cl_cpg, - first_new_cluster); - cluster_chunk =MIN (num_new_clusters, cl->cl_cpg); - num_new_clusters -= cluster_chunk; - first_new_cluster += cluster_chunk; - -if (++chain >= cl->cl_count) - chain =0 ; - -ocfs2_init_group_desc (fs, gd, gd_blkno, - fs->fs_super->i_fs_generation, di->i_blkno, - (cluster_chunk *cl->cl_bpc), chain); - -/* Add group to chain */ - cr = &(cl->cl_recs[chain]); -if (chain >= cl->cl_next_free_rec) { - cl->cl_next_free_rec++; - cr->c_free =0 ; - cr->c_total =0 ; - cr->c_blkno =0 ; - } - - gd->bg_next_group = cr->c_blkno; - cr->c_blkno = gd_blkno; - cr->c_free += gd->bg_free_bits_count; - cr->c_total += gd->bg_bits; - - used_bits += (gd->bg_bits - gd->bg_free_bits_count); - total_bits += gd->bg_bits; - - fs->fs_clusters += cluster_chunk; - fs->fs_blocks +=ocfs2_clusters_to_blocks (fs, cluster_chunk); - -/* Initialize the first cluster in the group */ - ret =io_write_block (fs->fs_io, gd_blkno, -ocfs2_clusters_to_blocks (fs,1 ), zero_buf); -if (ret) { -com_err (opts.progname, ret,"while initializing the " -"cluster starting at block %" PRIu64" during " -"volume resize" , gd_blkno); - goto bail; - } - -/* write a new group descriptor */ - ret =ocfs2_write_group_desc (fs, gd_blkno, gd_buf); -if (ret) { -com_err (opts.progname, ret,"while writing group " -"descriptor at block %" PRIu64" during " -"volume resize" , gd_blkno); - goto bail; - } - } + ret =init_new_gd (fs, di, first_new_cluster, + num_new_clusters, chain, &total_bits, &used_bits); +if (ret) + goto bail; di->id1.bitmap1.i_total = total_bits; di->id1.bitmap1.i_used = used_bits;
@@ -279,40 +346,15 @@ errcode_t update_volume_size(ocfs2_files fs->fs_super->i_clusters = di->i_clusters; -block_signals (SIG_BLOCK ); -/* Flush that last group descriptor we updated before the new ones */ -if (flush_lgd) { - ret =ocfs2_write_group_desc (fs, lgd_blkno, lgd_buf); -if (ret) { -block_signals (SIG_UNBLOCK ); -com_err (opts.progname, ret,"while flushing group " -"descriptor at block %" PRIu64" during " -"volume resize" , lgd_blkno); - goto bail; - } - } - -/* write the global bitmap inode */ - ret =ocfs2_write_inode (fs, bm_blkno, in_buf); -if (ret) { -block_signals (SIG_UNBLOCK ); -com_err (opts.progname, ret,"while writing global bitmap " -"inode at block %" PRIu64" during volume resize" , - bm_blkno); + ret =update_global_bitmap (fs, di, gd, flush_lgd); +if (ret) goto bail; - } - -block_signals (SIG_UNBLOCK ); *changed =1 ; bail: -if (zero_buf) -ocfs2_free (&zero_buf);if (in_buf)ocfs2_free (&in_buf); -if (gd_buf) -ocfs2_free (&gd_buf);if (lgd_buf)ocfs2_free (&lgd_buf);
Signature · 1 line
1.3.3
PATCH 3/6 Abstract checking and validating process in tunefs.ocfs2,take 1
In reply to Tao MaIn the main function of tunefs.ocfs2, there are a large number of checking and validating process. They are seperated and can be moved out of "main" so that future online resize can skip these check easily. So add 2 new function, volume_check and validate_parameter to organize the complicated process.
There are also 2 minor changes in this patch:
1. the print of "Adding backup superblock for the volume" are moved to validate process as others.
2. remove_slot_check is moved into function volume_check as it does the check work while it was in validate process.
---
tunefs.ocfs2/tunefs.c | 267 +++++++++++++++++++++++++++---------------------- 1 files changed, 147 insertions(+), 120 deletions(-)
6e284ab75718e8e55ffb03a262e8a32a5a807a6b
tunefs.ocfs2/tunefs.c +147 -120
@@ -30,6 +30,9 @@ ocfs2_tune_opts opts;ocfs2_filesys *fs_gbl =NULL ;static int cluster_locked =0 ;static int resize =0 ; +static uint64_t def_jrnl_size =0 ; +static char old_uuid[OCFS2_VOL_UUID_LEN *2 +1 ]; +static char new_uuid[OCFS2_VOL_UUID_LEN *2 +1 ];static void usage (const char *progname) {
@@ -997,6 +1000,145 @@ static void free_opts(void)free (opts.device); } +static errcode_t volume_check (ocfs2_filesys *fs) +{ +errcode_t ret; +int dirty =0 ; +uint16_t max_slots =OCFS2_RAW_SB (fs->fs_super)->s_max_slots; + + ret =journal_check (fs, &dirty, &def_jrnl_size); +if (ret || dirty) + goto bail; + + ret =1 ; +if (opts.list_sparse) { +if (!ocfs2_sparse_alloc (OCFS2_RAW_SB (fs->fs_super))) { +com_err (opts.progname,0 , +"sparse_file flag check failed. " ); + goto bail; + } +printf ("List all the sparse files in the volume\n" ); + } + +if (opts.feature_string) { +if (feature_check (fs)) { +com_err (opts.progname,0 , +"feature check failed. " ); + goto bail; + } +printf ("Modify feature \"%s\" for the volume\n" , + opts.feature_string); + } + +/* If operation requires touching the global bitmap, ensure it is good */ +/* This is to handle failed resize */ +if (opts.num_blocks || opts.num_slots || opts.jrnl_size || + opts.backup_super) { +if (global_bitmap_check (fs)) { +com_err (opts.progname,0 ,"Global bitmap check failed. " +"Run fsck.ocfs2 -f <device>." ); + goto bail; + } + } + +/* check whether the block for backup superblock are used. */ +if (opts.backup_super) { +if (backup_super_check (fs)) + goto bail; + } + +/* remove slot check. */ +if (opts.num_slots && opts.num_slots < max_slots) { + ret =remove_slot_check (fs); +if (ret) { +com_err (opts.progname,0 , +"remove slot check failed. " ); + goto bail; + } + } + + ret =0 ; +bail: +return ret; +} + +static void validate_parameter (ocfs2_filesys *fs) +{ +uint16_t max_slots =OCFS2_RAW_SB (fs->fs_super)->s_max_slots; +uint64_t num_clusters; +char *tmpstr; + +/* valid backup super. */ +if (opts.backup_super) +printf ("Adding backup superblock for the volume\n" ); + +/* validate volume label */ +if (opts.vol_label) { +printf ("Changing volume label from %s to %s\n" , +OCFS2_RAW_SB (fs->fs_super)->s_label, opts.vol_label); + } + +/* validate volume uuid */ +if (opts.vol_uuid) { +uuid_unparse (OCFS2_RAW_SB (fs->fs_super)->s_uuid, old_uuid); +uuid_unparse (opts.vol_uuid, new_uuid); +printf ("Changing volume uuid from %s to %s\n" , old_uuid, new_uuid); + } + +/* validate mount type */ +if (opts.mount) { +if (!validate_mount_change (fs)) { +if (opts.mount ==MOUNT_LOCAL ) + tmpstr =MOUNT_LOCAL_STR ; +else + tmpstr =MOUNT_CLUSTER_STR ; +printf ("Changing mount type to %s\n" , tmpstr); + }else + opts.mount =0 ; + } + +/* validate num slots */ + max_slots =OCFS2_RAW_SB (fs->fs_super)->s_max_slots; +if (opts.num_slots) { +if (opts.num_slots > max_slots) { +if (!opts.jrnl_size) + opts.jrnl_size = def_jrnl_size; + + }else if (opts.num_slots == max_slots) { +printf ("Giving the same number of nodes. " +"Ignore the change of slots." ); + opts.num_slots =0 ; + } + +if (opts.num_slots) +printf ("Changing number of node slots from %d to %d\n" , + max_slots, opts.num_slots); + } + +/* validate journal size */ +if (opts.jrnl_size) { + num_clusters = (opts.jrnl_size + fs->fs_clustersize -1 ) >> +OCFS2_RAW_SB (fs->fs_super)->s_clustersize_bits; + + opts.jrnl_size = num_clusters << +OCFS2_RAW_SB (fs->fs_super)->s_clustersize_bits; + +if (opts.jrnl_size != def_jrnl_size) +printf ("Changing journal size %" PRIu64" to %" PRIu64"\n" , + def_jrnl_size, opts.jrnl_size); + } + +/* validate volume size */ +if (opts.num_blocks) { +if (validate_vol_size (fs)) + opts.num_blocks =0 ; +else +printf ("Changing volume size from %" PRIu64" blocks to " +"%" PRIu64" blocks\n" , fs->fs_blocks, + opts.num_blocks); + } +} +int main (int argc,char **argv) {errcode_t ret =0 ;
@@ -1011,14 +1153,8 @@ int main(int argc, char **argv)int upd_incompat =0 ;int upd_backup_super =0 ;int upd_feature =0 ; -char *tmpstr;uint16_t max_slots; -uint64_t def_jrnl_size =0 ; -uint64_t num_clusters;uint64_t old_blocks =0 ; -int dirty =0 ; -char old_uuid[OCFS2_VOL_UUID_LEN *2 +1 ]; -char new_uuid[OCFS2_VOL_UUID_LEN *2 +1 ];initialize_ocfs_error_table ();initialize_o2dl_error_table ();
@@ -1116,121 +1252,11 @@ int main(int argc, char **argv)*/ io_init_cache (fs->fs_io,ocfs2_extent_recs_per_eb (fs->fs_blocksize)); - ret =journal_check (fs, &dirty, &def_jrnl_size); -if (ret || dirty) - goto unlock; - -if (opts.list_sparse) { -if (!ocfs2_sparse_alloc (OCFS2_RAW_SB (fs->fs_super))) { -com_err (opts.progname,0 , -"sparse_file flag check failed. " ); - goto unlock; - } -printf ("List all the sparse files in the volume\n" ); - } - -if (opts.feature_string) { -if (feature_check (fs)) { -com_err (opts.progname,0 , -"feature check failed. " ); - goto unlock; - } -printf ("Modify feature \"%s\" for the volume\n" , - opts.feature_string); - } - -/* If operation requires touching the global bitmap, ensure it is good */ -/* This is to handle failed resize */ -if (opts.num_blocks || opts.num_slots || opts.jrnl_size || - opts.backup_super) { -if (global_bitmap_check (fs)) { -com_err (opts.progname,0 ,"Global bitmap check failed. " -"Run fsck.ocfs2 -f <device>." ); - goto unlock; - } - } - -/* check whether the block for backup superblock are used. */ -if (opts.backup_super) { -if (backup_super_check (fs)) - goto unlock; -else -printf ("Adding backup superblock for the volume\n" ); - } - -/* validate volume label */ -if (opts.vol_label) { -printf ("Changing volume label from %s to %s\n" , -OCFS2_RAW_SB (fs->fs_super)->s_label, opts.vol_label); - } - -/* validate volume uuid */ -if (opts.vol_uuid) { -uuid_unparse (OCFS2_RAW_SB (fs->fs_super)->s_uuid, old_uuid); -uuid_unparse (opts.vol_uuid, new_uuid); -printf ("Changing volume uuid from %s to %s\n" , old_uuid, new_uuid); - } - -/* validate mount type */ -if (opts.mount) { -if (!validate_mount_change (fs)) { -if (opts.mount ==MOUNT_LOCAL ) - tmpstr =MOUNT_LOCAL_STR ; -else - tmpstr =MOUNT_CLUSTER_STR ; -printf ("Changing mount type to %s\n" , tmpstr); - }else - opts.mount =0 ; - } - -/* validate num slots */ - max_slots =OCFS2_RAW_SB (fs->fs_super)->s_max_slots; -if (opts.num_slots) { -if (opts.num_slots < max_slots) { - ret =remove_slot_check (fs); -if (ret) { -com_err (opts.progname,0 , -"remove slot check failed. " ); - goto unlock; - } - } -else if (opts.num_slots > max_slots) { -if (!opts.jrnl_size) - opts.jrnl_size = def_jrnl_size; - - }else { -printf ("Giving the same number of nodes. " -"Ignore the change of slots." ); - opts.num_slots =0 ; - } - -if (opts.num_slots) -printf ("Changing number of node slots from %d to %d\n" , - max_slots, opts.num_slots); - } - -/* validate journal size */ -if (opts.jrnl_size) { - num_clusters = (opts.jrnl_size + fs->fs_clustersize -1 ) >> -OCFS2_RAW_SB (fs->fs_super)->s_clustersize_bits; - - opts.jrnl_size = num_clusters << -OCFS2_RAW_SB (fs->fs_super)->s_clustersize_bits; - -if (opts.jrnl_size != def_jrnl_size) -printf ("Changing journal size %" PRIu64" to %" PRIu64"\n" , - def_jrnl_size, opts.jrnl_size); - } + ret =volume_check (fs); +if (ret) + goto unlock; -/* validate volume size */ -if (opts.num_blocks) { -if (validate_vol_size (fs)) - opts.num_blocks =0 ; -else -printf ("Changing volume size from %" PRIu64" blocks to " -"%" PRIu64" blocks\n" , fs->fs_blocks, - opts.num_blocks); - } +validate_parameter (fs); if (!opts.vol_label && !opts.vol_uuid && !opts.num_slots && !opts.jrnl_size && !opts.num_blocks && !opts.mount &&
@@ -1249,6 +1275,7 @@ int main(int argc, char **argv) }/* Set resize incompat flag on superblock */ + max_slots =OCFS2_RAW_SB (fs->fs_super)->s_max_slots;if (opts.num_blocks || (opts.num_slots && opts.num_slots < max_slots)) {if (opts.num_blocks)
Signature · 1 line
1.3.3
PATCH 4/6 Modfiy cl_cpg in global_bitmap to be maximum value during mkfs,take 1
In reply to Tao Macl_cpg is used in ocfs2 kernel to calculate the group no for a given cluster. Change it to maximum number so that there is no need to update it durin online resize.
---
fsck.ocfs2/pass0.c | 2 +- mkfs.ocfs2/mkfs.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
fe4f6a9996e36994e36196422efac3665dca90f8
fsck.ocfs2/pass0.c +1 -1
@@ -393,7 +393,7 @@ static void mark_group_used(o2fsck_state }/* -* Due to a glitch in mkfs, cl->cl_cpg for the GLOBAL BITMAP could be +* Due to a glitch in old mkfs, cl->cl_cpg for the GLOBAL BITMAP could be * less than the max possible for volumes having just one cluster * group. Fix. */
mkfs.ocfs2/mkfs.c +2 -1
@@ -1910,7 +1910,8 @@ format_file(State *s, SystemFileDiskRecoif (rec->cluster_bitmap) { di->id2.i_chain.cl_count =ocfs2_chain_recs_per_inode (s->blocksize); - di->id2.i_chain.cl_cpg = s->global_cpg; + di->id2.i_chain.cl_cpg = +ocfs2_group_bitmap_size (s->blocksize) *8 ; di->id2.i_chain.cl_bpc =1 ;if (s->nr_cluster_groups >ocfs2_chain_recs_per_inode (s->blocksize)) {
Signature · 1 line
1.3.3
PATCH 5/6 Modify fsck to trust global bitmap than super block,take 1
In reply to Tao MaIn resize, we update the global_bitmap first and then the super block. So if there is any corruption between these 2 steps, there will be a inconsistence. In kernel we use the information in global_bitmap, so fsck.ocfs2 should also trust it during the check.
---
fsck.ocfs2/pass0.c | 25 ++++++++++++++++++------- 1 files changed, 18 insertions(+), 7 deletions(-)
aa2bfd78e72a1a60302a06775b09f9c014cd487f
fsck.ocfs2/pass0.c +18 -7
@@ -1075,19 +1075,30 @@ errcode_t o2fsck_pass0(o2fsck_state *ostif (ret) goto out; +/* +* during resize, we may update the global bitmap but fails to +* to update i_clusters in superblock, so ask the user which one +* to use before checking. +*/ +if (fs->fs_super->i_clusters != di->i_clusters) { +if (prompt (ost,PY ,PR_SUPERBLOCK_CLUSTERS , +"Superblock has clusters set to %u instead of %u " +"recorded in global_bitmap, it may be caused by an " +"unsuccessful resize. Trust global_bitmap?" , + fs->fs_super->i_clusters, di->i_clusters)) { + ost->ost_num_clusters = di->i_clusters; + fs->fs_clusters = di->i_clusters; + fs->fs_blocks =ocfs2_clusters_to_blocks (fs, + fs->fs_clusters); + } + } + ret =verify_bitmap_descs (ost, di, blocks + ost->ost_fs->fs_blocksize, blocks + (ost->ost_fs->fs_blocksize *2 ));if (ret) goto out; -if (fs->fs_super->i_clusters != di->i_clusters) { -if (prompt (ost,PY ,PR_SUPERBLOCK_CLUSTERS , -"Superblock has clusters set to %u instead of %u. Fix?" , - fs->fs_super->i_clusters, di->i_clusters)) - ost->ost_num_clusters = di->i_clusters; - } -printf ("Pass 0b: Checking inode allocation chains\n" );/* first the global inode alloc and then each of the node's
Signature · 1 line
1.3.3
PATCH 6/6 Add online resize in tunefs.ocfs2,take 1
In reply to Tao MaDuring online resize, we prepare all the new group descriptors in user space. For the update of global_bitmap, super block and all the backups, they are handled in the kernel.
---
libocfs2/include/ocfs2_fs.h | 4 + tunefs.ocfs2/resize.c | 255 ++++++++++++++++++++++++++++++++++++++++--- tunefs.ocfs2/tunefs.c | 53 ++++++++- tunefs.ocfs2/tunefs.h | 6 + 4 files changed, 295 insertions(+), 23 deletions(-)
60516ce8535f9cd6c9f36ace7056e5a24fab5e1b
libocfs2/include/ocfs2_fs.h +3 -1
@@ -27,7 +27,7 @@ #define _OCFS2_FS_H/* Version */ #define OCFS2_MAJOR_REV_LEVEL 0 -#define OCFS2_MINOR_REV_LEVEL 90 +#define OCFS2_MINOR_REV_LEVEL 91/* * An OCFS2 volume starts this way:
@@ -230,6 +230,8 @@ #define OCFS2_IOC_FREESP64 _IOW ('X', 37#define OCFS2_IOC_RESVSP64 _IOW ('X', 42, struct ocfs2_space_resv)#define OCFS2_IOC_UNRESVSP64 _IOW ('X', 43, struct ocfs2_space_resv) +#define OCFS2_IOC_FSGROWFSDATA _IOW ('X', 110, struct ocfs2_dinode) +/* * Journal Flags (ocfs2_dinode.id1.journal1.i_flags) */
tunefs.ocfs2/resize.c +240 -15
313 lines not on this page · raw message
tunefs.ocfs2/tunefs.c +47 -6
92 lines not on this page · raw message
tunefs.ocfs2/tunefs.h +5 -1
@@ -117,6 +117,10 @@ errcode_t feature_check(ocfs2_filesys *ferrcode_t update_feature (ocfs2_filesys *fs);void get_vol_size (ocfs2_filesys *fs); -errcode_t update_volume_size (ocfs2_filesys *fs,int *changed); +errcode_t update_volume_size (ocfs2_filesys *fs,int *changed,int online);int validate_vol_size (ocfs2_filesys *fs); + +errcode_t online_resize_check (ocfs2_filesys *fs); +errcode_t online_resize_lock (ocfs2_filesys *fs); +errcode_t online_resize_unlock (ocfs2_filesys *fs);#endif /* _TUNEFS_H */
Signature · 1 line
1.3.3
PATCH 6/6 Add online resize in tunefs.ocfs2, take 1
tunefs.ocfs2/resize.c line 65
Quoted 13 lines · Tao Ma
tunefs.ocfs2/resize.c +13
-0+static errcode_t find_mount_point (char *device) +{ +int mount_flags =0 ; +errcode_t ret; + +memset (mnt_dir,0 ,sizeof (mnt_dir)); + + ret =ocfs2_check_mount_point (device, &mount_flags, + mnt_dir,sizeof (mnt_dir)); +if (ret) + goto out; + + if ((!mount_flags & OCFS2_MF_MOUNTED) ||
if(!(mount_flags & OCFS2_MF_MOUNTED) ||
Quoted 10 lines
tunefs.ocfs2/resize.c +10
-0+ (mount_flags & OCFS2_MF_READONLY) || + (mount_flags & OCFS2_MF_SWAP)) { + ret =OCFS2_ET_BAD_DEVICE_NAME ; + goto out; + } + + ret =0 ; +out: +return ret; +}
PATCH 6/6 Add online resize in tunefs.ocfs2, take 1
Quoted 19 lines · Roel Kluin
Quoted 4 lines · Tao Ma
tunefs.ocfs2/resize.c +3
-0+static errcode_t find_mount_point (char *device) +{ +int mount_flags =0 ;tunefs.ocfs2/resize.c line 65
Quoted 10 lines
tunefs.ocfs2/resize.c +10
-0+errcode_t ret; + +memset (mnt_dir,0 ,sizeof (mnt_dir)); + + ret =ocfs2_check_mount_point (device, &mount_flags, + mnt_dir,sizeof (mnt_dir)); +if (ret) + goto out; + + if ((!mount_flags & OCFS2_MF_MOUNTED) ||if(!(mount_flags &
OCFS2_MF_MOUNTED) ||
Thanks for pointing it out.
Quoted 12 lines
Quoted 12 lines
tunefs.ocfs2/resize.c +10
-0+ (mount_flags & OCFS2_MF_READONLY) || + (mount_flags & OCFS2_MF_SWAP)) { + ret =OCFS2_ET_BAD_DEVICE_NAME ; + goto out; + } + + ret =0 ; +out: +return ret; +}
PATCH 6/6 Add online resize support in tunefs.ocfs2, take 2
In reply to Tao MaModification from V1 to V2:
1. Divide the whole process into 2 steps.
2. Fix a bug found by Roel Kluin <[email protected]>.
User can do offline resize using tunefs.ocfs2 when a volume isn't mounted. Now the support for online resize is added.
Please note that the node where online resize goes must already has the volume mounted. We don't mount it behind the user and the operation would fail if we find it isn't mounted. As for other nodes, we don't care whether the volume is mounted or not.
global_bitmap, super block and all the backups will be updated in the kernel. And if super block or backup's update fails, we just output some error message in dmesg and continue the work.
The whole process is derived from ext3 and divided into 2 steps:
1. OCFS2_IOC_GROUP_EXTEND: We will extend the last group first if it isn't full. All the work is done in kernel.
2. For every new group, call OCFS2_IOC_GROUP_ADD to add them one by one. We initialize the new group descriptor in userspace, and let the kernel update the global_bitap etc.
--- libocfs2/include/ocfs2_fs.h | 13 ++ tunefs.ocfs2/resize.c | 276 ++++++++++++++++++++++++++++++++++++++----- tunefs.ocfs2/tunefs.c | 53 ++++++++- tunefs.ocfs2/tunefs.h | 6 +- 4 files changed, 312 insertions(+), 36 deletions(-)
libocfs2/include/ocfs2_fs.h +13 -0
@@ -230,6 +230,19 @@ struct ocfs2_space_resv {#define OCFS2_IOC_RESVSP64 _IOW ('X', 42, struct ocfs2_space_resv)#define OCFS2_IOC_UNRESVSP64 _IOW ('X', 43, struct ocfs2_space_resv) +/* Used to pass group descriptor data when online resize is done */ +struct ocfs2_new_group_input { +__u64 group;/* Group descriptor's blkno. */ +__u32 clusters;/* Total number of clusters in this group */ +__u32 frees;/* Total free number of clusters in this group */ +__u16 chain;/* Chain for this group */ +__u16 reserved1; +__u32 reserved2; +}; + +#define OCFS2_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) +#define OCFS2_IOC_GROUP_ADD _IOW('f', 8,struct ocfs2_new_group_input) +/* * Journal Flags (ocfs2_dinode.id1.journal1.i_flags) */
tunefs.ocfs2/resize.c +247 -29
340 lines not on this page · raw message
tunefs.ocfs2/tunefs.c +47 -6
92 lines not on this page · raw message
tunefs.ocfs2/tunefs.h +5 -1
@@ -117,6 +117,10 @@ errcode_t feature_check(ocfs2_filesys *fs);errcode_t update_feature (ocfs2_filesys *fs);void get_vol_size (ocfs2_filesys *fs); -errcode_t update_volume_size (ocfs2_filesys *fs,int *changed); +errcode_t update_volume_size (ocfs2_filesys *fs,int *changed,int online);int validate_vol_size (ocfs2_filesys *fs); + +errcode_t online_resize_check (ocfs2_filesys *fs); +errcode_t online_resize_lock (ocfs2_filesys *fs); +errcode_t online_resize_unlock (ocfs2_filesys *fs);#endif /* _TUNEFS_H */
Signature · 1 line
gitgui.0.9.0.gd794