cluster: RHEL6 - gfs2_convert: use correct i_goal values instead of zeros for inodes
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=7933984ea9c...
Commit: 7933984ea9c3cd08e1a68a52f098f55b05ab0924
Parent: de32500c7e24d6da99c2653e9af4884e52c380d2
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Tue Dec 23 13:37:48 2014 -0600
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Dec 23 13:37:48 2014 -0600
gfs2_convert: use correct i_goal values instead of zeros for inodes
This patch sets the inode i_goal_data and i_goal_meta values to the
last allocated block for that inode instead of setting it to zero
as it did before.
Resolves: rhbz#1149516
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index bf3f49b..ec7f56c 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -652,8 +652,10 @@ static int fix_ind_reg_or_dir(struct gfs2_sbd *sbp, struct gfs2_inode *ip, uint3
mp_gfs1_to_gfs2(sbp, di_height, gfs2_hgt, &blk->mp, &gfs2mp);
memcpy(&blk->mp, &gfs2mp, sizeof(struct metapath));
blk->height -= di_height - gfs2_hgt;
- if (len)
+ if (len) {
fix_metatree(sbp, ip, blk, ptr1, len);
+ ip->i_di.di_goal_data = ip->i_di.di_goal_meta = be64_to_cpu(*ptr2);
+ }
return 0;
}
@@ -930,7 +932,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode->i_di.di_mode |= S_IFSOCK;
break;
}
-
+
/* ----------------------------------------------------------- */
/* gfs2 inodes are slightly different from gfs1 inodes in that */
/* di_goal_meta has shifted locations and di_goal_data has */
@@ -956,7 +958,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode->i_di.di_goal_data = 0; /* make sure the upper 32b are 0 */
inode->i_di.di_goal_data = gfs1_dinode_struct->di_goal_dblk;
inode->i_di.di_generation = 0;
-
+
if (adjust_indirect_blocks(sbp, inode))
return -1;
/* Check for cdpns */
@@ -972,7 +974,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
return -1;
}
}
-
+
bmodified(inode->i_bh);
inode_put(&inode); /* does gfs2_dinode_out if modified */
sbp->md.next_inum++; /* update inode count */
9 years, 4 months
cluster: RHEL6 - fsck.gfs2: fix broken i_goal values in inodes
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=de32500c7e2...
Commit: de32500c7e24d6da99c2653e9af4884e52c380d2
Parent: d8825398b6b75f988b86bec0b5a76aab45f16da5
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Tue Dec 23 13:36:15 2014 -0600
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Dec 23 13:36:15 2014 -0600
fsck.gfs2: fix broken i_goal values in inodes
This patch allows fsck.gfs2 to fix bad values for the i_goal
field in inodes that could arise from a gfs1->gfs2 conversion
or through other corruption
Resolves: rhbz#1149516
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/fsck/metawalk.c | 14 ++++++++++----
gfs2/fsck/metawalk.h | 3 +++
gfs2/fsck/pass1.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 79ee241..075c2e1 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1333,7 +1333,8 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
*/
static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
struct gfs2_buffer_head *bh, int head_size,
- uint64_t *blks_checked, uint64_t *error_blk)
+ uint64_t *last_block, uint64_t *blks_checked,
+ uint64_t *error_blk)
{
int error = 0, rc = 0;
uint64_t block, *ptr;
@@ -1348,7 +1349,7 @@ static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
if (skip_this_pass || fsck_abort)
return error;
- block = be64_to_cpu(*ptr);
+ *last_block = block = be64_to_cpu(*ptr);
/* It's important that we don't call valid_block() and
bypass calling check_data on invalid blocks because that
would defeat the rangecheck_block related functions in
@@ -1428,7 +1429,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
struct gfs2_buffer_head *bh;
uint32_t height = ip->i_di.di_height;
int i, head_size;
- uint64_t blks_checked = 0;
+ uint64_t blks_checked = 0, last_block = 0;
int error, rc;
int metadata_clean = 0;
uint64_t error_blk = 0;
@@ -1452,6 +1453,9 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
* comprise the directory hash table, so we perform the directory
* checks and exit. */
if (is_dir(&ip->i_di, ip->i_sbd->gfs1)) {
+ last_block = ip->i_di.di_num.no_addr;
+ if (pass->check_i_goal)
+ pass->check_i_goal(ip, last_block, pass->private);
if (!(ip->i_di.di_flags & GFS2_DIF_EXHASH))
goto out;
/* check validity of leaf blocks and leaf chains */
@@ -1478,7 +1482,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
if (pass->check_data)
error = check_data(ip, pass, bh, head_size,
- &blks_checked, &error_blk);
+ &last_block, &blks_checked, &error_blk);
if (pass->big_file_msg && ip->i_di.di_blocks > COMFORTABLE_BLKS)
pass->big_file_msg(ip, blks_checked);
@@ -1491,6 +1495,8 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
(unsigned long long)ip->i_di.di_num.no_addr);
fflush(stdout);
}
+ if (!error && pass->check_i_goal)
+ pass->check_i_goal(ip, last_block, pass->private);
undo_metalist:
if (!error)
goto out;
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 5e30bfe..d4ffc62 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -90,6 +90,7 @@ enum meta_check_rc {
* check_dentry:
* check_eattr_entry:
* check_eattr_extentry:
+ * check_i_goal:
*/
struct metawalk_fxns {
void *private;
@@ -140,6 +141,8 @@ struct metawalk_fxns {
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
+ int (*check_i_goal) (struct gfs2_inode *ip, uint64_t goal_blk,
+ void *private);
int (*finish_eattr_indir) (struct gfs2_inode *ip, int leaf_pointers,
int leaf_pointer_errors, void *private);
void (*big_file_msg) (struct gfs2_inode *ip, uint64_t blks_checked);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 7208335..9606101 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -60,6 +60,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
+static int check_i_goal(struct gfs2_inode *ip, uint64_t goal_blk, void *private);
static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
int leaf_pointer_errors, void *private);
static int invalidate_metadata(struct gfs2_inode *ip, uint64_t block,
@@ -97,6 +98,7 @@ struct metawalk_fxns pass1_fxns = {
.check_dentry = NULL,
.check_eattr_entry = check_eattr_entries,
.check_eattr_extentry = check_extended_leaf_eattr,
+ .check_i_goal = NULL,
.finish_eattr_indir = finish_eattr_indir,
.big_file_msg = big_file_comfort,
.repair_leaf = pass1_repair_leaf,
@@ -790,6 +792,48 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
return error;
}
+/**
+ * check_i_goal
+ * @ip
+ * @goal_blk: What the goal block should be for this inode
+ *
+ * The goal block for a regular file is typically the last
+ * data block of the file. If we can't get the right value,
+ * the inode metadata block is the next best thing.
+ *
+ * Returns: 0 if corrected, 1 if not corrected
+ */
+static int check_i_goal(struct gfs2_inode *ip, uint64_t goal_blk,
+ void *private)
+{
+ struct gfs2_sbd *sdp = ip->i_sbd;
+
+ if (fsck_system_inode(sdp, ip->i_di.di_num.no_addr))
+ return 0;
+ if (!goal_blk)
+ goal_blk = ip->i_di.di_num.no_addr;
+ if (ip->i_di.di_goal_meta != goal_blk ||
+ ip->i_di.di_goal_data != goal_blk) {
+ log_err( _("Error: inode %llu (0x%llx) has invalid "
+ "allocation goal block %llu (0x%llx). Should"
+ " be %llu (0x%llx)\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_goal_meta,
+ (unsigned long long)ip->i_di.di_goal_meta,
+ (unsigned long long)goal_blk,
+ (unsigned long long)goal_blk);
+ if (query( _("Fix the invalid goal block? (y/n) "))) {
+ ip->i_di.di_goal_meta = ip->i_di.di_goal_data = goal_blk;
+ bmodified(ip->i_bh);
+ } else {
+ log_err(_("Invalid goal block not fixed.\n"));
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private)
@@ -1464,6 +1508,9 @@ int pass1(struct gfs2_sbd *sdp)
/* Make sure the system inodes are okay & represented in the bitmap. */
check_system_inodes(sdp);
+ /* Turn the check_i_goal function ON for the non-system inodes */
+ pass1_fxns.check_i_goal = check_i_goal;
+
/* So, do we do a depth first search starting at the root
* inode, or use the rg bitmaps, or just read every fs block
* to find the inodes? If we use the depth first search, why
9 years, 4 months
gfs2-utils: master - tests: test for incorrect inode i_goal values
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=820f78aa...
Commit: 820f78aa19af31c25d1bcfd1d21de134026a56db
Parent: 6b567ac44bb8c9c2eab5267c0578d47c7188ba76
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Tue Dec 23 12:51:27 2014 -0600
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Dec 23 12:56:51 2014 -0600
tests: test for incorrect inode i_goal values
Test corresponds to the bug 1149516
Resolves: rhbz#1149516
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
tests/fsck.at | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/tests/fsck.at b/tests/fsck.at
index d7a8357..afe26db 100644
--- a/tests/fsck.at
+++ b/tests/fsck.at
@@ -8,3 +8,8 @@ GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 513 }
GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 4095 }])
GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 4097 }])
AT_CLEANUP
+
+AT_SETUP([Fix invalid goal blocks])
+GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set '/' { di_goal_meta: 0 }])
+GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set '/' { di_goal_data: 0 }])
+AT_CLEANUP
9 years, 4 months
gfs2-utils: RHEL7 - tests: test for incorrect inode i_goal values
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=c5b09c4f...
Commit: c5b09c4f957d9690807610c8b5e789a280132d2e
Parent: d79246d702623124595a008c732133e32cacba8e
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Tue Dec 23 12:51:27 2014 -0600
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Dec 23 12:51:27 2014 -0600
tests: test for incorrect inode i_goal values
Test corresponds to the bug 1149516
Resolves: rhbz#1149516
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
tests/fsck.at | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/tests/fsck.at b/tests/fsck.at
index d7a8357..afe26db 100644
--- a/tests/fsck.at
+++ b/tests/fsck.at
@@ -8,3 +8,8 @@ GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 513 }
GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 4095 }])
GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 4097 }])
AT_CLEANUP
+
+AT_SETUP([Fix invalid goal blocks])
+GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set '/' { di_goal_meta: 0 }])
+GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set '/' { di_goal_data: 0 }])
+AT_CLEANUP
9 years, 4 months
gfs2-utils: RHEL7 - gfs2_convert: use correct i_goal values instead of zeros for inodes
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=d79246d7...
Commit: d79246d702623124595a008c732133e32cacba8e
Parent: b09dae840a4e91e59cf73089da8e18bc0f299e80
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Mon Dec 8 18:21:47 2014 -0600
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Dec 23 11:24:49 2014 -0600
gfs2_convert: use correct i_goal values instead of zeros for inodes
This patch sets the inode i_goal_data and i_goal_meta values to the
last allocated block for that inode instead of setting it to zero
as it did before.
Resolves: rhbz#1149516
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 19a9839..0b56dd1 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -618,8 +618,10 @@ static int fix_ind_reg_or_dir(struct gfs2_sbd *sbp, struct gfs2_inode *ip, uint3
mp_gfs1_to_gfs2(sbp, di_height, gfs2_hgt, &blk->mp, &gfs2mp);
memcpy(&blk->mp, &gfs2mp, sizeof(struct metapath));
blk->height -= di_height - gfs2_hgt;
- if (len)
+ if (len) {
fix_metatree(sbp, ip, blk, ptr1, len);
+ ip->i_di.di_goal_data = ip->i_di.di_goal_meta = be64_to_cpu(*ptr2);
+ }
return 0;
}
@@ -903,7 +905,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode->i_di.di_mode |= S_IFSOCK;
break;
}
-
+
/* ----------------------------------------------------------- */
/* gfs2 inodes are slightly different from gfs1 inodes in that */
/* di_goal_meta has shifted locations and di_goal_data has */
@@ -929,7 +931,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode->i_di.di_goal_data = 0; /* make sure the upper 32b are 0 */
inode->i_di.di_goal_data = gfs1_dinode_struct->di_goal_dblk;
inode->i_di.di_generation = 0;
-
+
if (adjust_indirect_blocks(sbp, inode))
return -1;
/* Check for cdpns */
@@ -945,7 +947,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
return -1;
}
}
-
+
bmodified(inode->i_bh);
inode_put(&inode); /* does gfs2_dinode_out if modified */
sbp->md.next_inum++; /* update inode count */
9 years, 4 months
gfs2-utils: RHEL7 - fsck.gfs2: fix broken i_goal values in inodes
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=b09dae84...
Commit: b09dae840a4e91e59cf73089da8e18bc0f299e80
Parent: 33c48a55afa572b86de40364246d749a0e5d44e2
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Fri Dec 5 10:16:49 2014 -0600
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Tue Dec 23 11:24:37 2014 -0600
fsck.gfs2: fix broken i_goal values in inodes
This patch allows fsck.gfs2 to fix bad values for the i_goal
field in inodes that could arise from a gfs1->gfs2 conversion
or through other corruption
Resolves: rhbz#1149516
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/fsck/metawalk.c | 14 ++++++++++----
gfs2/fsck/metawalk.h | 3 +++
gfs2/fsck/pass1.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 329fc3b..9aa9fb8 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1395,7 +1395,8 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
*/
static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
struct gfs2_buffer_head *bh, int head_size,
- uint64_t *blks_checked, uint64_t *error_blk)
+ uint64_t *last_block, uint64_t *blks_checked,
+ uint64_t *error_blk)
{
int error = 0, rc = 0;
uint64_t block, *ptr;
@@ -1410,7 +1411,7 @@ static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
if (skip_this_pass || fsck_abort)
return error;
- block = be64_to_cpu(*ptr);
+ *last_block = block = be64_to_cpu(*ptr);
/* It's important that we don't call valid_block() and
bypass calling check_data on invalid blocks because that
would defeat the rangecheck_block related functions in
@@ -1490,7 +1491,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
struct gfs2_buffer_head *bh;
uint32_t height = ip->i_di.di_height;
int i, head_size;
- uint64_t blks_checked = 0;
+ uint64_t blks_checked = 0, last_block = 0;
int error, rc;
int metadata_clean = 0;
uint64_t error_blk = 0;
@@ -1514,6 +1515,9 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
* comprise the directory hash table, so we perform the directory
* checks and exit. */
if (is_dir(&ip->i_di, ip->i_sbd->gfs1)) {
+ last_block = ip->i_di.di_num.no_addr;
+ if (pass->check_i_goal)
+ pass->check_i_goal(ip, last_block, pass->private);
if (!(ip->i_di.di_flags & GFS2_DIF_EXHASH))
goto out;
/* check validity of leaf blocks and leaf chains */
@@ -1540,7 +1544,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
if (pass->check_data)
error = check_data(ip, pass, bh, head_size,
- &blks_checked, &error_blk);
+ &last_block, &blks_checked, &error_blk);
if (pass->big_file_msg && ip->i_di.di_blocks > COMFORTABLE_BLKS)
pass->big_file_msg(ip, blks_checked);
}
@@ -1552,6 +1556,8 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
(unsigned long long)ip->i_di.di_num.no_addr);
fflush(stdout);
}
+ if (!error && pass->check_i_goal)
+ pass->check_i_goal(ip, last_block, pass->private);
undo_metalist:
if (!error)
goto out;
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index a4e0676..b3c1299 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -90,6 +90,7 @@ enum meta_check_rc {
* check_dentry:
* check_eattr_entry:
* check_eattr_extentry:
+ * check_i_goal:
*/
struct metawalk_fxns {
void *private;
@@ -141,6 +142,8 @@ struct metawalk_fxns {
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
+ int (*check_i_goal) (struct gfs2_inode *ip, uint64_t goal_blk,
+ void *private);
int (*finish_eattr_indir) (struct gfs2_inode *ip, int leaf_pointers,
int leaf_pointer_errors, void *private);
void (*big_file_msg) (struct gfs2_inode *ip, uint64_t blks_checked);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 90ca357..60f0356 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -62,6 +62,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
+static int check_i_goal(struct gfs2_inode *ip, uint64_t goal_blk, void *private);
static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
int leaf_pointer_errors, void *private);
static int invalidate_metadata(struct gfs2_inode *ip, uint64_t block,
@@ -99,6 +100,7 @@ struct metawalk_fxns pass1_fxns = {
.check_dentry = NULL,
.check_eattr_entry = check_eattr_entries,
.check_eattr_extentry = check_extended_leaf_eattr,
+ .check_i_goal = NULL,
.finish_eattr_indir = finish_eattr_indir,
.big_file_msg = big_file_comfort,
.repair_leaf = pass1_repair_leaf,
@@ -792,6 +794,48 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
return error;
}
+/**
+ * check_i_goal
+ * @ip
+ * @goal_blk: What the goal block should be for this inode
+ *
+ * The goal block for a regular file is typically the last
+ * data block of the file. If we can't get the right value,
+ * the inode metadata block is the next best thing.
+ *
+ * Returns: 0 if corrected, 1 if not corrected
+ */
+static int check_i_goal(struct gfs2_inode *ip, uint64_t goal_blk,
+ void *private)
+{
+ struct gfs2_sbd *sdp = ip->i_sbd;
+
+ if (fsck_system_inode(sdp, ip->i_di.di_num.no_addr))
+ return 0;
+ if (!goal_blk)
+ goal_blk = ip->i_di.di_num.no_addr;
+ if (ip->i_di.di_goal_meta != goal_blk ||
+ ip->i_di.di_goal_data != goal_blk) {
+ log_err( _("Error: inode %llu (0x%llx) has invalid "
+ "allocation goal block %llu (0x%llx). Should"
+ " be %llu (0x%llx)\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_goal_meta,
+ (unsigned long long)ip->i_di.di_goal_meta,
+ (unsigned long long)goal_blk,
+ (unsigned long long)goal_blk);
+ if (query( _("Fix the invalid goal block? (y/n) "))) {
+ ip->i_di.di_goal_meta = ip->i_di.di_goal_data = goal_blk;
+ bmodified(ip->i_bh);
+ } else {
+ log_err(_("Invalid goal block not fixed.\n"));
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private)
@@ -1624,6 +1668,9 @@ int pass1(struct gfs2_sbd *sdp)
/* Make sure the system inodes are okay & represented in the bitmap. */
check_system_inodes(sdp);
+ /* Turn the check_i_goal function ON for the non-system inodes */
+ pass1_fxns.check_i_goal = check_i_goal;
+
/* So, do we do a depth first search starting at the root
* inode, or use the rg bitmaps, or just read every fs block
* to find the inodes? If we use the depth first search, why
9 years, 4 months
gfs2-utils: master - gfs2_convert: use correct i_goal values instead of zeros for inodes
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=6b567ac4...
Commit: 6b567ac44bb8c9c2eab5267c0578d47c7188ba76
Parent: 50364c4909aa2e66858a63c06407cfefd91c230c
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Mon Dec 8 18:21:47 2014 -0600
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Mon Dec 8 18:21:47 2014 -0600
gfs2_convert: use correct i_goal values instead of zeros for inodes
This patch sets the inode i_goal_data and i_goal_meta values to the
last allocated block for that inode instead of setting it to zero
as it did before.
Resolves: rhbz#1149516
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index a92ee80..9a42985 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -618,8 +618,10 @@ static int fix_ind_reg_or_dir(struct gfs2_sbd *sbp, struct gfs2_inode *ip, uint3
mp_gfs1_to_gfs2(sbp, di_height, gfs2_hgt, &blk->mp, &gfs2mp);
memcpy(&blk->mp, &gfs2mp, sizeof(struct metapath));
blk->height -= di_height - gfs2_hgt;
- if (len)
+ if (len) {
fix_metatree(sbp, ip, blk, ptr1, len);
+ ip->i_di.di_goal_data = ip->i_di.di_goal_meta = be64_to_cpu(*ptr2);
+ }
return 0;
}
@@ -903,7 +905,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode->i_di.di_mode |= S_IFSOCK;
break;
}
-
+
/* ----------------------------------------------------------- */
/* gfs2 inodes are slightly different from gfs1 inodes in that */
/* di_goal_meta has shifted locations and di_goal_data has */
@@ -929,7 +931,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
inode->i_di.di_goal_data = 0; /* make sure the upper 32b are 0 */
inode->i_di.di_goal_data = gfs1_dinode_struct->di_goal_dblk;
inode->i_di.di_generation = 0;
-
+
if (adjust_indirect_blocks(sbp, inode))
goto err_freei;
/* Check for cdpns */
@@ -945,7 +947,7 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
goto err_freei;
}
}
-
+
bmodified(inode->i_bh);
inode_put(&inode); /* does gfs2_dinode_out if modified */
sbp->md.next_inum++; /* update inode count */
9 years, 4 months
gfs2-utils: master - fsck.gfs2: fix broken i_goal values in inodes
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=50364c49...
Commit: 50364c4909aa2e66858a63c06407cfefd91c230c
Parent: a292875bcd3ac77252775c0ca46c930363b718a4
Author: Abhi Das <adas(a)redhat.com>
AuthorDate: Fri Dec 5 10:16:49 2014 -0600
Committer: Abhi Das <adas(a)redhat.com>
CommitterDate: Fri Dec 5 10:16:49 2014 -0600
fsck.gfs2: fix broken i_goal values in inodes
This patch allows fsck.gfs2 to fix bad values for the i_goal
field in inodes that could arise from a gfs1->gfs2 conversion
or through other corruption
Resolves: rhbz#1149516
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/fsck/metawalk.c | 14 ++++++++++----
gfs2/fsck/metawalk.h | 3 +++
gfs2/fsck/pass1.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 329fc3b..9aa9fb8 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1395,7 +1395,8 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
*/
static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
struct gfs2_buffer_head *bh, int head_size,
- uint64_t *blks_checked, uint64_t *error_blk)
+ uint64_t *last_block, uint64_t *blks_checked,
+ uint64_t *error_blk)
{
int error = 0, rc = 0;
uint64_t block, *ptr;
@@ -1410,7 +1411,7 @@ static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
if (skip_this_pass || fsck_abort)
return error;
- block = be64_to_cpu(*ptr);
+ *last_block = block = be64_to_cpu(*ptr);
/* It's important that we don't call valid_block() and
bypass calling check_data on invalid blocks because that
would defeat the rangecheck_block related functions in
@@ -1490,7 +1491,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
struct gfs2_buffer_head *bh;
uint32_t height = ip->i_di.di_height;
int i, head_size;
- uint64_t blks_checked = 0;
+ uint64_t blks_checked = 0, last_block = 0;
int error, rc;
int metadata_clean = 0;
uint64_t error_blk = 0;
@@ -1514,6 +1515,9 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
* comprise the directory hash table, so we perform the directory
* checks and exit. */
if (is_dir(&ip->i_di, ip->i_sbd->gfs1)) {
+ last_block = ip->i_di.di_num.no_addr;
+ if (pass->check_i_goal)
+ pass->check_i_goal(ip, last_block, pass->private);
if (!(ip->i_di.di_flags & GFS2_DIF_EXHASH))
goto out;
/* check validity of leaf blocks and leaf chains */
@@ -1540,7 +1544,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
if (pass->check_data)
error = check_data(ip, pass, bh, head_size,
- &blks_checked, &error_blk);
+ &last_block, &blks_checked, &error_blk);
if (pass->big_file_msg && ip->i_di.di_blocks > COMFORTABLE_BLKS)
pass->big_file_msg(ip, blks_checked);
}
@@ -1552,6 +1556,8 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
(unsigned long long)ip->i_di.di_num.no_addr);
fflush(stdout);
}
+ if (!error && pass->check_i_goal)
+ pass->check_i_goal(ip, last_block, pass->private);
undo_metalist:
if (!error)
goto out;
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index a4e0676..b3c1299 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -90,6 +90,7 @@ enum meta_check_rc {
* check_dentry:
* check_eattr_entry:
* check_eattr_extentry:
+ * check_i_goal:
*/
struct metawalk_fxns {
void *private;
@@ -141,6 +142,8 @@ struct metawalk_fxns {
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
+ int (*check_i_goal) (struct gfs2_inode *ip, uint64_t goal_blk,
+ void *private);
int (*finish_eattr_indir) (struct gfs2_inode *ip, int leaf_pointers,
int leaf_pointer_errors, void *private);
void (*big_file_msg) (struct gfs2_inode *ip, uint64_t blks_checked);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 90ca357..60f0356 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -62,6 +62,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
struct gfs2_ea_header *ea_hdr,
struct gfs2_ea_header *ea_hdr_prev,
void *private);
+static int check_i_goal(struct gfs2_inode *ip, uint64_t goal_blk, void *private);
static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
int leaf_pointer_errors, void *private);
static int invalidate_metadata(struct gfs2_inode *ip, uint64_t block,
@@ -99,6 +100,7 @@ struct metawalk_fxns pass1_fxns = {
.check_dentry = NULL,
.check_eattr_entry = check_eattr_entries,
.check_eattr_extentry = check_extended_leaf_eattr,
+ .check_i_goal = NULL,
.finish_eattr_indir = finish_eattr_indir,
.big_file_msg = big_file_comfort,
.repair_leaf = pass1_repair_leaf,
@@ -792,6 +794,48 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
return error;
}
+/**
+ * check_i_goal
+ * @ip
+ * @goal_blk: What the goal block should be for this inode
+ *
+ * The goal block for a regular file is typically the last
+ * data block of the file. If we can't get the right value,
+ * the inode metadata block is the next best thing.
+ *
+ * Returns: 0 if corrected, 1 if not corrected
+ */
+static int check_i_goal(struct gfs2_inode *ip, uint64_t goal_blk,
+ void *private)
+{
+ struct gfs2_sbd *sdp = ip->i_sbd;
+
+ if (fsck_system_inode(sdp, ip->i_di.di_num.no_addr))
+ return 0;
+ if (!goal_blk)
+ goal_blk = ip->i_di.di_num.no_addr;
+ if (ip->i_di.di_goal_meta != goal_blk ||
+ ip->i_di.di_goal_data != goal_blk) {
+ log_err( _("Error: inode %llu (0x%llx) has invalid "
+ "allocation goal block %llu (0x%llx). Should"
+ " be %llu (0x%llx)\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_goal_meta,
+ (unsigned long long)ip->i_di.di_goal_meta,
+ (unsigned long long)goal_blk,
+ (unsigned long long)goal_blk);
+ if (query( _("Fix the invalid goal block? (y/n) "))) {
+ ip->i_di.di_goal_meta = ip->i_di.di_goal_data = goal_blk;
+ bmodified(ip->i_bh);
+ } else {
+ log_err(_("Invalid goal block not fixed.\n"));
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
uint64_t parent, struct gfs2_buffer_head **bh,
void *private)
@@ -1624,6 +1668,9 @@ int pass1(struct gfs2_sbd *sdp)
/* Make sure the system inodes are okay & represented in the bitmap. */
check_system_inodes(sdp);
+ /* Turn the check_i_goal function ON for the non-system inodes */
+ pass1_fxns.check_i_goal = check_i_goal;
+
/* So, do we do a depth first search starting at the root
* inode, or use the rg bitmaps, or just read every fs block
* to find the inodes? If we use the depth first search, why
9 years, 4 months
fence-agents: master - [refactor] Function _get_opts_with_invalid_choices(...)
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=028f0b...
Commit: 028f0bba76b2171a3c25f5d755209ecb29c8053d
Parent: 17100edb3fe29f4992b225676bb4a32db7a53310
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Dec 15 16:19:34 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Dec 15 16:19:34 2014 +0100
[refactor] Function _get_opts_with_invalid_choices(...)
---
fence/agents/lib/fencing.py.py | 28 +++++++++++++++++-----------
1 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 41770a4..a8ea448 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1141,17 +1141,9 @@ def _validate_input(options):
options.has_key("--method") and options["--method"] == "cycle":
fail_usage("Failed: Cannot use --method cycle for more than 1 plug")
- for opt in device_opt:
- if all_opt[opt].has_key("choices"):
- longopt = "--" + all_opt[opt]["longopt"]
- possible_values_upper = [y.upper() for y in all_opt[opt]["choices"]]
- if options.has_key(longopt):
- options[longopt] = options[longopt].upper()
- if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper:
- fail_usage("Failed: You have to enter a valid choice " + \
- "for %s from the valid values: %s" % \
- ("--" + all_opt[opt]["longopt"], str(all_opt[opt]["choices"])))
-
+ for failed_opt in _get_opts_with_invalid_choices(options):
+ fail_usage("Failed: You have to enter a valid choice for %s from the valid values: %s" % \
+ ("--" + all_opt[failed_opt]["longopt"], str(all_opt[failed_opt]["choices"])))
def _encode_html_entities(text):
return text.replace("&", "&").replace('"', """).replace('<', "<"). \
@@ -1221,3 +1213,17 @@ def _join2(words, normal_separator=", ", last_separator=" and "):
return "".join(words)
else:
return last_separator.join([normal_separator.join(words[:-1]), words[-1]])
+
+def _get_opts_with_invalid_choices(options):
+ options_failed = []
+ device_opt = options["device_opt"]
+
+ for opt in device_opt:
+ if all_opt[opt].has_key("choices"):
+ longopt = "--" + all_opt[opt]["longopt"]
+ possible_values_upper = [y.upper() for y in all_opt[opt]["choices"]]
+ if options.has_key(longopt):
+ options[longopt] = options[longopt].upper()
+ if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper:
+ options_failed.append(opt)
+ return options_failed
9 years, 4 months
fence-agents: master - [refactor] Function _parse_input_cmdline(...)
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=17100e...
Commit: 17100edb3fe29f4992b225676bb4a32db7a53310
Parent: 321a214d48eebfe94d0923d5a08195621a8682bc
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Dec 8 16:59:36 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Dec 8 16:59:36 2014 +0100
[refactor] Function _parse_input_cmdline(...)
Simplify and remove code for adding also short names to final dict. This is no
longer needed and only long names are entered there.
---
fence/agents/lib/fencing.py.py | 23 ++++++++---------------
1 files changed, 8 insertions(+), 15 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 5449373..41770a4 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1206,21 +1206,14 @@ def _parse_input_cmdline(avail_opt):
except getopt.GetoptError, error:
fail_usage("Parse error: " + error.msg)
- ## Transform short getopt to long one which are used in fencing agents
- #####
- opt = {}
- for o in dict(entered_opt).keys():
- if o.startswith("--"):
- for x in all_opt.keys():
- if all_opt[x].has_key("longopt") and "--" + all_opt[x]["longopt"] == o:
- opt["--" + all_opt[x]["longopt"]] = dict(entered_opt)[o]
- else:
- for x in all_opt.keys():
- if x in avail_opt and all_opt[x].has_key("getopt") and all_opt[x].has_key("longopt") and \
- ("-" + all_opt[x]["getopt"] == o or "-" + all_opt[x]["getopt"].rstrip(":") == o):
- opt["--" + all_opt[x]["longopt"]] = dict(entered_opt)[o]
- opt[o] = dict(entered_opt)[o]
- return opt
+ # Short and long getopt names are changed to consistent "--" + long name (e.g. --username)
+ long_opts = {}
+ for arg_name in dict(entered_opt).keys():
+ all_key = [key for (key, value) in all_opt.items() \
+ if "--" + value.get("longopt", "") == arg_name or "-" + value.get("getopt", "").rstrip(":") == arg_name][0]
+ long_opts["--" + all_opt[all_key]["longopt"]] = dict(entered_opt)[arg_name]
+
+ return long_opts
# for ["John", "Mary", "Eli"] returns "John, Mary and Eli"
def _join2(words, normal_separator=", ", last_separator=" and "):
9 years, 4 months