Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=18…
Commit: 180b154c556288e8a3649fef9d830c7453a22437
Parent: b3279aedde9440e5fd006981542db2bc91f9d15b
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 17:19:25 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
fsck.gfs2: Journals not properly checked
The coverity tool found a problem with the previous set of patches that
led me to discover a problem with how journals were being processed
under the new code. The problem was that the journal index was read
in after journal replay. But journal replay relies upon information
in the jindex. This patch rearranges the initializeation sequence
of fsck.gfs2 so that the journal index and rindex are read in and
processed prior to journal recovery.
rhbz#675723
---
gfs2/fsck/fs_recovery.c | 12 ---
gfs2/fsck/initialize.c | 183 +++++++++++++++++++++++++++++++----------------
2 files changed, 122 insertions(+), 73 deletions(-)
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index d3c742a..52303dd 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -572,14 +572,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
*clean_journals = 0;
sdp->jsize = GFS2_DEFAULT_JSIZE;
- /* Get master dinode */
- gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
-
- /* read in the journal index data */
- if (ji_update(sdp)){
- log_err( _("Unable to read in jindex inode.\n"));
- return -1;
- }
for(i = 0; i < sdp->md.journals; i++) {
if (!sdp->md.journal[i]) {
@@ -608,11 +600,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
}
*clean_journals += clean;
}
- inode_put(&sdp->md.journal[i]);
}
- inode_put(&sdp->md.jiinode);
- free(sdp->md.journal);
- sdp->md.journal = NULL;
/* Sync the buffers to disk so we get a fresh start. */
fsync(sdp->device_fd);
return error;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 95a6a65..608eb32 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -477,18 +477,13 @@ static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild)
}
/**
- * init_system_inodes
- *
- * Returns: 0 on success, -1 on failure
+ * fetch_rgrps - fetch the resource groups from disk, and check their integrity
*/
-static int init_system_inodes(struct gfs2_sbd *sdp)
+static int fetch_rgrps(struct gfs2_sbd *sdp)
{
- uint64_t inumbuf;
- char *buf;
- struct gfs2_statfs_change sc;
- int rgcount, sane = 1, err = 0;
enum rgindex_trust_level trust_lvl;
- uint64_t addl_mem_needed;
+ int rgcount, sane = 1;
+
const char *level_desc[] = {
_("Checking if all rgrp and rindex values are good"),
_("Checking if rindex values may be easily repaired"),
@@ -503,48 +498,6 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
_("Too many rgrp misses: rgrps must be unevenly spaced"),
_("Too much damage found: we cannot rebuild this rindex"),
};
-
- /*******************************************************************
- ****************** Initialize important inodes ******************
- *******************************************************************/
-
- log_info( _("Initializing special inodes...\n"));
-
- /* Get root dinode */
- sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
-
- if (sdp->gfs1)
- sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
- else
- gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
- if (!sdp->md.riinode) {
- if (query( _("The gfs2 system rindex inode is missing. "
- "Okay to rebuild it? (y/n) ")))
- build_rindex(sdp);
- }
-
- /*******************************************************************
- ****************** Fill in journal information ******************
- *******************************************************************/
-
- /* rgrepair requires the journals be read in in order to distinguish
- "real" rgrps from rgrps that are just copies left in journals. */
- if (sdp->gfs1)
- sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
- else
- gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
- if (!sdp->md.jiinode) {
- if (query( _("The gfs2 system jindex inode is missing. "
- "Okay to rebuild it? (y/n) ")))
- build_jindex(sdp);
- }
-
- /* read in the ji data */
- if (ji_update(sdp)){
- log_err( _("Unable to read in jindex inode.\n"));
- return -1;
- }
-
/*******************************************************************
******** Validate and read in resource group information ********
*******************************************************************/
@@ -580,6 +533,34 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
log_info( _("%u resource groups found.\n"), rgcount);
check_rgrps_integrity(sdp);
+ return 0;
+}
+
+/**
+ * init_system_inodes
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int init_system_inodes(struct gfs2_sbd *sdp)
+{
+ uint64_t inumbuf = 0;
+ char *buf;
+ struct gfs2_statfs_change sc;
+ uint64_t addl_mem_needed;
+ int err;
+
+ /*******************************************************************
+ ****************** Initialize important inodes ******************
+ *******************************************************************/
+
+ log_info( _("Initializing special inodes...\n"));
+
+ /* Get root dinode */
+ sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
+
+ err = fetch_rgrps(sdp);
+ if (err)
+ return err;
/*******************************************************************
***************** Initialize more system inodes *****************
@@ -1232,8 +1213,6 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
log_info("Clearing journal %d\n", jnum);
for (seg = 0; seg < ji_nsegment; seg++){
- bh = bget(sdp, lh.lh_first * sdp->bsize);
- memset(bh->b_data, 0, sdp->bsize);
memset(&lh, 0, sizeof(struct gfs_log_header));
lh.lh_header.mh_magic = GFS2_MAGIC;
@@ -1245,6 +1224,8 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
(seg * sbd1->sb_seg_size);
lh.lh_sequence = sequence;
+ bh = bget(sdp, lh.lh_first * sdp->bsize);
+ memset(bh->b_data, 0, sdp->bsize);
gfs_log_header_out(&lh, bh->b_data);
gfs_log_header_out(&lh, bh->b_data + GFS2_BASIC_BLOCK -
sizeof(struct gfs_log_header));
@@ -1269,7 +1250,7 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
struct gfs_jindex ji;
char buf[sizeof(struct gfs_jindex)];
- log_err("Clearing GFS journals (this may take a while)");
+ log_err("Clearing GFS journals (this may take a while)\n");
for (i = 0; i < sdp->md.journals; i++) {
gfs2_readi(sdp->md.jiinode, buf, i * sizeof(struct gfs_jindex),
sizeof(struct gfs_jindex));
@@ -1284,6 +1265,81 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
}
/**
+ * init_rindex - read in the rindex file
+ */
+static int init_rindex(struct gfs2_sbd *sdp)
+{
+ int err;
+
+ if (sdp->gfs1)
+ sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
+ else
+ gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
+
+ if (sdp->md.riinode)
+ return 0;
+
+ if (!query( _("The gfs2 system rindex inode is missing. "
+ "Okay to rebuild it? (y/n) "))) {
+ log_crit(_("Error: Cannot proceed without a valid rindex.\n"));
+ return -1;
+ }
+ if ((err = build_rindex(sdp))) {
+ log_crit(_("Error %d rebuilding rindex\n"), err);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * init_jindex - read in the rindex file
+ */
+static int init_jindex(struct gfs2_sbd *sdp)
+{
+ /*******************************************************************
+ ****************** Fill in journal information ******************
+ *******************************************************************/
+
+ /* rgrepair requires the journals be read in in order to distinguish
+ "real" rgrps from rgrps that are just copies left in journals. */
+ if (sdp->gfs1)
+ sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
+ else
+ gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
+
+ if (!sdp->md.jiinode) {
+ int err;
+
+ if (!query( _("The gfs2 system jindex inode is missing. "
+ "Okay to rebuild it? (y/n) "))) {
+ log_crit(_("Error: cannot proceed without a valid "
+ "jindex file.\n"));
+ return -1;
+ }
+ /* In order to rebuild jindex, we need some valid
+ rgrps in memory. Temporarily read those in. */
+ err = fetch_rgrps(sdp);
+ if (err)
+ return err;
+
+ err = build_jindex(sdp);
+ /* Free rgrps read in earlier (re-read them later) */
+ gfs2_rgrp_free(&sdp->rgtree);
+ if (err) {
+ log_crit(_("Error %d rebuilding jindex\n"), err);
+ return err;
+ }
+ }
+
+ /* read in the ji data */
+ if (ji_update(sdp)){
+ log_err( _("Unable to read in jindex inode.\n"));
+ return -1;
+ }
+ return 0;
+}
+
+/**
* initialize - initialize superblock pointer
*
*/
@@ -1372,7 +1428,17 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
if (!sdp->gfs1)
lookup_per_node(sdp, 0);
- /* verify various things */
+ /* We need rindex first in case jindex is missing and needs to read
+ in the rgrps before rebuilding it. */
+ if (init_rindex(sdp))
+ return FSCK_ERROR;
+
+ /* We need to read in jindex in order to replay the journals */
+ if (init_jindex(sdp))
+ return FSCK_ERROR;
+
+ /* If GFS, rebuild the journals. If GFS2, replay them. We don't have
+ the smarts to replay GFS1 journals (neither did gfs_fsck). */
if (sdp->gfs1) {
if (reconstruct_journals(sdp))
@@ -1403,7 +1469,7 @@ mount_fail:
return FSCK_USAGE;
}
-static void destroy_sdp(struct gfs2_sbd *sdp)
+void destroy(struct gfs2_sbd *sdp)
{
if (!opts.no) {
if (block_mounters(sdp, 0)) {
@@ -1425,8 +1491,3 @@ static void destroy_sdp(struct gfs2_sbd *sdp)
"caches.\n"));
}
}
-
-void destroy(struct gfs2_sbd *sdp)
-{
- destroy_sdp(sdp);
-}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=c3…
Commit: c31b42c143250be89c6fc9817bf52d3293a28a05
Parent: 4768e3497c96f80f2776489ea5c65dba4dcd3681
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 17:01:57 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:28 2012 -0600
Change man pages and gfs2_convert messages to include GFS
Since fsck.gfs2 can now handle GFS1 file systems, this patch changes
the message in gfs2_convert and the man pages to reflect that.
rhbz#675723
---
gfs2/convert/gfs2_convert.c | 2 +-
gfs2/man/fsck.gfs2.8 | 9 +++++----
gfs2/man/gfs2_convert.8 | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 8ed2c1a..fa6461f 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1604,7 +1604,7 @@ static void give_warning(void)
printf("WARNING: This can't be undone. It is strongly advised " \
"that you:\n\n");
printf(" 1. Back up your entire filesystem first.\n");
- printf(" 2. Run gfs_fsck first to ensure filesystem integrity.\n");
+ printf(" 2. Run fsck.gfs2 first to ensure filesystem integrity.\n");
printf(" 3. Make sure the filesystem is NOT mounted from any node.\n");
printf(" 4. Make sure you have the latest software versions.\n");
}/* give_warning */
diff --git a/gfs2/man/fsck.gfs2.8 b/gfs2/man/fsck.gfs2.8
index 462e918..3ecfbe3 100644
--- a/gfs2/man/fsck.gfs2.8
+++ b/gfs2/man/fsck.gfs2.8
@@ -1,18 +1,19 @@
.TH fsck.gfs2 8
.SH NAME
-fsck.gfs2 - Offline GFS2 file system checker
+fsck.gfs2 - Offline GFS and GFS2 file system checker
.SH SYNOPSIS
.B fsck.gfs2
[\fIOPTION\fR]... \fIDEVICE\fR
.SH WARNING
-All GFS2 nodes \fImust\fP have the GFS2 filesystem unmounted before running
-fsck.gfs2. Failure to unmount all nodes may result in filesystem corruption.
+All computers \fImust\fP have the filesystem unmounted before running
+fsck.gfs2. Failure to unmount from all nodes in a cluster will likely result
+in filesystem corruption.
.SH DESCRIPTION
-fsck.gfs2 will check that the GFS2 file system on a device is structurally valid.
+fsck.gfs2 will check that the GFS or GFS2 file system on a device is structurally valid.
It should not be run on a mounted file system. If file system corruption is
detected, it will attempt to repair the file system. There is a limit to what
fsck.gfs2 can do. If important file system structures are destroyed, such that
diff --git a/gfs2/man/gfs2_convert.8 b/gfs2/man/gfs2_convert.8
index 5969432..ca0f64f 100644
--- a/gfs2/man/gfs2_convert.8
+++ b/gfs2/man/gfs2_convert.8
@@ -10,7 +10,7 @@ gfs2_convert - Convert a GFS1 filesystem to GFS2
.SH DESCRIPTION
gfs2_convert is used to convert a filesystem from GFS1 to GFS2. It is
required that the GFS1 filesystem be checked and fixed for errors using
-\fBgfs_fsck\fP and that the filesystem be backed up before
+\fBfsck.gfs2\fP and that the filesystem be backed up before
attempting to convert it. The convert process is irreversible and any
error encountered during the conversion can result in the abrupt
termination of the program and consequently an unusable filesystem.
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=16…
Commit: 165021e9be8503dd8ffc37edd2da71d1aa994df0
Parent: 0a25dd5b441e6743180e94100b241ed137bfda76
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 14:19:09 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Print step 2 duplicate debug msg first
In testing fsck.gfs2 I noticed that when duplicates were resolved,
the "step 2" debug message was printed after step 2 was actually
done. That's misleading, so this patch changes it.
rhbz#675723
---
gfs2/fsck/pass1b.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index da71f99..39c3289 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -642,15 +642,15 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
* directory inode referencing a data block as a leaf block.
*/
if (!last_reference) {
- last_reference = resolve_dup_references(sdp, b,
- &b->ref_inode_list,
- &dh, 0,
- acceptable_ref);
log_debug( _("----------------------------------------------\n"
"Step 2: Eliminate references to block %llu "
"(0x%llx) that need the wrong block type.\n"),
(unsigned long long)b->block,
(unsigned long long)b->block);
+ last_reference = resolve_dup_references(sdp, b,
+ &b->ref_inode_list,
+ &dh, 0,
+ acceptable_ref);
}
/* Step 3 - We have multiple dinodes referencing it as the correct
* type. Just blast one of them.
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=0a…
Commit: 0a25dd5b441e6743180e94100b241ed137bfda76
Parent: 9b917c047a4ceafc6b15994bdd5a9bd13120173b
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 14:16:59 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Recognize partially gfs2-converted dinodes
In testing fsck.gfs2 I noticed that if a file system had some
leftover gfs2 dinodes (due to an interrupted gfs2_convert or
in my case, because I had previously loaded gfs2 metadata that
left gfs2 blocks laying around the gfs1 file system) those gfs2
dinodes were not properly processed. In particular, it would not
recognize gfs2-style directories as directories because of the
difference in where dinode mode information is kept. This patch
gives fsck.gfs2 the ability to correctly identify gfs2 dinodes
when checking a gfs1 file system.
rhbz#675723
---
gfs2/fsck/lost_n_found.c | 4 ++--
gfs2/fsck/util.c | 2 +-
gfs2/fsck/util.h | 11 +++++++++--
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index c028f8d..16afb11 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -207,7 +207,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
lf_blocks = lf_dip->i_di.di_blocks;
if (sdp->gfs1)
- mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+ mode = gfs_to_gfs2_mode(ip);
else
mode = ip->i_di.di_mode & S_IFMT;
@@ -266,7 +266,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
incr_link_count(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
_("from lost+found"));
/* If it's a directory, lost+found is back-linked to it via .. */
- if (is_dir(&ip->i_di, sdp->gfs1))
+ if (mode == S_IFDIR)
incr_link_count(lf_dip->i_di.di_num.no_addr,
ip->i_di.di_num.no_addr, _("to lost+found"));
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 0be86de..92818fb 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -479,7 +479,7 @@ int set_ip_blockmap(struct gfs2_inode *ip, int instree)
uint32_t mode;
if (sdp->gfs1)
- mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+ mode = gfs_to_gfs2_mode(ip);
else
mode = ip->i_di.di_mode & S_IFMT;
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 6581cb1..2f74af3 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -143,8 +143,10 @@ static inline int is_dir(struct gfs2_dinode *dinode, int gfs1)
return 0;
}
-static inline uint32_t gfs_to_gfs2_mode(uint32_t gfs1mode)
+static inline uint32_t gfs_to_gfs2_mode(struct gfs2_inode *ip)
{
+ uint16_t gfs1mode = ip->i_di.__pad1;
+
switch (gfs1mode) {
case GFS_FILE_DIR:
return S_IFDIR;
@@ -161,7 +163,12 @@ static inline uint32_t gfs_to_gfs2_mode(uint32_t gfs1mode)
case GFS_FILE_SOCK:
return S_IFSOCK;
default:
- return S_IFREG;
+ /* This could be an aborted gfs2_convert so look for both. */
+ if (ip->i_di.di_entries ||
+ (ip->i_di.di_mode & S_IFMT) == S_IFDIR)
+ return S_IFDIR;
+ else
+ return S_IFREG;
}
}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=9b…
Commit: 9b917c047a4ceafc6b15994bdd5a9bd13120173b
Parent: e648de42ea46cccc0257e0bc5cb13cbeecf45a5f
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 14:14:29 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: system dinodes take priority over user dinodes
In testing fsck.gfs2 I noticed some incorrect behavior: If a block
was referenced incorrectly by two dinodes, fsck deleted which
ever reference it found first. Therefore, if a system dinode
and a user dinode referenced the same block, fsck.gfs2 could
mistakenly delete the system dinode. For example, a journal could
get deleted because a user dinode improperly referenced one of its
blocks. This patch gives priority to system dinodes when resolving
duplicates.
rhbz#675723
---
gfs2/fsck/pass1b.c | 9 ++++++++-
gfs2/fsck/util.c | 14 ++++++++++++--
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index b7be683..da71f99 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -483,7 +483,14 @@ static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
continue; /* don't delete the dinode */
}
}
-
+ /* If this reference is from a system inode, for example, if
+ it's data or metadata inside a journal, the reference
+ should take priority over user dinodes that reference the
+ block. */
+ if (!found_good_ref && fsck_system_inode(sdp, id->block_no)) {
+ found_good_ref = 1;
+ continue; /* don't delete the dinode */
+ }
log_warn( _("Inode %s (%lld/0x%llx) references block "
"%llu (0x%llx) as '%s', but the block is "
"really %s.\n"),
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 69bf328..0be86de 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -280,8 +280,18 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
inode reference list otherwise put it on the normal list. */
if (!inode_valid || q == gfs2_inode_invalid)
osi_list_add_prev(&id->list, &dt->ref_invinode_list);
- else
- osi_list_add_prev(&id->list, &dt->ref_inode_list);
+ else {
+ /* If this is a system dinode, we want the duplicate
+ processing to find it first. That way references
+ from inside journals, et al, will take priority.
+ We don't want to delete journals in favor of dinodes
+ that reference a block inside a journal. */
+ if (fsck_system_inode(ip->i_sbd, id->block_no))
+ osi_list_add(&id->list, &dt->ref_inode_list);
+ else
+ osi_list_add_prev(&id->list,
+ &dt->ref_inode_list);
+ }
}
id->reftypecount[reftype]++;
id->dup_count++;
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=18…
Commit: 180cde49a993e2bd32d4fc0664aad1b6703a6f41
Parent: 07afbc65f31ec524396cc5beb3ca421330e9bbaf
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 14:06:09 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Shorten debug output
This patch considerably shortens the debug output of fsck.gfs2 by
doing a few things. First, if fsck is just reporting the setting
of block types, it abbreviates the output by just listing other
blocks in parenthesis. Second, some of the key debug messages now give
only the block number in hexadecimal rather than both decimal and hex.
In one fsck.gfs2 run I did, it reduced the output from 32GB to 6.7GB.
rhbz#675723
---
gfs2/fsck/link.c | 38 ++++++++++++---------------
gfs2/fsck/metawalk.c | 69 ++++++++++++++++++++++++++++++++-----------------
gfs2/fsck/pass2.c | 6 ++--
3 files changed, 65 insertions(+), 48 deletions(-)
diff --git a/gfs2/fsck/link.c b/gfs2/fsck/link.c
index 18aeeb9..47365d8 100644
--- a/gfs2/fsck/link.c
+++ b/gfs2/fsck/link.c
@@ -35,22 +35,20 @@ int incr_link_count(uint64_t inode_no, uint64_t referenced_from,
struct inode_info *ii = NULL;
ii = inodetree_find(inode_no);
- /* If the list has entries, look for one that matches
- * inode_no */
+ /* If the list has entries, look for one that matches inode_no */
if (ii) {
ii->counted_links++;
- log_debug( _("Directory %lld (0x%llx) incremented counted "
- "links to %u for %"PRIu64" (0x%" PRIx64 ") "
- "via %s\n"),
+ log_debug( _("Dir (0x%llx) incremented counted "
+ "links to %u for (0x%llx) via %s\n"),
(unsigned long long)referenced_from,
- (unsigned long long)referenced_from,
- ii->counted_links, inode_no, inode_no, why);
+ ii->counted_links, (unsigned long long)inode_no,
+ why);
return 0;
}
- log_debug( _("Ref: %lld (0x%llx) No match found when incrementing "
- "link for %" PRIu64 " (0x%" PRIx64 ")!\n"),
+ log_debug( _("Ref: (0x%llx) No match found when incrementing "
+ "link for (0x%llx)!\n"),
(unsigned long long)referenced_from,
- (unsigned long long)referenced_from, inode_no, inode_no);
+ (unsigned long long)inode_no);
/* If no match was found, add a new entry and set its
* counted links to 1 */
ii = inodetree_insert(inode_no);
@@ -71,24 +69,22 @@ int decr_link_count(uint64_t inode_no, uint64_t referenced_from,
* inode_no */
if (ii) {
if (!ii->counted_links) {
- log_debug( _("Directory %lld (0x%llx)'s link to "
- " %"PRIu64" (0x%" PRIx64 ") via %s is zero!\n"),
- (unsigned long long)referenced_from,
+ log_debug( _("Dir (0x%llx)'s link to "
+ "(0x%llx) via %s is zero!\n"),
(unsigned long long)referenced_from,
- inode_no, inode_no, why);
+ (unsigned long long)inode_no, why);
return 0;
}
ii->counted_links--;
- log_debug( _("Directory %lld (0x%llx) decremented counted "
- "links to %u for %"PRIu64" (0x%" PRIx64 ") "
- "via %s\n"),
- (unsigned long long)referenced_from,
+ log_debug( _("Dir (0x%llx) decremented counted "
+ "links to %u for (0x%llx) via %s\n"),
(unsigned long long)referenced_from,
- ii->counted_links, inode_no, inode_no, why);
+ ii->counted_links, (unsigned long long)inode_no,
+ why);
return 0;
}
- log_debug( _("No match found when decrementing link for %" PRIu64
- " (0x%" PRIx64 ")!\n"), inode_no, inode_no);
+ log_debug( _("No match found when decrementing link for (0x%llx)!\n"),
+ (unsigned long long)inode_no);
return -1;
}
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index db7168b..6ddc936 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -107,36 +107,57 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
const char *caller, int fline)
{
int error;
+ static int prev_ino_addr = 0;
+ static enum gfs2_mark_block prev_mark = 0;
+ static int prevcount = 0;
if (print_level >= MSG_DEBUG) {
+ if ((ip->i_di.di_num.no_addr == prev_ino_addr) &&
+ (mark == prev_mark)) {
+ log_info("(0x%llx) ", (unsigned long long)bblock);
+ prevcount++;
+ if (prevcount > 10) {
+ log_info("\n");
+ prevcount = 0;
+ }
/* I'm circumventing the log levels here on purpose to make the
output easier to debug. */
- if (ip->i_di.di_num.no_addr == bblock) {
- print_fsck_log(MSG_DEBUG, caller, fline,
- _("%s inode found at block "
- "0x%llx: marking as '%s'\n"),
- btype, (unsigned long long)
- ip->i_di.di_num.no_addr,
- block_type_string(mark));
+ } else if (ip->i_di.di_num.no_addr == bblock) {
+ if (prevcount) {
+ log_info("\n");
+ prevcount = 0;
+ }
+ printf( _("(%s:%d) %s inode found at block "
+ "(0x%llx): marking as '%s'\n"), caller, fline,
+ btype,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ block_type_string(mark));
+
} else if (mark == gfs2_bad_block || mark == gfs2_meta_inval) {
- print_fsck_log(MSG_DEBUG, caller, fline,
- _("inode 0x%llx references "
- "%s block 0x%llx: "
- "marking as '%s'\n"),
- (unsigned long long)
- ip->i_di.di_num.no_addr,
- btype, (unsigned long long)bblock,
- block_type_string(mark));
+ if (prevcount) {
+ log_info("\n");
+ prevcount = 0;
+ }
+ printf( _("(%s:%d) inode (0x%llx) references %s block"
+ " (0x%llx): marking as '%s'\n"),
+ caller, fline,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ btype, (unsigned long long)bblock,
+ block_type_string(mark));
} else {
- print_fsck_log(MSG_DEBUG, caller, fline,
- _("inode 0x%llx references "
- "%s block 0x%llx: "
- "marking as '%s'\n"),
- (unsigned long long)
- ip->i_di.di_num.no_addr, btype,
- (unsigned long long)bblock,
- block_type_string(mark));
+ if (prevcount) {
+ log_info("\n");
+ prevcount = 0;
+ }
+ printf( _("(%s:%d) inode (0x%llx) references %s block"
+ " (0x%llx): marking as '%s'\n"),
+ caller, fline,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ btype, (unsigned long long)bblock,
+ block_type_string(mark));
}
+ prev_ino_addr = ip->i_di.di_num.no_addr;
+ prev_mark = mark;
}
/* First, check the rgrp bitmap against what we think it should be.
@@ -699,7 +720,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
if (!leaf.lf_next || error)
break;
leaf_no = leaf.lf_next;
- log_debug( _("Leaf chain 0x%llx detected.\n"),
+ log_debug( _("Leaf chain (0x%llx) detected.\n"),
(unsigned long long)leaf_no);
} while (1); /* while we have chained leaf blocks */
} /* for every leaf block */
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index e02fdd0..be0e5fe 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -69,7 +69,7 @@ static int set_dotdot_dir(struct gfs2_sbd *sdp, uint64_t childblock,
}
if (di->dinode != childblock) {
log_debug("'..' doesn't point to what we found: childblock "
- "0x%llx != dinode 0x%llx\n",
+ "(0x%llx) != dinode (0x%llx)\n",
(unsigned long long)childblock,
(unsigned long long)di->dinode);
return -1;
@@ -86,8 +86,8 @@ static int set_dotdot_dir(struct gfs2_sbd *sdp, uint64_t childblock,
(unsigned long long)di->dotdot_parent);
return -1;
}
- log_debug("Setting '..' for directory block 0x%llx to parent 0x%llx\n",
- (unsigned long long)childblock,
+ log_debug("Setting '..' for directory block (0x%llx) to parent "
+ "(0x%llx)\n", (unsigned long long)childblock,
(unsigned long long)parentblock);
di->dotdot_parent = parentblock;
return 0;
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=e6…
Commit: e648de42ea46cccc0257e0bc5cb13cbeecf45a5f
Parent: 180cde49a993e2bd32d4fc0664aad1b6703a6f41
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 14:11:11 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Increment link count reporting wrong dinode
The output from fsck.gfs2 was wrong when it reported about a
link count change for lost+found. This patch fixes the message
so it reports the correct dinode block number.
rhbz#675723
---
gfs2/fsck/lost_n_found.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index af4189f..c028f8d 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -268,7 +268,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
/* If it's a directory, lost+found is back-linked to it via .. */
if (is_dir(&ip->i_di, sdp->gfs1))
incr_link_count(lf_dip->i_di.di_num.no_addr,
- ip->i_di.di_mode, _("to lost+found"));
+ ip->i_di.di_num.no_addr, _("to lost+found"));
log_notice( _("Added inode #%llu (0x%llx) to lost+found\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=07…
Commit: 07afbc65f31ec524396cc5beb3ca421330e9bbaf
Parent: b9070aae3f60ade86055a44caef0e1dbe08a18f9
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Fri Jan 6 13:55:38 2012 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: Make rebuild functions not re-read ip
Before this patch, the libgfs2 rebuild functions in structures.c
were not consistent about reading in the gfs2_inode in-core struct.
Some of the functions did and some didn't. The previous patch to
make fsck.gfs2 operate on gfs1 introduced a problem because the code
was changed to re-read the inum and statfs files if they were rebuilt.
But since the functions already did the read, it was a double-read.
A double-read is a bad thing because inode writes are now done on
the last inode put, and the double-read messed up the counter.
(Number of inode gets should match puts). This patch makes all the
build functions consistent: they all put the inode after building,
except for root and master which have no parent inodes.
There was also a minor problem whereby leaf searches were getting
the number of entries from the directory buffer rather than from
the dinode itself. (The buffer may be out of date, but the dinode
should always be current). So there were circumstances where you
could add a new dirent to "master" but the count of entries was not
correct in the buffer, which caused the search to stop prematurely.
rhbz#675723
---
gfs2/convert/gfs2_convert.c | 3 +++
gfs2/fsck/initialize.c | 5 +++++
gfs2/libgfs2/fs_ops.c | 10 +++++-----
gfs2/libgfs2/structures.c | 4 ++--
gfs2/mkfs/main_mkfs.c | 2 ++
5 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 9cc3258..43d0093 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -2158,9 +2158,12 @@ int main(int argc, char **argv)
build_per_node(&sb2);
/* Create the empty inode number file */
build_inum(&sb2); /* Does not do inode_put */
+ gfs2_lookupi(sb2.master_dir, "inum", 4, &sb2.md.inum);
/* Create the statfs file */
build_statfs(&sb2); /* Does not do inode_put */
+ gfs2_lookupi(sb2.master_dir, "statfs", 6, &sb2.md.statfs);
+ do_init_statfs(&sb2);
/* Create the resource group index file */
build_rindex(&sb2);
/* Create the quota file */
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index cee1f49..75b363b 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -392,6 +392,7 @@ static int rebuild_master(struct gfs2_sbd *sdp)
IF2DT(S_IFREG | 0600));
} else {
build_inum(sdp);
+ gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
}
if (fix_md.statfs) {
@@ -401,6 +402,7 @@ static int rebuild_master(struct gfs2_sbd *sdp)
IF2DT(S_IFREG | 0600));
} else {
build_statfs(sdp);
+ gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
}
if (fix_md.riinode) {
@@ -422,6 +424,8 @@ static int rebuild_master(struct gfs2_sbd *sdp)
}
log_err(_("Master directory rebuilt.\n"));
+ inode_put(&sdp->md.inum);
+ inode_put(&sdp->md.statfs);
inode_put(&sdp->master_dir);
return 0;
}
@@ -635,6 +639,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
"a valid statfs file; aborting.\n"));
goto fail;
}
+ do_init_statfs(sdp);
}
buf = malloc(sdp->md.statfs->i_di.di_size);
// FIXME: handle failed malloc
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index e99cc2a..0163371 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -1243,6 +1243,7 @@ static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
dent->de_hash = cpu_to_be32(dent->de_hash);
dent->de_type = cpu_to_be16(type);
memcpy((char *)(dent + 1), filename, len);
+ bmodified(dip->i_bh);
}
void dir_add(struct gfs2_inode *dip, const char *filename, int len,
@@ -1437,10 +1438,9 @@ static int leaf_search(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
if (type == IS_LEAF){
struct gfs2_leaf *leaf = (struct gfs2_leaf *)bh->b_data;
entries = be16_to_cpu(leaf->lf_entries);
- } else if (type == IS_DINODE) {
- struct gfs2_dinode *dinode = (struct gfs2_dinode *)bh->b_data;
- entries = be32_to_cpu(dinode->di_entries);
- } else
+ } else if (type == IS_DINODE)
+ entries = dip->i_di.di_entries;
+ else
return -1;
hash = gfs2_disk_hash(filename, len);
@@ -1453,7 +1453,7 @@ static int leaf_search(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
if (be32_to_cpu(dent->de_hash) == hash &&
gfs2_filecmp(filename, (char *)(dent + 1),
- be16_to_cpu(dent->de_name_len))){
+ be16_to_cpu(dent->de_name_len))) {
*dent_out = dent;
if (dent_prev)
*dent_prev = prev;
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index f53b4af..b998f2d 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -284,7 +284,7 @@ int build_inum(struct gfs2_sbd *sdp)
gfs2_dinode_print(&ip->i_di);
}
- sdp->md.inum = ip;
+ inode_put(&ip);
return 0;
}
@@ -300,7 +300,7 @@ int build_statfs(struct gfs2_sbd *sdp)
gfs2_dinode_print(&ip->i_di);
}
- sdp->md.statfs = ip;
+ inode_put(&ip);
return 0;
}
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 3db3b14..ee2a5da 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -650,7 +650,9 @@ void main_mkfs(int argc, char *argv[])
build_jindex(sdp);
build_per_node(sdp);
build_inum(sdp);
+ gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
build_statfs(sdp);
+ gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
build_rindex(sdp);
build_quota(sdp);
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=a0…
Commit: a07ef06fdd7048154aee94e24a3972b582d4d85a
Parent: 94ada9a53b0c5bdf273c9801e2ffe1877356478d
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 17 10:33:07 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Remove bad inodes from duplicate tree
The problem was that if an inode was determined to be "bad" (lots of
corruption) and its metadata blocks were invalidated in pass1, the
"bad" block for the inode was set as "data" in the bitmap. Later,
that caused duplicate reference processing (pass1b) to not remove the
block from the inode tree inside function check_n_fix_bitmap when the
bad block was freed. Later still, in pass4, that caused the now
deleted inode to be processed again, at which time it would reprocess
the inode's metadata and free all blocks, including blocks that were
duplicate-referenced by other inodes. In other words, pass4 freed
blocks out from under valid references when it should not have. This
patch changes the bitmap type for "bad" blocks from "data" to
"inode". That causes function check_n_fix_bitmap to try to remove the
bad block from the inode tree, so pass4 never processes it by mistake.
This patch also changes a few debug messages to make them shorter so
that the output files aren't as big to search through.
rhbz#675723
---
gfs2/fsck/metawalk.c | 20 ++++++--------------
gfs2/fsck/pass1.c | 8 ++++++--
gfs2/fsck/util.h | 4 ++--
3 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 2ddf7dd..94b0148 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -113,36 +113,28 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
output easier to debug. */
if (ip->i_di.di_num.no_addr == bblock) {
print_fsck_log(MSG_DEBUG, caller, fline,
- _("%s inode found at block %lld "
- "(0x%llx): marking as '%s'\n"),
+ _("%s inode found at block "
+ "0x%llx: marking as '%s'\n"),
btype, (unsigned long long)
ip->i_di.di_num.no_addr,
- (unsigned long long)
- ip->i_di.di_num.no_addr,
block_type_string(mark));
} else if (mark == gfs2_bad_block || mark == gfs2_meta_inval) {
print_fsck_log(MSG_DEBUG, caller, fline,
- _("inode %lld (0x%llx) references "
- "%s block %lld (0x%llx): "
+ _("inode 0x%llx references "
+ "%s block 0x%llx: "
"marking as '%s'\n"),
(unsigned long long)
ip->i_di.di_num.no_addr,
- (unsigned long long)
- ip->i_di.di_num.no_addr,
btype, (unsigned long long)bblock,
- (unsigned long long)bblock,
block_type_string(mark));
} else {
print_fsck_log(MSG_DEBUG, caller, fline,
- _("inode %lld (0x%llx) references "
- "%s block %lld (0x%llx): "
+ _("inode 0x%llx references "
+ "%s block 0x%llx: "
"marking as '%s'\n"),
(unsigned long long)
- ip->i_di.di_num.no_addr,
- (unsigned long long)
ip->i_di.di_num.no_addr, btype,
(unsigned long long)bblock,
- (unsigned long long)bblock,
block_type_string(mark));
}
}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 876078e..515f50a 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -383,8 +383,12 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
*bh = NULL;
if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
+ /* The bad dinode should be invalidated later due to
+ "unrecoverable" errors. The inode itself should be
+ set "free" and removed from the inodetree by
+ undo_check_metalist. */
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
- _("itself"), gfs2_bad_block);
+ _("bad block referencing"), gfs2_bad_block);
log_debug( _("Bad indirect block (invalid/out of range) "
"found in inode %lld (0x%llx).\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
@@ -457,7 +461,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
- _("itself"), gfs2_block_free);
+ _("bad block referencing"), gfs2_block_free);
return 1;
}
if (is_dir(&ip->i_di, ip->i_sbd->gfs1) && h == ip->i_di.di_height)
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 9b2de61..fd75212 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -109,7 +109,7 @@ static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
GFS2_BLKST_UNLINKED, /* GFS unlinked metadata */
GFS2_BLKST_USED, /* eattribute */
- GFS2_BLKST_USED}, /* bad */
+ GFS2_BLKST_DINODE}, /* bad */
/* ---------------------- gfs1 ----------------------------- */
{GFS2_BLKST_FREE, /* free */
GFS2_BLKST_USED, /* data */
@@ -129,7 +129,7 @@ static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
GFS2_BLKST_UNLINKED, /* GFS unlinked metadata */
GFS2_BLKST_DINODE, /* eattribute */
- GFS2_BLKST_USED}}; /* bad */
+ GFS2_BLKST_DINODE}}; /* bad */
return bitmap_states[gfs1][m];
}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=7a…
Commit: 7a55740823bc98268dc7765eb99f365e42f4803b
Parent: 02714254368e71d63e1804e05a4534d564d5f5cb
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Aug 11 12:25:38 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: four-step duplicate elimination process
This patch reforms the duplicate block reference processing by
introducing a new four-step duplicate elimination process.
Step 1. Delete inodes that reference the block and were previously
marked invalid.
Step 2. Delete inodes that reference the block as the wrong block
type. (Data block referenced as metadata, or vise versa)
Step 3. Delete inodes until we're down to a single reference.
Step 4. Fix the block type to be according to the remaining reference.
rhbz#675723
---
gfs2/fsck/pass1b.c | 280 ++++++++++++++++++++++++++++++++++++----------------
1 files changed, 196 insertions(+), 84 deletions(-)
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 67b8d14..a66bd8b 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -13,6 +13,10 @@
#include "metawalk.h"
#include "inode_hash.h"
+const char *reftype_str[ref_types + 1] = {"data", "metadata",
+ "extended attribute",
+ "unimportant"};
+
struct fxn_info {
uint64_t block;
int found;
@@ -365,25 +369,38 @@ static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
return error;
}
+/* get_ref_type - figure out if all duplicate references from this inode
+ are the same type, and if so, return the type. */
+static enum dup_ref_type get_ref_type(struct inode_with_dups *id)
+{
+ if (id->reftypecount[ref_as_ea] &&
+ !id->reftypecount[ref_as_data] &&
+ !id->reftypecount[ref_as_meta])
+ return ref_as_ea;
+ if (!id->reftypecount[ref_as_ea] &&
+ id->reftypecount[ref_as_data] &&
+ !id->reftypecount[ref_as_meta])
+ return ref_as_data;
+ if (!id->reftypecount[ref_as_ea] &&
+ !id->reftypecount[ref_as_data] &&
+ id->reftypecount[ref_as_meta])
+ return ref_as_meta;
+ return ref_types; /* multiple references */
+}
+
static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
{
char reftypestring[32];
struct inode_with_dups *id;
id = osi_list_entry(tmp, struct inode_with_dups, list);
- if (id->dup_count == 1) {
- if (id->reftypecount[ref_as_data])
- strcpy(reftypestring, "as data");
- else if (id->reftypecount[ref_as_meta])
- strcpy(reftypestring, "as metadata");
- else
- strcpy(reftypestring, "as extended attribute");
- } else {
+ if (id->dup_count == 1)
+ sprintf(reftypestring, "as %s", reftype_str[get_ref_type(id)]);
+ else
sprintf(reftypestring, "%d/%d/%d",
id->reftypecount[ref_as_data],
id->reftypecount[ref_as_meta],
id->reftypecount[ref_as_ea]);
- }
if (inval)
log_warn( _("Invalid "));
log_warn( _("Inode %s (%lld/0x%llx) has %d reference(s) to "
@@ -393,10 +410,22 @@ static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
(unsigned long long)b->block,
(unsigned long long)b->block, reftypestring);
}
-
-static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
- osi_list_t *ref_list, struct dup_handler *dh,
- int inval)
+/*
+ * resolve_dup_references - resolve all but the last dinode that has a
+ * duplicate reference to a given block.
+ *
+ * @sdp - pointer to the superblock structure
+ * @b - pointer to the duplicate reference rbtree to use
+ * @ref_list - list of duplicate references to be resolved (invalid or valid)
+ * @dh - duplicate handler
+ * inval - The references on this ref_list are invalid. We prefer to delete
+ * these first before resorting to deleting valid dinodes.
+ * acceptable_ref - Delete dinodes that reference the given block as anything
+ * _but_ this type. Try to save references as this type.
+ */
+static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
+ osi_list_t *ref_list, struct dup_handler *dh,
+ int inval, int acceptable_ref)
{
struct gfs2_inode *ip;
struct inode_with_dups *id;
@@ -412,26 +441,74 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
.check_eattr_entry = clear_eattr_entry,
.check_eattr_extentry = clear_eattr_extentry,
};
+ enum dup_ref_type this_ref;
+ struct inode_info *ii;
+ int found_good_ref = 0;
osi_list_foreach_safe(tmp, ref_list, x) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
dh->b = b;
dh->id = id;
+
if (dh->ref_inode_count == 1) /* down to the last reference */
return 1;
- if (!(query( _("Okay to clear %s inode %lld (0x%llx)? (y/n) "),
+
+ this_ref = get_ref_type(id);
+ if (inval)
+ log_warn( _("Invalid "));
+ /* FIXME: If we already found an acceptable reference to this
+ * block, we should really duplicate the block and fix all
+ * references to it in this inode. Unfortunately, we would
+ * have to traverse the entire metadata tree to do that. */
+ if (acceptable_ref != ref_types && /* If we're nuking all but
+ an acceptable reference
+ type and */
+ this_ref == acceptable_ref && /* this ref is acceptable */
+ !found_good_ref) { /* We haven't found a good reference */
+ uint8_t q;
+
+ /* If this is an invalid inode, but not on the invalid
+ list, it's better to delete it. */
+ q = block_type(id->block_no);
+ if (q != gfs2_inode_invalid) {
+ found_good_ref = 1;
+ continue; /* don't delete the dinode */
+ }
+ }
+
+ log_warn( _("Inode %s (%lld/0x%llx) references block "
+ "%llu (0x%llx) as '%s', but the block is "
+ "really %s.\n"),
+ id->name, (unsigned long long)id->block_no,
+ (unsigned long long)id->block_no,
+ (unsigned long long)b->block,
+ (unsigned long long)b->block,
+ reftype_str[this_ref],
+ reftype_str[acceptable_ref]);
+ if (!(query( _("Okay to delete %s inode %lld (0x%llx)? "
+ "(y/n) "),
(inval ? _("invalidated") : ""),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no))) {
- log_warn( _("The bad inode was not cleared...\n"));
+ log_warn( _("The bad inode was not cleared."));
+ /* delete the list entry so we don't leak memory but
+ leave the reference count. If the decrement the
+ ref count, we could get down to 1 and the dinode
+ would be changed without a 'Yes' answer. */
+ /* (dh->ref_inode_count)--;*/
+ dup_listent_delete(id);
continue;
}
log_warn( _("Clearing inode %lld (0x%llx)...\n"),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no);
+
+ ip = fsck_load_inode(sdp, id->block_no);
+ ii = inodetree_find(ip->i_di.di_num.no_addr);
+ if (ii)
+ inodetree_delete(ii);
clear_dup_fxns.private = (void *) dh;
/* Clear the EAs for the inode first */
- ip = fsck_load_inode(sdp, id->block_no);
check_inode_eattr(ip, &clear_dup_fxns);
/* If the dup wasn't only in the EA, clear the inode */
if (id->reftypecount[ref_as_data] ||
@@ -439,13 +516,14 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
check_metatree(ip, &clear_dup_fxns);
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
- _("bad"), gfs2_inode_invalid);
+ _("duplicate referencing bad"),
+ gfs2_inode_invalid);
fsck_inode_put(&ip); /* out, brelse, free */
(dh->ref_inode_count)--;
- /* Inode is marked invalid and is removed in pass2 */
/* FIXME: other option should be to duplicate the
* block for each duplicate and point the metadata at
* the cloned blocks */
+ dup_listent_delete(id);
}
if (dh->ref_inode_count == 1) /* down to the last reference */
return 1;
@@ -458,19 +536,56 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
osi_list_t *tmp;
struct inode_with_dups *id;
struct dup_handler dh = {0};
- int last_reference, ref_in_invalid_inode = 0;
+ int last_reference = 0;
+ struct gfs2_buffer_head *bh;
+ uint32_t cmagic, ctype;
+ enum dup_ref_type acceptable_ref;
+ /* Count the duplicate references, both valid and invalid */
osi_list_foreach(tmp, &b->ref_invinode_list) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
dh.ref_inode_count++;
dh.ref_count += id->dup_count;
- ref_in_invalid_inode = 1;
}
osi_list_foreach(tmp, &b->ref_inode_list) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
dh.ref_inode_count++;
dh.ref_count += id->dup_count;
}
+
+ /* Log the duplicate references */
+ log_notice( _("Block %llu (0x%llx) has %d inodes referencing it"
+ " for a total of %d duplicate references:\n"),
+ (unsigned long long)b->block, (unsigned long long)b->block,
+ dh.ref_inode_count, dh.ref_count);
+
+ osi_list_foreach(tmp, &b->ref_invinode_list)
+ log_inode_reference(b, tmp, 1);
+ osi_list_foreach(tmp, &b->ref_inode_list)
+ log_inode_reference(b, tmp, 0);
+
+ /* Figure out the block type to see if we can eliminate references
+ to a different type. In other words, if the duplicate block looks
+ like metadata, we can delete dinodes that reference it as data.
+ If the block doesn't look like metadata, we can eliminate any
+ references to it as metadata. Dinodes with such references are
+ clearly corrupt and need to be deleted.
+ And if we're left with a single reference, problem solved. */
+ bh = bread(sdp, b->block);
+ cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
+ ctype = ((struct gfs2_meta_header *)(bh->b_data))->mh_type;
+ brelse(bh);
+
+ if (be32_to_cpu(cmagic) == GFS2_MAGIC &&
+ (be32_to_cpu(ctype) == GFS2_METATYPE_EA ||
+ be32_to_cpu(ctype) == GFS2_METATYPE_ED))
+ acceptable_ref = ref_as_ea;
+ else if (be32_to_cpu(cmagic) == GFS2_MAGIC &&
+ be32_to_cpu(ctype) <= GFS2_METATYPE_QC)
+ acceptable_ref = ref_as_meta;
+ else
+ acceptable_ref = ref_as_data;
+
/* A single reference to the block implies a possible situation where
a data pointer points to a metadata block. In other words, the
duplicate reference in the file system is (1) Metadata block X and
@@ -484,75 +599,71 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
invalidated for other reasons, such as bad pointers. So we need to
make sure at this point that any inode deletes reverse out any
duplicate reference before we get to this point. */
- if (dh.ref_count == 1) {
- struct gfs2_buffer_head *bh;
- uint32_t cmagic;
-
- bh = bread(sdp, b->block);
- cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
- brelse(bh);
- if (be32_to_cpu(cmagic) == GFS2_MAGIC) {
- if (ref_in_invalid_inode)
- tmp = b->ref_invinode_list.next;
- else
- tmp = b->ref_inode_list.next;
- id = osi_list_entry(tmp, struct inode_with_dups, list);
- log_warn( _("Inode %s (%lld/0x%llx) has a reference to"
- " data block %llu (0x%llx), "
- "but the block is really metadata.\n"),
- id->name, (unsigned long long)id->block_no,
- (unsigned long long)id->block_no,
- (unsigned long long)b->block,
- (unsigned long long)b->block);
- if (query( _("Clear the inode? (y/n) "))) {
- struct inode_info *ii;
-
- log_warn( _("Clearing inode %lld (0x%llx)...\n"),
- (unsigned long long)id->block_no,
- (unsigned long long)id->block_no);
- ip = fsck_load_inode(sdp, id->block_no);
- ii = inodetree_find(ip->i_di.di_num.no_addr);
- if (ii)
- inodetree_delete(ii);
- /* Setting the block to invalid means the inode
- is cleared in pass2 */
- fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
- _("inode with bad duplicate"),
- gfs2_inode_invalid);
- fsck_inode_put(&ip);
- } else {
- log_warn( _("The bad inode was not cleared."));
- }
- return 0;
- }
- /* The other references may have been discredited due to
- invalid metadata or something. Use the last remaining. */
- log_notice( _("Block %llu (0x%llx) has only one remaining "
- "reference.\n"),
+ if (dh.ref_count == 1)
+ last_reference = 1;
+
+ /* Step 1 - eliminate references from inodes that are not valid.
+ * This may be because they were deleted due to corruption.
+ * All block types are unacceptable, so we use ref_types.
+ */
+ if (!last_reference) {
+ log_debug( _("----------------------------------------------\n"
+ "Step 1: Eliminate references to block %llu "
+ "(0x%llx) that were previously marked "
+ "invalid.\n"),
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
+ last_reference = resolve_dup_references(sdp, b,
+ &b->ref_invinode_list,
+ &dh, 1, ref_types);
+ }
+ /* Step 2 - eliminate reference from inodes that reference it as the
+ * wrong type. For example, a data file referencing it as
+ * a data block, but it's really a metadata block. Or a
+ * directory inode referencing a data block as a leaf block.
+ */
+ if (!last_reference) {
+ last_reference = resolve_dup_references(sdp, b,
+ &b->ref_inode_list,
+ &dh, 0,
+ acceptable_ref);
+ log_debug( _("----------------------------------------------\n"
+ "Step 2: Eliminate references to block %llu "
+ "(0x%llx) that need the wrong block type.\n"),
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
+ }
+ /* Step 3 - We have multiple dinodes referencing it as the correct
+ * type. Just blast one of them.
+ * All block types are fair game, so we use ref_types.
+ */
+ if (!last_reference) {
+ log_debug( _("----------------------------------------------\n"
+ "Step 3: Choose one reference to block %llu "
+ "(0x%llx) to keep.\n"),
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
+ last_reference = resolve_dup_references(sdp, b,
+ &b->ref_inode_list,
+ &dh, 0, ref_types);
+ }
+ /* Now fix the block type of the block in question. */
+ if (osi_list_empty(&b->ref_inode_list)) {
+ log_notice( _("Block %llu (0x%llx) has no more references; "
+ "Marking as 'free'.\n"),
(unsigned long long)b->block,
(unsigned long long)b->block);
+ gfs2_blockmap_set(bl, b->block, gfs2_block_free);
+ check_n_fix_bitmap(sdp, b->block, gfs2_block_free);
return 0;
}
-
- log_notice( _("Block %llu (0x%llx) has %d inodes referencing it"
- " for a total of %d duplicate references\n"),
- (unsigned long long)b->block, (unsigned long long)b->block,
- dh.ref_inode_count, dh.ref_count);
-
- osi_list_foreach(tmp, &b->ref_invinode_list)
- log_inode_reference(b, tmp, 1);
- osi_list_foreach(tmp, &b->ref_inode_list)
- log_inode_reference(b, tmp, 0);
-
- last_reference = clear_a_reference(sdp, b, &b->ref_invinode_list,
- &dh, 1);
- if (!last_reference)
- last_reference = clear_a_reference(sdp, b, &b->ref_inode_list,
- &dh, 0);
-
- if (last_reference && !osi_list_empty(&b->ref_inode_list)) {
+ if (last_reference) {
uint8_t q;
+ log_notice( _("Block %llu (0x%llx) has only one remaining "
+ "reference.\n"),
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
/* If we're down to a single reference (and not all references
deleted, which may be the case of an inode that has only
itself and a reference), we need to reset the block type
@@ -560,7 +671,8 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
in the list, not the structure's place holder. */
tmp = (&b->ref_inode_list)->next;
id = osi_list_entry(tmp, struct inode_with_dups, list);
- log_debug( _("Resetting the type based on the remaining "
+ log_debug( _("----------------------------------------------\n"
+ "Step 4. Set block type based on the remaining "
"reference in inode %lld (0x%llx).\n"),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no);
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=e4…
Commit: e411d72a57ee6b8e720db6e49c8de58a2b4d3501
Parent: acee2940261ea454b8f82fcc55827a3e97ad0049
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 10:33:49 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: Use dinode buffer to map gfs1 dinode blocks
When function gfs1_block_map found a block for a stuffed file it
wasn't returning the dinode buffer, it was returning the block as a
new buffer. The problem is, if changes are made to the block, they
will be overwritten by the dinode buffer when that is released.
The result is a fixed block that doesn't get fixed. This patch
changes the code to return the block properly like gfs2_block_map.
rhbz#675723
---
gfs2/libgfs2/gfs1.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 59eaa8d..2ace124 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -118,7 +118,10 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
mh.mh_format = GFS2_FORMAT_IN;
gfs2_meta_header_out(&mh, bh);
} else {
- bh = bread(sdp, *dblock);
+ if (*dblock == ip->i_di.di_num.no_addr)
+ bh = ip->i_bh;
+ else
+ bh = bread(sdp, *dblock);
}
}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=0b…
Commit: 0bb789dbabb6ada3d29dd476c520428d8c116c42
Parent: debfd10488695bc940bbb1cd88b2dc79e74064b3
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 15:51:34 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: don't free prev rgrp list repairing rgrps
In cases where fsck.gfs2 is trying to repair damaged resource groups or
rindex, it tries several levels of repair. Some of those levels build a
list of expected resource groups and check them against the actual ones,
and the previous list is freed before the next level is attempted.
However, in the case of minor damage, such as one bitmap block that was
overwritten, we can often repair the damage by reading in the resource
groups at the first level, then at the second level of repair (called
"ye_of_little_faith") use those values to compare against. This patch
allows the second level of repair to use the first level's list.
rhbz#675723
---
gfs2/fsck/rgrepair.c | 17 +++++++++++++----
1 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 52cc529..c01aaa6 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -780,12 +780,12 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
osi_list_t *exp, *act; /* expected, actual */
struct gfs2_rindex buf;
- /* Free previous incarnations in memory, if any. */
- gfs2_rgrp_free(&sdp->rglist);
-
if (trust_lvl == blind_faith)
return 0;
- else if (trust_lvl == ye_of_little_faith) { /* if rindex seems sane */
+ if (trust_lvl == ye_of_little_faith) { /* if rindex seems sane */
+ /* Don't free previous incarnations in memory, if any.
+ * We need them to copy in the next function:
+ * gfs2_rgrp_free(&sdp->rglist); */
if (!(*sane)) {
log_err(_("The rindex file does not meet our "
"expectations.\n"));
@@ -798,6 +798,9 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
return error;
}
} else if (trust_lvl == open_minded) { /* If we can't trust RG index */
+ /* Free previous incarnations in memory, if any. */
+ gfs2_rgrp_free(&sdp->rglist);
+
/* Calculate our own RG index for comparison */
error = gfs2_rindex_calculate(sdp, &expected_rglist,
&calc_rg_count);
@@ -807,6 +810,9 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
}
}
else if (trust_lvl == distrust) { /* If we can't trust RG index */
+ /* Free previous incarnations in memory, if any. */
+ gfs2_rgrp_free(&sdp->rglist);
+
error = gfs2_rindex_rebuild(sdp, &expected_rglist,
&calc_rg_count, 0);
if (error) {
@@ -817,6 +823,9 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
sdp->rgrps = calc_rg_count;
}
else if (trust_lvl == indignation) { /* If we can't trust anything */
+ /* Free previous incarnations in memory, if any. */
+ gfs2_rgrp_free(&sdp->rglist);
+
error = gfs2_rindex_rebuild(sdp, &expected_rglist,
&calc_rg_count, 1);
if (error) {
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=de…
Commit: debfd10488695bc940bbb1cd88b2dc79e74064b3
Parent: 32e3d16a69e12b19134557fde710d22d0560a356
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 15:29:35 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Add find_remove_dup, free_block_if_notdup
This patch adds a couple new functions to util.c: find_remove_dup
and free_block_if_notdup. This is a centralized function that
is used to remove a duplicate reference. Each reference needs to be
removed to determine when all duplicate references have been resolved.
The object is to get down to one reference, so we can set the proper
type based on the remaining reference. However, if the very last
reference is deleted as well, the block may be freed.
These functions present one consistent way to do all this rather than
before when the it wasn't very consistent and various bitmap
inaccuracies were sometimes left in the file system.
rhbz#675723
---
gfs2/fsck/metawalk.c | 64 ++++++++++++++++++++++++-------
gfs2/fsck/metawalk.h | 4 ++
gfs2/fsck/pass1.c | 34 +----------------
gfs2/fsck/util.c | 101 ++++++++++++++++++++++++++-----------------------
gfs2/fsck/util.h | 4 ++
5 files changed, 113 insertions(+), 94 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index a5de1c8..b25b40d 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -823,6 +823,54 @@ int delete_block(struct gfs2_inode *ip, uint64_t block,
}
/**
+ * find_remove_dup - find out if this is a duplicate ref. If so, remove it.
+ * Returns: 0 if not a duplicate reference, 1 if it is.
+ */
+int find_remove_dup(struct gfs2_inode *ip, uint64_t block, const char *btype)
+{
+ struct duptree *d;
+ struct inode_with_dups *id;
+
+ d = dupfind(block);
+ if (!d)
+ return 0;
+
+ /* remove the inode reference id structure for this reference. */
+ id = find_dup_ref_inode(d, ip);
+ if (!id)
+ return 0;
+
+ dup_listent_delete(id);
+ log_err( _("Removing duplicate status of block %llu (0x%llx) "
+ "referenced as %s by dinode %llu (0x%llx)\n"),
+ (unsigned long long)block, (unsigned long long)block,
+ btype, (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr);
+ d->refs--; /* one less reference */
+ if (d->refs == 1) {
+ log_info( _("This leaves only one reference: it's "
+ "no longer a duplicate.\n"));
+ dup_delete(d); /* not duplicate now */
+ } else
+ log_info( _("%d block reference(s) remain.\n"),
+ d->refs);
+ return 1; /* but the original ref still exists so do not free it. */
+}
+
+/**
+ * free_block_if_notdup - free blocks associated with an inode, but if it's a
+ * duplicate, just remove that designation instead.
+ * Returns: 0 if the block was freed, 1 if a duplicate reference was removed
+ */
+int free_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
+ const char *btype)
+{
+ if (!find_remove_dup(ip, block, btype))
+ fsck_blockmap_set(ip, block, btype, gfs2_block_free);
+ return 0;
+}
+
+/**
* delete_block_if_notdup - delete blocks associated with an inode
*
* Ignore blocks that are already marked free.
@@ -834,7 +882,6 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
const char *btype, void *private)
{
uint8_t q;
- struct duptree *d;
if (!valid_block(ip->i_sbd, block))
return -EFAULT;
@@ -849,20 +896,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)ip->i_di.di_num.no_addr);
return 0;
}
- d = dupfind(block);
- if (d) {
- log_info( _("Removing duplicate reference %d "
- "to block %lld (0x%llx).\n"), d->refs,
- (unsigned long long)block,
- (unsigned long long)block);
- d->refs--; /* one less reference */
- if (d->refs == 1) /* If down to the last reference */
- dup_delete(d); /* not duplicate now */
- return 1; /* but the original ref still exists
- so return (do not free it). */
- }
- fsck_blockmap_set(ip, block, btype, gfs2_block_free);
- return 0;
+ return free_block_if_notdup(ip, block, btype);
}
/**
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 7a8ae4c..719bbd9 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -35,6 +35,10 @@ extern void reprocess_inode(struct gfs2_inode *ip, const char *desc);
extern struct duptree *dupfind(uint64_t block);
extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
uint64_t block);
+extern int find_remove_dup(struct gfs2_inode *ip, uint64_t block,
+ const char *btype);
+extern int free_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
+ const char *btype);
#define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index f5ec37a..64220f0 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -438,7 +438,6 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, int h,
void *private)
{
- struct duptree *d;
int found_dup = 0, iblk_type;
struct gfs2_buffer_head *nbh;
struct block_count *bc = (struct block_count *)private;
@@ -455,20 +454,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
else
iblk_type = GFS2_METATYPE_IN;
- d = dupfind(block);
- if (d) {
- log_err( _("Reversing duplicate status of block %llu (0x%llx) "
- "referenced as metadata in indirect block for "
- "dinode %llu (0x%llx)\n"),
- (unsigned long long)block,
- (unsigned long long)block,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr);
- d->refs--; /* one less reference */
- if (d->refs == 1)
- dup_delete(d);
- found_dup = 1;
- }
+ found_dup = find_remove_dup(ip, block, _("Metadata"));
nbh = bread(ip->i_sbd, block);
if (gfs2_check_meta(nbh, iblk_type)) {
@@ -548,7 +534,6 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
static int undo_check_data(struct gfs2_inode *ip, uint64_t block,
void *private)
{
- struct duptree *d;
struct block_count *bc = (struct block_count *) private;
if (!valid_block(ip->i_sbd, block)) {
@@ -560,23 +545,8 @@ static int undo_check_data(struct gfs2_inode *ip, uint64_t block,
gfs2_block_free);
return 1;
}
- d = dupfind(block);
- if (d) {
- log_err( _("Reversing duplicate status of block %llu (0x%llx) "
- "referenced as data by dinode %llu (0x%llx)\n"),
- (unsigned long long)block,
- (unsigned long long)block,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr);
- d->refs--; /* one less reference */
- if (d->refs == 1)
- dup_delete(d);
- bc->data_count--;
- return 1;
- }
- fsck_blockmap_set(ip, block, _("data"), gfs2_block_free);
bc->data_count--;
- return 0;
+ return free_block_if_notdup(ip, block, _("data"));
}
static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc)
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 9930624..569f25a 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -185,6 +185,30 @@ static struct duptree *gfs2_dup_set(uint64_t dblock, int create)
return data;
}
+/**
+ * find_dup_ref_inode - find a duplicate reference inode entry for an inode
+ */
+struct inode_with_dups *find_dup_ref_inode(struct duptree *dt,
+ struct gfs2_inode *ip)
+{
+ osi_list_t *ref;
+ struct inode_with_dups *id;
+
+ osi_list_foreach(ref, &dt->ref_invinode_list) {
+ id = osi_list_entry(ref, struct inode_with_dups, list);
+
+ if (id->block_no == ip->i_di.di_num.no_addr)
+ return id;
+ }
+ osi_list_foreach(ref, &dt->ref_inode_list) {
+ id = osi_list_entry(ref, struct inode_with_dups, list);
+
+ if (id->block_no == ip->i_di.di_num.no_addr)
+ return id;
+ }
+ return NULL;
+}
+
/*
* add_duplicate_ref - Add a duplicate reference to the duplicates tree list
* A new element of the tree will be created as needed
@@ -193,15 +217,19 @@ static struct duptree *gfs2_dup_set(uint64_t dblock, int create)
* So we need to recreate the duplicate reference structure if it's not there.
* Later, in pass1b, it has to go back through the file system
* and figure out those original references in order to resolve them.
+ *
+ * first - if 1, we're being called from pass1b, in which case we're trying
+ * to find the first reference to this block. If 0, we're being
+ * called from pass1, which is the second reference, which determined
+ * it was a duplicate..
*/
int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
enum dup_ref_type reftype, int first, int inode_valid)
{
- osi_list_t *ref;
- struct inode_with_dups *id, *found_id;
+ struct inode_with_dups *id;
struct duptree *dt;
- if (!valid_block(ip->i_sbd, block) != 0)
+ if (!valid_block(ip->i_sbd, block))
return 0;
/* If this is not the first reference (i.e. all calls from pass1) we
need to create the duplicate reference. If this is pass1b, we want
@@ -221,65 +249,42 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
reference, we don't want to increment the reference count because
it's already accounted for. */
if (first) {
- if (!dt->first_ref_found) {
- dt->first_ref_found = 1;
- dups_found_first++; /* We found another first ref. */
- }
+ dt->first_ref_found = 1;
+ dups_found_first++; /* We found another first ref. */
} else {
dt->refs++;
}
- /* Check for a previous reference to this duplicate on the "invalid
- inode" reference list. */
- found_id = NULL;
- osi_list_foreach(ref, &dt->ref_invinode_list) {
- id = osi_list_entry(ref, struct inode_with_dups, list);
-
- if (id->block_no == ip->i_di.di_num.no_addr) {
- found_id = id;
- break;
- }
- }
- if (found_id == NULL) {
- osi_list_foreach(ref, &dt->ref_inode_list) {
- id = osi_list_entry(ref, struct inode_with_dups, list);
-
- if (id->block_no == ip->i_di.di_num.no_addr) {
- found_id = id;
- break;
- }
- }
- }
- if (found_id == NULL) {
+ /* Check for a previous reference to this duplicate */
+ id = find_dup_ref_inode(dt, ip);
+ if (id == NULL) {
/* Check for the inode on the invalid inode reference list. */
uint8_t q;
- if (!(found_id = malloc(sizeof(*found_id)))) {
+ if (!(id = malloc(sizeof(*id)))) {
log_crit( _("Unable to allocate "
"inode_with_dups structure\n"));
return -1;
}
- if (!(memset(found_id, 0, sizeof(*found_id)))) {
+ if (!(memset(id, 0, sizeof(*id)))) {
log_crit( _("Unable to zero inode_with_dups "
"structure\n"));
return -1;
}
- found_id->block_no = ip->i_di.di_num.no_addr;
+ id->block_no = ip->i_di.di_num.no_addr;
q = block_type(ip->i_di.di_num.no_addr);
/* If it's an invalid dinode, put it first on the invalid
inode reference list otherwise put it on the normal list. */
if (!inode_valid || q == gfs2_inode_invalid)
- osi_list_add_prev(&found_id->list,
- &dt->ref_invinode_list);
+ osi_list_add_prev(&id->list, &dt->ref_invinode_list);
else
- osi_list_add_prev(&found_id->list,
- &dt->ref_inode_list);
+ osi_list_add_prev(&id->list, &dt->ref_inode_list);
}
- found_id->reftypecount[reftype]++;
- found_id->dup_count++;
+ id->reftypecount[reftype]++;
+ id->dup_count++;
log_info( _("Found %d reference(s) to block %llu"
" (0x%llx) as %s in inode #%llu (0x%llx)\n"),
- found_id->dup_count, (unsigned long long)block,
+ id->dup_count, (unsigned long long)block,
(unsigned long long)block, reftypes[reftype],
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
@@ -343,6 +348,14 @@ struct dir_info *dirtree_find(uint64_t block)
return NULL;
}
+void dup_listent_delete(struct inode_with_dups *id)
+{
+ if (id->name)
+ free(id->name);
+ osi_list_del(&id->list);
+ free(id);
+}
+
void dup_delete(struct duptree *b)
{
struct inode_with_dups *id;
@@ -351,18 +364,12 @@ void dup_delete(struct duptree *b)
while (!osi_list_empty(&b->ref_invinode_list)) {
tmp = (&b->ref_invinode_list)->next;
id = osi_list_entry(tmp, struct inode_with_dups, list);
- if (id->name)
- free(id->name);
- osi_list_del(&id->list);
- free(id);
+ dup_listent_delete(id);
}
while (!osi_list_empty(&b->ref_inode_list)) {
tmp = (&b->ref_inode_list)->next;
id = osi_list_entry(tmp, struct inode_with_dups, list);
- if (id->name)
- free(id->name);
- osi_list_del(&id->list);
- free(id);
+ dup_listent_delete(id);
}
osi_erase(&b->node, &dup_blocks);
free(b);
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index d2c81db..56b83fe 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -15,6 +15,10 @@ void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked);
void warm_fuzzy_stuff(uint64_t block);
int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
enum dup_ref_type reftype, int first, int inode_valid);
+extern struct inode_with_dups *find_dup_ref_inode(struct duptree *dt,
+ struct gfs2_inode *ip);
+extern void dup_listent_delete(struct inode_with_dups *id);
+
extern const char *reftypes[3];
static inline uint8_t block_type(uint64_t bblock)
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=32…
Commit: 32e3d16a69e12b19134557fde710d22d0560a356
Parent: d44048a47efe1784bdcb3da3b995fc77259bebb7
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 14:22:12 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Don't use old_leaf if it was a duplicate
In function check_leaf_blks fsck.gfs2 keeps track of the current leaf
and the previous leaf. It can only check the number of pointers is
correct for the old leaf after it finds a new leaf block. However,
it was getting confused if the old leaf was a duplicate reference.
If the old leaf was a duplicate referenced by a different dinode, we
can't check the number of pointers because the number of pointers may
be for that other dinode's reference, not this one. The other dinode
referencing this leaf block may have the correct depth and this one
may not. This patch adds an extra check for the old leaf block being
a duplicate before checking the number of pointers.
rhbz#675723
---
gfs2/fsck/metawalk.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 9b68de8..a5de1c8 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -603,7 +603,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
struct gfs2_buffer_head *lbh;
int lindex;
struct gfs2_sbd *sdp = ip->i_sbd;
- int ref_count = 0;
+ int ref_count = 0, old_was_dup;
/* Find the first valid leaf pointer in range and use it as our "old"
leaf. That way, bad blocks at the beginning will be overwritten
@@ -631,7 +631,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
}
old_leaf = -1;
memset(&oldleaf, 0, sizeof(oldleaf));
- for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
+ old_was_dup = 0;
+ for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
if (fsck_abort)
break;
gfs2_get_leaf_nr(ip, lindex, &leaf_no);
@@ -650,7 +651,11 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
do {
if (fsck_abort)
return 0;
- if (pass->check_num_ptrs &&
+ /* If the old leaf was a duplicate referenced by a
+ previous dinode, we can't check the number of
+ pointers because the number of pointers may be for
+ that other dinode's reference, not this one. */
+ if (pass->check_num_ptrs && !old_was_dup &&
valid_block(ip->i_sbd, old_leaf)) {
error = pass->check_num_ptrs(ip, old_leaf,
&ref_count,
@@ -662,6 +667,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
error = check_leaf(ip, lindex, pass, &ref_count,
&leaf_no, old_leaf, &bad_leaf,
first_ok_leaf, &leaf, &oldleaf);
+ old_was_dup = (error == -EEXIST);
old_leaf = leaf_no;
memcpy(&oldleaf, &leaf, sizeof(oldleaf));
if (!leaf.lf_next || error)
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=43…
Commit: 43c29f0c0477427ccf065642a355045ebb95f4bb
Parent: 37a84a1d83dfb5b71cbf41cf5411caab8311e87a
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 13:01:05 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:26 2012 -0600
fsck.gfs2 pass2: Don't delete invalid inode metadata
In pass2, all metadata was deleted for inodes that were marked either
"bad" or "invalid" but that is wrong, and here is why:
Blocks marked "invalid" were invalidated due to duplicate block references.
Pass1b should have already taken care of deleting their metadata, so in pass2
we only need to delete the directory entries pointing to them. We delete the
metadata in pass1b because we need to eliminate the inode referencing the
duplicate-referenced block from the list of candidates to keep. So we have a
delete-as-we-go policy. Blocks marked "bad" need to have their entire
metadata tree deleted.
rhbz#675723
---
gfs2/fsck/pass2.c | 30 ++++++++++++++++++++++--------
1 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index bcd9355..5fe5454 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -315,6 +315,18 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
q = block_type(entryblock);
/* Get the status of the directory inode */
+ /**
+ * 1. Blocks marked "invalid" were invalidated due to duplicate
+ * block references. Pass1b should have already taken care of deleting
+ * their metadata, so here we only need to delete the directory entries
+ * pointing to them. We delete the metadata in pass1b because we need
+ * to eliminate the inode referencing the duplicate-referenced block
+ * from the list of candidates to keep. So we have a delete-as-we-go
+ * policy.
+ *
+ * 2. Blocks marked "bad" need to have their entire
+ * metadata tree deleted.
+ */
if (q == gfs2_inode_invalid || q == gfs2_bad_block) {
/* This entry's inode has bad blocks in it */
@@ -329,14 +341,16 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
goto dentry_is_valid;
}
- if (ip->i_di.di_num.no_addr == entryblock)
- entry_ip = ip;
- else
- entry_ip = fsck_load_inode(sdp, entryblock);
- check_inode_eattr(entry_ip, &pass2_fxns_delete);
- check_metatree(entry_ip, &pass2_fxns_delete);
- if (entry_ip != ip)
- fsck_inode_put(&entry_ip);
+ if (q == gfs2_bad_block) {
+ if (ip->i_di.di_num.no_addr == entryblock)
+ entry_ip = ip;
+ else
+ entry_ip = fsck_load_inode(sdp, entryblock);
+ check_inode_eattr(entry_ip, &pass2_fxns_delete);
+ check_metatree(entry_ip, &pass2_fxns_delete);
+ if (entry_ip != ip)
+ fsck_inode_put(&entry_ip);
+ }
fsck_blockmap_set(ip, entryblock,
_("bad directory entry"), gfs2_block_free);
log_err( _("Inode %lld (0x%llx) was deleted.\n"),
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=5a…
Commit: 5a677ee1d50a8545b72113d1873bbc78898d8531
Parent: aab0d6535dab2ce48aa20062f7005a7deb4ad773
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 11:38:18 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:26 2012 -0600
fsck.gfs2: Shorten output
This patch shortens some of the output of fsck.gfs2, thereby making
the output files smaller and more manageable.
rhbz#675723
---
gfs2/fsck/lost_n_found.c | 6 +++---
gfs2/fsck/metawalk.c | 7 ++++---
gfs2/fsck/pass5.c | 13 +++++++------
3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 7886625..0de4f8e 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -66,8 +66,8 @@ static void add_dotdot(struct gfs2_inode *ip)
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)di->dotdot_parent);
else
- log_debug(_("Couldn't find a valid \"..\" entry "
- "for orphan directory %lld (0x%llx)\n"),
+ log_debug(_("Couldn't find directory %lld (0x%llx) "
+ "in directory tree.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
}
@@ -206,7 +206,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
incr_link_count(lf_dip->i_di.di_num.no_addr,
ip->i_di.di_mode, _("to lost+found"));
- log_notice( _("Added inode #%llu (0x%llx) to lost+found dir\n"),
+ log_notice( _("Added inode #%llu (0x%llx) to lost+found\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
gfs2_dinode_out(&lf_dip->i_di, lf_dip->i_bh);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 9252aec..af27432 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -45,12 +45,13 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
const char *allocdesc[] = {"free space", "data", "unlinked",
"inode", "reserved"};
- log_err( _("Block %llu (0x%llx) seems to be %s, but is "
- "marked as %s in the bitmap.\n"),
+ /* Keep these messages as short as possible, or the output
+ gets to be huge and unmanageable. */
+ log_err( _("Block %llu (0x%llx) was '%s', should be %s.\n"),
(unsigned long long)blk, (unsigned long long)blk,
allocdesc[new_bitmap_state],
allocdesc[old_bitmap_state]);
- if (query( _("Okay to fix the bitmap? (y/n)"))) {
+ if (query( _("Fix the bitmap? (y/n)"))) {
/* If the new bitmap state is free (and therefore the
old state was not) we have to add to the free
space in the rgrp. If the old bitmap state was
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 1811e5a..028515b 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -79,8 +79,8 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
So we ignore it. */
if (rg_status == GFS2_BLKST_UNLINKED &&
block_status == GFS2_BLKST_FREE) {
- log_err( _("Unlinked inode block found at "
- "block %llu (0x%llx).\n"),
+ log_err( _("Unlinked inode found at block %llu "
+ "(0x%llx).\n"),
(unsigned long long)block,
(unsigned long long)block);
if (query(_("Do you want to fix the bitmap? (y/n) "))) {
@@ -109,16 +109,17 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
log_err( _("Ondisk status is %u (%s) but FSCK thinks it should be "),
rg_status, blockstatus[rg_status]);
log_err("%u (%s)\n", block_status, blockstatus[block_status]);
- log_err( _("Metadata type is %u (%s)\n"), q,
- block_type_string(q));
+ if (q) /* Don't print redundant "free" */
+ log_err( _("Metadata type is %u (%s)\n"), q,
+ block_type_string(q));
if (query(_("Fix bitmap for block %llu (0x%llx) ? (y/n) "),
(unsigned long long)block,
(unsigned long long)block)) {
if (gfs2_set_bitmap(sdp, block, block_status))
- log_err( _("Failed.\n"));
+ log_err( _("Repair failed.\n"));
else
- log_err( _("Succeeded.\n"));
+ log_err( _("Fixed.\n"));
} else
log_err( _("Bitmap at block %"PRIu64" (0x%" PRIx64
") left inconsistent\n"), block, block);
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=2b…
Commit: 2b9c1cfac56cef5bde3d9941bc5f21027c22b1c8
Parent: 95edb17a8a8312bc2e08c7ce8efc59b54bffda10
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Tue Aug 9 09:23:05 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:26 2012 -0600
fsck.gfs2: fsck.gfs2: Move check_num_ptrs from metawalk to pass1
This patch moves function check_num_ptrs from metawalk.c to pass1.c
and also its helper function fix_leaf_pointers. This function checks
that the number of pointers in a leaf block is a factor of 2, and sane.
This should only happen once, when leaf blocks are initially checked.
Previously it was wasting a lot of time doing this check from every pass.
rhbz#675723
---
gfs2/fsck/metawalk.c | 129 +++-------------------------------------------
gfs2/fsck/metawalk.h | 3 +
gfs2/fsck/pass1.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 148 insertions(+), 124 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index dd0b929..cf75164 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -464,123 +464,6 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
*leaf_no = old_leaf;
}
-/*
- * fix_leaf_pointers - fix a directory dinode that has a number of pointers
- * that is not a multiple of 2.
- * dip - the directory inode having the problem
- * lindex - the index of the leaf right after the problem (need to back up)
- * cur_numleafs - current (incorrect) number of instances of the leaf block
- * correct_numleafs - the correct number instances of the leaf block
- */
-static int fix_leaf_pointers(struct gfs2_inode *dip, int *lindex,
- int cur_numleafs, int correct_numleafs)
-{
- int count;
- char *ptrbuf;
- int start_lindex = *lindex - cur_numleafs; /* start of bad ptrs */
- int tot_num_ptrs = (1 << dip->i_di.di_depth) - start_lindex;
- int bufsize = tot_num_ptrs * sizeof(uint64_t);
- int off_by = cur_numleafs - correct_numleafs;
-
- ptrbuf = malloc(bufsize);
- if (!ptrbuf) {
- log_err( _("Error: Cannot allocate memory to fix the leaf "
- "pointers.\n"));
- return -1;
- }
- /* Read all the pointers, starting with the first bad one */
- count = gfs2_readi(dip, ptrbuf, start_lindex * sizeof(uint64_t),
- bufsize);
- if (count != bufsize) {
- log_err( _("Error: bad read while fixing leaf pointers.\n"));
- free(ptrbuf);
- return -1;
- }
-
- bufsize -= off_by * sizeof(uint64_t); /* We need to write fewer */
- /* Write the same pointers, but offset them so they fit within the
- smaller factor of 2. So if we have 12 pointers, write out only
- the last 8 of them. If we have 7, write the last 4, etc.
- We need to write these starting at the current lindex and adjust
- lindex accordingly. */
- count = gfs2_writei(dip, ptrbuf + (off_by * sizeof(uint64_t)),
- start_lindex * sizeof(uint64_t), bufsize);
- if (count != bufsize) {
- log_err( _("Error: bad read while fixing leaf pointers.\n"));
- free(ptrbuf);
- return -1;
- }
- /* Now zero out the hole left at the end */
- memset(ptrbuf, 0, off_by * sizeof(uint64_t));
- gfs2_writei(dip, ptrbuf, (start_lindex * sizeof(uint64_t)) +
- bufsize, off_by * sizeof(uint64_t));
- free(ptrbuf);
- *lindex -= off_by; /* adjust leaf index to account for the change */
- return 0;
-}
-
-/* check_num_ptrs - check a previously processed leaf's pointer count */
-static int check_num_ptrs(struct gfs2_inode *ip, uint64_t old_leaf,
- int *ref_count, int *exp_count, int *lindex,
- struct gfs2_leaf *oldleaf)
-{
- int factor = 0, divisor = *ref_count, multiple = 1, error = 0;
- struct gfs2_buffer_head *lbh;
-
- /* Check to see if the number of pointers we found is a power of 2.
- It needs to be and if it's not we need to fix it.*/
- while (divisor > 1) {
- factor++;
- divisor /= 2;
- multiple = multiple << 1;
- }
- if (*ref_count != multiple) {
- log_err( _("Directory #%llu (0x%llx) has an "
- "invalid number of pointers to "
- "leaf #%llu (0x%llx)\n\tFound: %u, "
- "which is not a factor of 2.\n"),
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)old_leaf,
- (unsigned long long)old_leaf, *ref_count);
- if (!query( _("Attempt to fix it? (y/n) "))) {
- log_err( _("Directory inode was not fixed.\n"));
- return 1;
- }
- error = fix_leaf_pointers(ip, lindex, *ref_count, multiple);
- if (error)
- return error;
- *ref_count = multiple;
- log_err( _("Directory inode was fixed.\n"));
- }
- /* Check to see if the counted number of leaf pointers is what we
- expect. */
- if (*ref_count != *exp_count) {
- log_err( _("Directory #%llu (0x%llx) has an "
- "incorrect number of pointers to "
- "leaf #%llu (0x%llx)\n\tFound: "
- "%u, Expected: %u\n"),
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)old_leaf,
- (unsigned long long)old_leaf, *ref_count, *exp_count);
- if (!query( _("Attempt to fix it? (y/n) "))) {
- log_err( _("Directory leaf was not fixed.\n"));
- return 1;
- }
- lbh = bread(ip->i_sbd, old_leaf);
- gfs2_leaf_in(oldleaf, lbh);
- log_err( _("Leaf depth was %d, changed to %d\n"),
- oldleaf->lf_depth, ip->i_di.di_depth - factor);
- oldleaf->lf_depth = ip->i_di.di_depth - factor;
- gfs2_leaf_out(oldleaf, lbh);
- brelse(lbh);
- *exp_count = *ref_count;
- log_err( _("Directory leaf was fixed.\n"));
- }
- return 0;
-}
-
/* Checks exhash directory entries */
static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
{
@@ -639,10 +522,14 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
}
do {
- if (!valid_block(ip->i_sbd, old_leaf) == 0) {
- error = check_num_ptrs(ip, old_leaf,
- &ref_count, &exp_count,
- &lindex, &oldleaf);
+ if (fsck_abort)
+ return 0;
+ if (pass->check_num_ptrs &&
+ valid_block(ip->i_sbd, old_leaf)) {
+ error = pass->check_num_ptrs(ip, old_leaf,
+ &ref_count,
+ &lindex,
+ &oldleaf);
if (error)
return error;
}
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index d705726..7a8ae4c 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -89,6 +89,9 @@ struct metawalk_fxns {
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);
+ int (*check_num_ptrs) (struct gfs2_inode *ip, uint64_t leafno,
+ int *ref_count, int *lindex,
+ struct gfs2_leaf *leaf);
};
#endif /* _METAWALK_H */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 271075c..26883d3 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -32,7 +32,7 @@ struct block_count {
uint64_t ea_count;
};
-static int leaf(struct gfs2_inode *ip, uint64_t block, void *private);
+static int check_leaf(struct gfs2_inode *ip, uint64_t block, void *private);
static int check_metalist(struct gfs2_inode *ip, uint64_t block,
struct gfs2_buffer_head **bh, int h, void *private);
static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
@@ -57,6 +57,8 @@ 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_num_ptrs(struct gfs2_inode *ip, uint64_t leafno,
+ int *ref_count, int *lindex, struct gfs2_leaf *leaf);
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,
@@ -77,7 +79,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
struct metawalk_fxns pass1_fxns = {
.private = NULL,
- .check_leaf = leaf,
+ .check_leaf = check_leaf,
.check_metalist = check_metalist,
.check_data = check_data,
.check_eattr_indir = check_eattr_indir,
@@ -87,6 +89,7 @@ struct metawalk_fxns pass1_fxns = {
.check_eattr_extentry = check_extended_leaf_eattr,
.finish_eattr_indir = finish_eattr_indir,
.big_file_msg = big_file_comfort,
+ .check_num_ptrs = check_num_ptrs,
};
struct metawalk_fxns undo_fxns = {
@@ -197,7 +200,138 @@ struct metawalk_fxns sysdir_fxns = {
.check_dentry = resuscitate_dentry,
};
-static int leaf(struct gfs2_inode *ip, uint64_t block, void *private)
+/*
+ * fix_leaf_pointers - fix a directory dinode that has a number of pointers
+ * that is not a multiple of 2.
+ * dip - the directory inode having the problem
+ * lindex - the index of the leaf right after the problem (need to back up)
+ * cur_numleafs - current (incorrect) number of instances of the leaf block
+ * correct_numleafs - the correct number instances of the leaf block
+ */
+static int fix_leaf_pointers(struct gfs2_inode *dip, int *lindex,
+ int cur_numleafs, int correct_numleafs)
+{
+ int count;
+ char *ptrbuf;
+ int start_lindex = *lindex - cur_numleafs; /* start of bad ptrs */
+ int tot_num_ptrs = (1 << dip->i_di.di_depth) - start_lindex;
+ int bufsize = tot_num_ptrs * sizeof(uint64_t);
+ int off_by = cur_numleafs - correct_numleafs;
+
+ ptrbuf = malloc(bufsize);
+ if (!ptrbuf) {
+ log_err( _("Error: Cannot allocate memory to fix the leaf "
+ "pointers.\n"));
+ return -1;
+ }
+ /* Read all the pointers, starting with the first bad one */
+ count = gfs2_readi(dip, ptrbuf, start_lindex * sizeof(uint64_t),
+ bufsize);
+ if (count != bufsize) {
+ log_err( _("Error: bad read while fixing leaf pointers.\n"));
+ free(ptrbuf);
+ return -1;
+ }
+
+ bufsize -= off_by * sizeof(uint64_t); /* We need to write fewer */
+ /* Write the same pointers, but offset them so they fit within the
+ smaller factor of 2. So if we have 12 pointers, write out only
+ the last 8 of them. If we have 7, write the last 4, etc.
+ We need to write these starting at the current lindex and adjust
+ lindex accordingly. */
+ count = gfs2_writei(dip, ptrbuf + (off_by * sizeof(uint64_t)),
+ start_lindex * sizeof(uint64_t), bufsize);
+ if (count != bufsize) {
+ log_err( _("Error: bad read while fixing leaf pointers.\n"));
+ free(ptrbuf);
+ return -1;
+ }
+ /* Now zero out the hole left at the end */
+ memset(ptrbuf, 0, off_by * sizeof(uint64_t));
+ gfs2_writei(dip, ptrbuf, (start_lindex * sizeof(uint64_t)) +
+ bufsize, off_by * sizeof(uint64_t));
+ free(ptrbuf);
+ *lindex -= off_by; /* adjust leaf index to account for the change */
+ return 0;
+}
+
+/**
+ * check_num_ptrs - check a previously processed leaf's pointer count in the
+ * hash table.
+ *
+ * The number of pointers in a directory hash table that point to any given
+ * leaf block should always be a factor of two. The difference between the
+ * leaf block's depth and the dinode's di_depth gives us the factor.
+ * This function makes sure the leaf follows the rules properly.
+ *
+ * ip - pointer to the in-core inode structure
+ * leafno - the leaf number we're operating on
+ * ref_count - the number of pointers to this leaf we actually counted.
+ * exp_count - the number of pointers to this leaf we expect based on
+ * ip depth minus leaf depth.
+ * lindex - leaf index number
+ * leaf - the leaf structure for the leaf block to check
+ */
+static int check_num_ptrs(struct gfs2_inode *ip, uint64_t leafno,
+ int *ref_count, int *lindex, struct gfs2_leaf *leaf)
+{
+ int factor = 0, divisor = *ref_count, multiple = 1, error = 0;
+ struct gfs2_buffer_head *lbh;
+ int exp_count;
+
+ /* Check to see if the number of pointers we found is a power of 2.
+ It needs to be and if it's not we need to fix it.*/
+ while (divisor > 1) {
+ factor++;
+ divisor /= 2;
+ multiple = multiple << 1;
+ }
+ if (*ref_count != multiple) {
+ log_err( _("Directory #%llu (0x%llx) has an invalid number of "
+ "pointers to leaf #%llu (0x%llx)\n\tFound: %u, "
+ "which is not a factor of 2.\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)leafno,
+ (unsigned long long)leafno, *ref_count);
+ if (!query( _("Attempt to fix it? (y/n) "))) {
+ log_err( _("Directory inode was not fixed.\n"));
+ return 1;
+ }
+ error = fix_leaf_pointers(ip, lindex, *ref_count, multiple);
+ if (error)
+ return error;
+ *ref_count = multiple;
+ log_err( _("Directory inode was fixed.\n"));
+ }
+ /* Check to see if the counted number of leaf pointers is what we
+ expect based on the leaf depth. */
+ exp_count = (1 << (ip->i_di.di_depth - leaf->lf_depth));
+ if (*ref_count != exp_count) {
+ log_err( _("Directory #%llu (0x%llx) has an incorrect number "
+ "of pointers to leaf #%llu (0x%llx)\n\tFound: "
+ "%u, Expected: %u\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)leafno,
+ (unsigned long long)leafno, *ref_count, exp_count);
+ if (!query( _("Attempt to fix it? (y/n) "))) {
+ log_err( _("Directory leaf was not fixed.\n"));
+ return 1;
+ }
+ lbh = bread(ip->i_sbd, leafno);
+ gfs2_leaf_in(leaf, lbh);
+ log_err( _("Leaf depth was %d, changed to %d\n"),
+ leaf->lf_depth, ip->i_di.di_depth - factor);
+ leaf->lf_depth = ip->i_di.di_depth - factor;
+ gfs2_leaf_out(leaf, lbh);
+ brelse(lbh);
+ log_err( _("Directory leaf was fixed.\n"));
+ }
+ return 0;
+}
+
+static int check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
{
struct block_count *bc = (struct block_count *) private;
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=01…
Commit: 01401b5167a5d2aa9b36a1dc4605ec07fca4db65
Parent: 1de5d9be1718dbf67ddb4e308b27f39d52415384
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Aug 8 16:20:14 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:26 2012 -0600
fsck.gfs2: fsck.gfs2: Don't stop invalidating blocks on invalid
When fsck found a duplicate reference to a block it invalidated the dinode's
metadata. But if it encountered an invalid block, for example, out of range,
the invalidating would stop. If we encounter a block that isn't valid, we
obviously can't invalidate it. However, if we return an error, all future
invalidating will stop for that dinode. That's wrong because we need it to
continue to invalidate the other valid blocks. If we don't do this, block
references that follow the bad one that are also referenced elsewhere
(duplicates) won't be flagged as such. As a result, they'll be freed when
this corrupt dinode is deleted, despite being used by another dinode as a
valid block. This patch makes it return a good return code so the invalidating
continues.
rhbz#675723
---
gfs2/fsck/pass1.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 49a8f4e..271075c 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -825,8 +825,15 @@ static int mark_block_invalid(struct gfs2_inode *ip, uint64_t block,
{
uint8_t q;
- if (!valid_block(ip->i_sbd, block) != 0)
- return -EFAULT;
+ /* If the block isn't valid, we obviously can't invalidate it.
+ * However, if we return an error, invalidating will stop, and
+ * we want it to continue to invalidate the valid blocks. If we
+ * don't do this, block references that follow that are also
+ * referenced elsewhere (duplicates) won't be flagged as such,
+ * and as a result, they'll be freed when this dinode is deleted,
+ * despite being used by another dinode as a valid block. */
+ if (!valid_block(ip->i_sbd, block))
+ return 0;
q = block_type(block);
if (q != gfs2_block_free) {
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=f5…
Commit: f5da0eb475b287a1bc4227b54c87083878490c72
Parent: 5cacd15160d57c57e76b6defdd701460c296b8c9
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Aug 8 14:47:49 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:26 2012 -0600
dirent_repair needs to mark the buffer as modified
This patch adds a call to bmodified to function dirent_repair. Without
setting the modified bit, directory repairs may be forgotten and never
written back to disk, leaving the damage in place.
rhbz#675723
---
gfs2/fsck/metawalk.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 888acec..94de22a 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -264,6 +264,7 @@ static int dirent_repair(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
de->de_rec_len = GFS2_DIRENT_SIZE(de->de_name_len);
}
gfs2_dirent_out(de, (char *)dent);
+ bmodified(bh);
return 0;
}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=2d…
Commit: 2dd1ef3d036b0958fcf3dee56945e5454fd7bdb0
Parent: f5da0eb475b287a1bc4227b54c87083878490c72
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Aug 8 15:16:01 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:26 2012 -0600
fsck.gfs2: fsck.gfs2: Ask to reclaim unlinked meta per-rgrp only
Before this patch, fsck.gfs2 would ask for every unlinked metadata bit
whether you wanted to reclaim it as free space. This patch makes it
ask only once per resource group, and reports which resource group
so that the user doesn't think it's stuck in an infinite loop.
rhbz#675723
---
gfs2/fsck/initialize.c | 16 ++++++++++++----
1 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 29e4560..08da24f 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -192,7 +192,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
int *this_rg_bad)
{
uint32_t rg_free, rg_reclaimed;
- int rgb, x, y, off, bytes_to_check, total_bytes_to_check;
+ int rgb, x, y, off, bytes_to_check, total_bytes_to_check, asked = 0;
unsigned int state;
rg_free = rg_reclaimed = 0;
@@ -231,9 +231,17 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
}
/* GFS2_BLKST_UNLINKED */
*this_rg_bad = 1;
- if (!(*fixit)) {
- if (query(_("Okay to reclaim unlinked "
- "inodes? (y/n)")))
+ if (!asked) {
+ char msg[256];
+
+ asked = 1;
+ sprintf(msg,
+ _("Okay to reclaim unlinked "
+ "inodes in resource group "
+ "%lld (0x%llx)? (y/n)"),
+ (unsigned long long)rgd->ri.ri_addr,
+ (unsigned long long)rgd->ri.ri_addr);
+ if (query("%s", msg))
*fixit = 1;
}
if (!(*fixit))
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=3b…
Commit: 3b05a9a1941731dbef64f9b5dd8cb7abe000bf89
Parent: 4d10b88a659c4e1004e63efe31021f9fec490b1a
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Aug 8 14:21:06 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:26 2012 -0600
fsck.gfs2: fsck.gfs2: Sync di_nlink adding links for lost+found
When adding a ".." entry to a directory newly linked to lost+found
fsck.gfs2 needs to update its di_nlink value to account for the new
link. If not, it can "correct" the di_nlink value to the wrong
value and not find the error until a second fsck.gfs2 is done.
This only happens in the rare case where there is no pre-existing
".." entry that may be reused to re-link to lost+found.
rhbz#675723
---
gfs2/fsck/lost_n_found.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 684792a..e5d7571 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -109,6 +109,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
dip = fsck_load_inode(sdp, di->dotdot_parent);
if (dip->i_di.di_nlink > 0) {
dip->i_di.di_nlink--;
+ set_di_nlink(dip); /* keep inode tree in sync */
log_debug(_("Decrementing its links to %d\n"),
dip->i_di.di_nlink);
bmodified(dip->i_bh);
@@ -119,6 +120,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
"Changing it to 0.\n"),
dip->i_di.di_nlink);
dip->i_di.di_nlink = 0;
+ set_di_nlink(dip); /* keep inode tree in sync */
bmodified(dip->i_bh);
}
fsck_inode_put(&dip);
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=fb…
Commit: fb034f744c3ff377641e266fbe08da3b90bbb67f
Parent: a361afc11b1e86d27ce1b48c9982a34b1e3f7a2e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jan 18 11:50:44 2012 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jan 18 11:50:44 2012 -0600
default to GPLv2+ for original files
Signed-off-by: David Teigland <teigland(a)redhat.com>
---
README.license | 16 ++++++++++++++++
dlm_controld/action.c | 2 +-
dlm_controld/config.c | 2 +-
dlm_controld/cpg.c | 2 +-
dlm_controld/crc.c | 2 +-
dlm_controld/deadlock.c | 2 +-
dlm_controld/dlm_controld.h | 2 +-
dlm_controld/dlm_daemon.h | 2 +-
dlm_controld/fence.c | 2 +-
dlm_controld/lib.c | 2 +-
dlm_controld/libdlmcontrol.h | 2 +-
dlm_controld/linux_endian.h | 2 +-
dlm_controld/logging.c | 2 +-
dlm_controld/main.c | 2 +-
dlm_controld/member.c | 2 +-
dlm_controld/netlink.c | 2 +-
dlm_controld/plock.c | 2 +-
dlm_tool/main.c | 2 +-
18 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/README.license b/README.license
new file mode 100644
index 0000000..ededf66
--- /dev/null
+++ b/README.license
@@ -0,0 +1,16 @@
+LGPLv2+
+
+libdlm/libdlm.c
+libdlm/libdlm.h
+libdlm/libdlm_internal.h
+
+GPLv2
+
+dlm_controld/list.h (copied from linux kernel)
+
+GPLv2+
+
+dlm_controld/rbtree.c (copied from linux kernel)
+dlm_controld/rbtree.h (copied from linux kernel)
+all other original files
+
diff --git a/dlm_controld/action.c b/dlm_controld/action.c
index f24eb20..ae3f6cd 100644
--- a/dlm_controld/action.c
+++ b/dlm_controld/action.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/config.c b/dlm_controld/config.c
index d909557..3bf02c0 100644
--- a/dlm_controld/config.c
+++ b/dlm_controld/config.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/cpg.c b/dlm_controld/cpg.c
index 4f0709c..f490cf5 100644
--- a/dlm_controld/cpg.c
+++ b/dlm_controld/cpg.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/crc.c b/dlm_controld/crc.c
index 1ac38d0..2b4b9c9 100644
--- a/dlm_controld/crc.c
+++ b/dlm_controld/crc.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/deadlock.c b/dlm_controld/deadlock.c
index 8d4b48f..51649d6 100644
--- a/dlm_controld/deadlock.c
+++ b/dlm_controld/deadlock.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/dlm_controld.h b/dlm_controld/dlm_controld.h
index 8d5826c..638b0de 100644
--- a/dlm_controld/dlm_controld.h
+++ b/dlm_controld/dlm_controld.h
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#ifndef __DLM_CONTROLD_DOT_H__
diff --git a/dlm_controld/dlm_daemon.h b/dlm_controld/dlm_daemon.h
index f013fd1..497e6e8 100644
--- a/dlm_controld/dlm_daemon.h
+++ b/dlm_controld/dlm_daemon.h
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#ifndef __DLM_DAEMON_DOT_H__
diff --git a/dlm_controld/fence.c b/dlm_controld/fence.c
index 738c97a..95a8bc1 100644
--- a/dlm_controld/fence.c
+++ b/dlm_controld/fence.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/lib.c b/dlm_controld/lib.c
index e682b69..09f84cf 100644
--- a/dlm_controld/lib.c
+++ b/dlm_controld/lib.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include <stdio.h>
diff --git a/dlm_controld/libdlmcontrol.h b/dlm_controld/libdlmcontrol.h
index 9ba809e..609372d 100644
--- a/dlm_controld/libdlmcontrol.h
+++ b/dlm_controld/libdlmcontrol.h
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#ifndef _LIBDLMCONTROL_H_
diff --git a/dlm_controld/linux_endian.h b/dlm_controld/linux_endian.h
index 244ea52..625bf72 100644
--- a/dlm_controld/linux_endian.h
+++ b/dlm_controld/linux_endian.h
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#ifndef __LINUX_ENDIAN_DOT_H__
diff --git a/dlm_controld/logging.c b/dlm_controld/logging.c
index 8fd6439..1f97df7 100644
--- a/dlm_controld/logging.c
+++ b/dlm_controld/logging.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/main.c b/dlm_controld/main.c
index 7355ae1..e0420b6 100644
--- a/dlm_controld/main.c
+++ b/dlm_controld/main.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#define EXTERN
diff --git a/dlm_controld/member.c b/dlm_controld/member.c
index b36985d..4a445c8 100644
--- a/dlm_controld/member.c
+++ b/dlm_controld/member.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/netlink.c b/dlm_controld/netlink.c
index 04ce2f1..0f996d6 100644
--- a/dlm_controld/netlink.c
+++ b/dlm_controld/netlink.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_controld/plock.c b/dlm_controld/plock.c
index 23e6a41..b6dc0a4 100644
--- a/dlm_controld/plock.c
+++ b/dlm_controld/plock.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include "dlm_daemon.h"
diff --git a/dlm_tool/main.c b/dlm_tool/main.c
index 8715439..c9a15db 100644
--- a/dlm_tool/main.c
+++ b/dlm_tool/main.c
@@ -3,7 +3,7 @@
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
+ * of the GNU General Public License v2 or (at your option) any later version.
*/
#include <unistd.h>
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=a3…
Commit: a361afc11b1e86d27ce1b48c9982a34b1e3f7a2e
Parent: 14b3794189606e6a39d73f810bdd94d3d20ef229
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jan 18 11:40:31 2012 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jan 18 11:40:31 2012 -0600
remove fsf address
shut up rpmlint
Signed-off-by: David Teigland <teigland(a)redhat.com>
---
dlm_controld/rbtree.c | 2 +-
dlm_controld/rbtree.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlm_controld/rbtree.c b/dlm_controld/rbtree.c
index 430ccc1..a1d78e7 100644
--- a/dlm_controld/rbtree.c
+++ b/dlm_controld/rbtree.c
@@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc.
linux/lib/rbtree.c
*/
diff --git a/dlm_controld/rbtree.h b/dlm_controld/rbtree.h
index e2b2409..9a4ad60 100644
--- a/dlm_controld/rbtree.h
+++ b/dlm_controld/rbtree.h
@@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc.
linux/include/linux/rbtree.h
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=96…
Commit: 968f58cbdf01f6e8f3b7f3024556b5d7d5237b88
Parent: 6f8a9a9e4ccc96a3383ea8de181b9224e0907802
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Jan 20 11:07:45 2012 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Jan 20 11:07:45 2012 +0000
fsck.gfs2: Plug a leak in peruse_system_dinode()
Spotted by coverity: Variable "ip" going out of scope leaks the storage
it points to.
If one of the if/else conditions is true, ip is stored in a global
variable or freed, so the leak happens when none of them are true. To
fix this I've added an else statement to free ip and moved the
out_discard_ip label into it to avoid duplicating the inode_put().
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/fsck/initialize.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 3daf12d..f07e0b2 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -911,11 +911,10 @@ static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
fix_md.qinode = ip;
log_warn(_("Found system quota file at: 0x%llx\n"),
di->di_num.no_addr);
- }
- return;
-
+ } else {
out_discard_ip:
- inode_put(&ip);
+ inode_put(&ip);
+ }
}
/**
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=f2…
Commit: f29c6083c5e71eec2165bc1b3c41293b73d6c467
Parent: d0a0e58a4de53a0c582acc1d6a9333e7502f0168
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Jan 13 12:12:47 2012 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Jan 13 12:12:47 2012 +0000
fsck.gfs2: Plug a leak in find_block_ref()
Spotted by coverity: Variable "ip" going out of scope leaks the storage
it points to.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/fsck/pass1b.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index ae6d45c..9e6f376 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -344,6 +344,7 @@ static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
log_debug( _("Block %lld (0x%llx) is not gfs2 metadata.\n"),
(unsigned long long)inode,
(unsigned long long)inode);
+ fsck_inode_put(&ip);
return 1;
}
/* Check to see if this inode was referenced by another by mistake */
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=75…
Commit: 75c0d37f03d94013d6bf0f0260e19e2edcde803c
Parent: a2533b1568d3381141fb5794fd212db0dce00ed6
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jan 16 13:49:49 2012 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jan 16 13:49:49 2012 -0600
update copyright
Signed-off-by: David Teigland <teigland(a)redhat.com>
---
dlm_controld/action.c | 2 +-
dlm_controld/config.c | 2 +-
dlm_controld/cpg.c | 2 +-
dlm_controld/crc.c | 2 +-
dlm_controld/deadlock.c | 2 +-
dlm_controld/dlm_controld.h | 2 +-
dlm_controld/dlm_daemon.h | 2 +-
dlm_controld/fence.c | 2 +-
dlm_controld/lib.c | 2 +-
dlm_controld/libdlmcontrol.h | 2 +-
dlm_controld/linux_endian.h | 2 +-
dlm_controld/logging.c | 2 +-
dlm_controld/main.c | 2 +-
dlm_controld/member.c | 2 +-
dlm_controld/netlink.c | 2 +-
dlm_controld/plock.c | 2 +-
dlm_tool/main.c | 2 +-
include/copyright.cf | 2 +-
libdlm/libdlm.c | 2 +-
libdlm/libdlm.h | 2 +-
libdlm/libdlm_internal.h | 2 +-
21 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/dlm_controld/action.c b/dlm_controld/action.c
index fa7c06c..f24eb20 100644
--- a/dlm_controld/action.c
+++ b/dlm_controld/action.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/config.c b/dlm_controld/config.c
index 5a4c5c4..d909557 100644
--- a/dlm_controld/config.c
+++ b/dlm_controld/config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/cpg.c b/dlm_controld/cpg.c
index 4f63fb0..4f0709c 100644
--- a/dlm_controld/cpg.c
+++ b/dlm_controld/cpg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/crc.c b/dlm_controld/crc.c
index 1764850..1ac38d0 100644
--- a/dlm_controld/crc.c
+++ b/dlm_controld/crc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/deadlock.c b/dlm_controld/deadlock.c
index 9a7fd5d..8d4b48f 100644
--- a/dlm_controld/deadlock.c
+++ b/dlm_controld/deadlock.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/dlm_controld.h b/dlm_controld/dlm_controld.h
index a802882..8d5826c 100644
--- a/dlm_controld/dlm_controld.h
+++ b/dlm_controld/dlm_controld.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/dlm_daemon.h b/dlm_controld/dlm_daemon.h
index d60bc0f..f013fd1 100644
--- a/dlm_controld/dlm_daemon.h
+++ b/dlm_controld/dlm_daemon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/fence.c b/dlm_controld/fence.c
index a43d621..738c97a 100644
--- a/dlm_controld/fence.c
+++ b/dlm_controld/fence.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/lib.c b/dlm_controld/lib.c
index 311b6e9..e682b69 100644
--- a/dlm_controld/lib.c
+++ b/dlm_controld/lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/libdlmcontrol.h b/dlm_controld/libdlmcontrol.h
index 5a9404f..9ba809e 100644
--- a/dlm_controld/libdlmcontrol.h
+++ b/dlm_controld/libdlmcontrol.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/linux_endian.h b/dlm_controld/linux_endian.h
index 8736b5b..244ea52 100644
--- a/dlm_controld/linux_endian.h
+++ b/dlm_controld/linux_endian.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/logging.c b/dlm_controld/logging.c
index 803d08a..8fd6439 100644
--- a/dlm_controld/logging.c
+++ b/dlm_controld/logging.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/main.c b/dlm_controld/main.c
index 21a5575..7355ae1 100644
--- a/dlm_controld/main.c
+++ b/dlm_controld/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/member.c b/dlm_controld/member.c
index 58ef70e..b36985d 100644
--- a/dlm_controld/member.c
+++ b/dlm_controld/member.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/netlink.c b/dlm_controld/netlink.c
index 06b6312..04ce2f1 100644
--- a/dlm_controld/netlink.c
+++ b/dlm_controld/netlink.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_controld/plock.c b/dlm_controld/plock.c
index 3e48267..23e6a41 100644
--- a/dlm_controld/plock.c
+++ b/dlm_controld/plock.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/dlm_tool/main.c b/dlm_tool/main.c
index 776aa64..8715439 100644
--- a/dlm_tool/main.c
+++ b/dlm_tool/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
diff --git a/include/copyright.cf b/include/copyright.cf
index 3801aa9..6a73d4a 100644
--- a/include/copyright.cf
+++ b/include/copyright.cf
@@ -1,6 +1,6 @@
#ifndef __COPYRIGHT_DOT_CF__
#define __COPYRIGHT_DOT_CF__
-#define REDHAT_COPYRIGHT "Copyright (C) Red Hat, Inc. 2004-2010 All rights reserved."
+#define REDHAT_COPYRIGHT "Copyright Red Hat, Inc. 2004-2012"
#endif /* __COPYRIGHT_DOT_CF__ */
diff --git a/libdlm/libdlm.c b/libdlm/libdlm.c
index 134f5a7..a9e6195 100644
--- a/libdlm/libdlm.c
+++ b/libdlm/libdlm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/libdlm/libdlm.h b/libdlm/libdlm.h
index 6a30407..7b6e681 100644
--- a/libdlm/libdlm.h
+++ b/libdlm/libdlm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/libdlm/libdlm_internal.h b/libdlm/libdlm_internal.h
index c8fded7..685ecee 100644
--- a/libdlm/libdlm_internal.h
+++ b/libdlm/libdlm_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=a0…
Commit: a0c6128c8aa3a15604c6bd2214762cef207fa8d1
Parent: 55626ed257b0ae681e817e586e7b654e7ceec782
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Wed Jan 11 16:54:01 2012 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Wed Jan 11 18:17:56 2012 +0000
fsck.gfs2: Remove unsigned comparisons with zero
Spotted by coverity: This less-than-zero comparison of an unsigned value
is never true. "q < 0". (Fixes 6 occurrences)
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/fsck/metawalk.c | 9 +++------
gfs2/fsck/pass1b.c | 2 +-
gfs2/fsck/pass2.c | 2 +-
gfs2/fsck/pass5.c | 6 ------
4 files changed, 5 insertions(+), 14 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index d78df72..eb80ccf 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1530,8 +1530,7 @@ static int alloc_metalist(struct gfs2_inode *ip, uint64_t block,
after the bitmap has been set but before the blockmap has. */
*bh = bread(ip->i_sbd, block);
q = block_type(block);
- if (q < 0 ||
- blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE) {
+ if (blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE) {
log_debug(_("%s reference to new metadata block "
"%lld (0x%llx) is now marked as indirect.\n"),
desc, (unsigned long long)block,
@@ -1550,8 +1549,7 @@ static int alloc_data(struct gfs2_inode *ip, uint64_t block, void *private)
/* We can't check the bitmap here because this function is called
after the bitmap has been set but before the blockmap has. */
q = block_type(block);
- if (q < 0 ||
- blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE) {
+ if (blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE) {
log_debug(_("%s reference to new data block "
"%lld (0x%llx) is now marked as data.\n"),
desc, (unsigned long long)block,
@@ -1569,8 +1567,7 @@ static int alloc_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
/* We can't check the bitmap here because this function is called
after the bitmap has been set but before the blockmap has. */
q = block_type(block);
- if (q < 0 ||
- blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE)
+ if (blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE)
fsck_blockmap_set(ip, block, _("newly allocated leaf"),
gfs2_leaf_blk);
return 0;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 1879cc4..ae6d45c 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -701,7 +701,7 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
ip = fsck_load_inode(sdp, id->block_no);
q = block_type(id->block_no);
- if (q < 0 || q == gfs2_inode_invalid) {
+ if (q == gfs2_inode_invalid) {
log_debug( _("The remaining reference inode %lld "
"(0x%llx) is marked invalid: Marking "
"the block as free.\n"),
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 8562b6a..d89dd4f 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -328,7 +328,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
* 2. Blocks marked "bad" need to have their entire
* metadata tree deleted.
*/
- if (q < 0 || q == gfs2_inode_invalid || q == gfs2_bad_block) {
+ if (q == gfs2_inode_invalid || q == gfs2_bad_block) {
/* This entry's inode has bad blocks in it */
/* Handle bad blocks */
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index cb18b5a..6c08e13 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -123,12 +123,6 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
return 0;
q = block_type(block);
- if (q < 0) {
- log_err( _("Invalid block type for block #%llu "
- "(0x%llx)\n"), (unsigned long long)block,
- (unsigned long long)block);
- return q;
- }
if (sdp->gfs1)
block_status = gfs1_convert_mark(q, count);
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=1c…
Commit: 1c42411b5a8f38deabdcb4d52139da580cd1a9a9
Parent: 8c322343d559a671a0ed84488a59b475a247ae69
Author: Adam Drew <adrew(a)redhat.com>
AuthorDate: Wed Jan 11 10:09:22 2012 -0500
Committer: Adam Drew <adrew(a)redhat.com>
CommitterDate: Wed Jan 11 10:09:22 2012 -0500
Added gfs2_lockgather data gathering script.
---
configure.ac | 1 +
gfs2/Makefile.am | 2 +-
gfs2/lockgather/Makefile.am | 12 ++++
gfs2/lockgather/gfs2_lockgather | 129 +++++++++++++++++++++++++++++++++++++++
gfs2/man/Makefile.am | 1 +
gfs2/man/gfs2_lockgather.8 | 26 ++++++++
6 files changed, 170 insertions(+), 1 deletions(-)
diff --git a/configure.ac b/configure.ac
index 81ffad8..3fe1a49 100644
--- a/configure.ac
+++ b/configure.ac
@@ -285,6 +285,7 @@ AC_CONFIG_FILES([Makefile
gfs2/tool/Makefile
gfs2/tune/Makefile
gfs2/man/Makefile
+ gfs2/lockgather/Makefile
doc/Makefile
po/Makefile.in
])
diff --git a/gfs2/Makefile.am b/gfs2/Makefile.am
index 9116bd3..08e59c4 100644
--- a/gfs2/Makefile.am
+++ b/gfs2/Makefile.am
@@ -1,4 +1,4 @@
MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = libgfs2 convert edit fsck mkfs mount quota tool man \
- tune include #init.d
+ tune include lockgather #init.d
diff --git a/gfs2/lockgather/Makefile.am b/gfs2/lockgather/Makefile.am
new file mode 100644
index 0000000..fe8b480
--- /dev/null
+++ b/gfs2/lockgather/Makefile.am
@@ -0,0 +1,12 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+# When an exec_prefix setting would have us install into /usr/sbin,
+# use /sbin instead.
+# Accept an existing sbindir value of /usr/sbin (probably for older automake),
+# or an empty value, for automake-1.11 and newer.
+sbindir := $(shell rpl=0; test '$(exec_prefix):$(sbindir)' = /usr:/usr/sbin \
+ || test '$(exec_prefix):$(sbindir)' = /usr: && rpl=1; \
+ test $$rpl = 1 && echo /sbin || echo '$(exec_prefix)/sbin')
+
+
+dist_sbin_SCRIPTS = gfs2_lockgather
diff --git a/gfs2/lockgather/gfs2_lockgather b/gfs2/lockgather/gfs2_lockgather
new file mode 100644
index 0000000..ed4a0c5
--- /dev/null
+++ b/gfs2/lockgather/gfs2_lockgather
@@ -0,0 +1,129 @@
+#!/bin/bash
+
+# gfs2_lockgather - A script that gathers data for diagnosing GFS2 locking issues
+# Copyright 2012 Adam Drew <adrew(a)redhat.com>
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+QUIET=false
+
+#Handle arguments
+for var in "$@"
+do
+ #Handle running on all nodes
+ if [ $var == "--allnodes" ] || [ $var == "-a" ] ; then
+
+ for node in $(ccs_tool lsnode | tail --lines=+5 | grep -v "Cluster name" | grep -v "Nodename" | awk '{print $1}') ; do
+ #We gather via SSH on all nodes, even the local node
+ #We do this becuase determining which node name is the
+ #node running the script is too much logic to be worth it
+ echo "Starting data gathering on $node..."
+ ssh -q -f root@$node '/sbin/gfs2_lockgather -q'
+ echo "gfs2_lockgather will log a message in /var/log/messages on $node when complete or if there is an error."
+ done
+ exit 0
+ fi
+
+ #Handle quiet mode
+ if [ $var == "-q" ] || [ $var == "--quiet" ] ; then
+ QUIET=true
+ fi
+
+ #Handle help request
+ if [ $var == "--help" ] || [ $var == "--info" ] || [ $var == "-h" ] ; then
+
+ echo "gfs2_lockgather, version 1"
+ echo "A script that gathers data for diagnosing GFS2 locking issues."
+ echo "---------------------------------------------------------------"
+ echo "To gather on a single node invoke the script with no arguments."
+ echo "To see this message use --help, --info, or -h."
+ echo "To run with messages supressed use --quiet or -q."
+ echo "To gather on all nodes invoke the script with --allnodes or -a."
+ echo "Only 1 instance of gfs2_lockgather may run on a node at a time."
+ echo ""
+ exit 0
+ fi
+
+done
+
+#Check for the lock file. We only want one instance running at a time.
+if [ -e /var/run/gfs2_lockgather.lock ]; then
+ echo -ne 'Error: Lock file /var/run/gfs2_lockgather.lock found.\nAnother instance of gfs2_lockgather may be running.\nAnother node may be running a gather on this node.\n'
+ logger -t gfs2_lockgather 'Error: Lock file /var/run/gfs2_lockgather.lock found. Another instance may be running. Quitting.'
+ exit 1
+fi
+
+#Create the gather lock
+touch /var/run/gfs2_lockgather.lock
+
+logger -t gfs2_lockgather 'Gather started.'
+
+if [ $QUIET == false ] ; then echo -ne '[ ] Setting up for gather.\t\t\t\t\t\t\t\t\r' ; fi
+#Get the current datetime for unique naming
+DATETIME=$(date +%m%d%Y-%H%M%S)
+
+#Set up the directory structure
+mkdir /tmp/debugfs
+mount -t debugfs none /tmp/debugfs
+mkdir /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata
+mkdir /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/run1
+mkdir /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/run2
+
+if [ $QUIET == false ] ; then echo -ne '[# ] Gathering environment data.\t\t\t\t\t\t\t\t\r' ; fi
+#Gather some basics
+clustat > /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/clustat.out
+cman_tool services > /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/clustat.out
+mount -l > /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/mount-l.out
+ps aux > /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/ps-aux.out
+uname -a > /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/uname-a.out
+
+if [ $QUIET == false ] ; then echo -ne '[## ] Gathering GFS2 and DLM lock data: pass 1\t\t\t\t\t\t\t\t\r' ; fi
+#Glock and DLM lock dump 1
+for dlmfile in $(ls -lsv /tmp/debugfs/dlm/ | grep -v total | awk '{print $10}') ; do dd if=/tmp/debugfs/dlm/$dlmfile bs=1024M of=/tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/run1/$dlmfile &> /dev/null; done
+for fs in $(ls -lsv /tmp/debugfs/gfs2/ | grep -v total | awk '{print $10}') ; do dd if=/tmp/debugfs/gfs2/$fs/glocks bs=1024M of=/tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/run1/$fs-glocks &> /dev/null; done
+
+#Enable and trigger sysrq
+echo 1 > /proc/sys/kernel/sysrq
+
+#Thread Dump
+#This is much faster than waiting for syslog to dump the thread dumps to the messages log
+if [ $QUIET == false ] ; then echo -ne '[### ] Gathering thread dumps.\t\t\t\t\t\t\t\t\r' ; fi
+
+$(
+cat /proc/kmsg > /tmp/thread-dumps &
+echo 't' > /proc/sysrq-trigger
+sleep 10
+kill -9 $!
+)
+
+if [ $QUIET == false ] ; then echo -ne '[#### ] Gathering GFS2 and DLM lock data: pass 2.\t\t\t\t\t\t\t\t\r' ; fi
+#Glock and DLM dump 2
+for dlmfile in $(ls -lsv /tmp/debugfs/dlm/ | grep -v total | awk '{print $10}') ; do dd if=/tmp/debugfs/dlm/$dlmfile bs=1024M of=/tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/run2/$dlmfile &> /dev/null; done
+for fs in $(ls -lsv /tmp/debugfs/gfs2/ | grep -v total | awk '{print $10}') ; do dd if=/tmp/debugfs/gfs2/$fs/glocks bs=1024M of=/tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/run2/$fs-glocks &> /dev/null; done
+
+if [ $QUIET == false ] ; then echo -ne '[##### ] Gathering messages logs\t\t\t\t\t\t\t\t\r' ; fi
+#Get the messages log file
+cp /var/log/messages /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/
+
+#Tar up the results and clean up temporary files
+if [ $QUIET == false ] ; then echo -ne '[###### ] Cleaning up... 80%.\t\t\t\t\t\t\t\t\r' ; fi
+tar cjf /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata.tar.bz /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata/ &> /dev/null
+umount /tmp/debugfs/
+rm -f /var/run/gfs2_lockgather.lock
+rm -rf /tmp/debugfs
+rm -rf /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata
+logger -t gfs2_lockgather "Gather completed. File is /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata.tar.bz"
+if [ $QUIET == false ] ; then echo -ne "[#######] Done. File is /tmp/$(hostname)-$(echo $DATETIME)-gfshangdata.tar.bz\r\t\t\t\t\t\t\t\t\r\n" ; fi
+exit 0
diff --git a/gfs2/man/Makefile.am b/gfs2/man/Makefile.am
index 0f132d6..648ed84 100644
--- a/gfs2/man/Makefile.am
+++ b/gfs2/man/Makefile.am
@@ -9,5 +9,6 @@ dist_man_MANS = fsck.gfs2.8 \
gfs2_quota.8 \
gfs2_tool.8 \
mkfs.gfs2.8 \
+ gfs2_lockgather.8 \
mount.gfs2.8 \
tunegfs2.8
diff --git a/gfs2/man/gfs2_lockgather.8 b/gfs2/man/gfs2_lockgather.8
new file mode 100644
index 0000000..3cd8b9c
--- /dev/null
+++ b/gfs2/man/gfs2_lockgather.8
@@ -0,0 +1,26 @@
+.TH gfs2_lockgather 8
+
+.SH NAME
+gfs2_lockgather - Gathers data for diagnosing GFS2 locking issues
+
+.SH SYNOPSIS
+.B gfs2_lockgather
+[\fIOPTIONS\fR]
+
+.SH DESCRIPTION
+gfs2_lockgather will gather data that is useful for diagnosing performance and locking issues
+involving GFS2 filesystems. The script gathers basic system and cluster data such as rpm output,
+kernel version, thread dumps from all processes, and 2 passes of glock and DLM locking data. After
+the data is gathered it is stored in a tarball under /tmp. The script can be invoked to gather
+data from a single node, or to gather data from all nodes via ssh.
+.SH OPTIONS
+.TP
+\fB-h, --help, --info\fP
+Display help and usage information.
+.TP
+\fB-q, --quiet\fP
+Quiet mode. Run with output supressed.
+.TP
+\fB-a, --allnodes\fP
+Gather data from all nodes via ssh.
+
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=73…
Commit: 737c05e726e32349dcf26fa1c54dabf4f94b6906
Parent: b58b340885082b19bc2f8eab28354e552249e151
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Tue Sep 6 15:42:41 2011 -0400
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Tue Jan 10 16:36:41 2012 -0500
rgmanager: Resolve rare deadlock
In very rare cases, it was possible to fill up a pipe used for
IPC between threads during reconfiguration, causing a deadlock.
This patch resolves the issue.
Resolves: rhbz#759541
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/daemons/groups.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/rgmanager/src/daemons/groups.c b/rgmanager/src/daemons/groups.c
index ecb7b85..128446a 100644
--- a/rgmanager/src/daemons/groups.c
+++ b/rgmanager/src/daemons/groups.c
@@ -1726,8 +1726,6 @@ init_resource_groups(int reconfigure, int do_init, int new_config_version)
free(val);
}
- /* Wait for any pending requests */
- rg_wait_threads();
/* Block operations that would break during configuration
changes */
rg_clear_initialized(FL_CONFIG);
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=7c…
Commit: 7cb765d530c34dc39cb0e6ed36641f3feafd4c6d
Parent: 0e53e6655e2dbf0432f2b0d4af9f2df07c25727a
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Tue Sep 6 15:42:41 2011 -0400
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Tue Jan 10 16:35:46 2012 -0500
rgmanager: Resolve rare deadlock
In very rare cases, it was possible to fill up a pipe used for
IPC between threads during reconfiguration, causing a deadlock.
This patch resolves the issue.
Resolves: rhbz#759542
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/daemons/groups.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/rgmanager/src/daemons/groups.c b/rgmanager/src/daemons/groups.c
index b546421..1e93e03 100644
--- a/rgmanager/src/daemons/groups.c
+++ b/rgmanager/src/daemons/groups.c
@@ -1737,8 +1737,6 @@ init_resource_groups(int reconfigure, int do_init, int new_config_version)
free(val);
}
- /* Wait for any pending requests */
- rg_wait_threads();
/* Block operations that would break during configuration
changes */
rg_clear_initialized(FL_CONFIG);
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=3b…
Commit: 3b33ff879bb10d5086cf4a62f53b4bd8a37ca571
Parent: 17bacf59aea4f2d021ba8127f71e9d840703b692
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Wed Oct 5 00:18:17 2011 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Mon Jan 9 16:07:26 2012 +0000
libgfs2: Don't count sentinel dirent as an entry
dir_split_leaf() adds a sentinel dirent using dirent_alloc() which
increments di_entries in the directory dinode. Since sentinel dirents
aren't real directory entries, di_entries becomes too high in some
situations. This patch decrements di_entries after the sentinel dirent
is created to fix the discrepancy.
rhbz#745161
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/fs_ops.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 353d47f..3d57b97 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -929,6 +929,8 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
if (dirent_alloc(dip, nbh, 0, &new))
die("dir_split_leaf (4)\n");
new->de_inum.no_formal_ino = 0;
+ /* Don't count the sentinel dirent as an entry */
+ dip->i_di.di_entries--;
}
oleaf->lf_depth = be16_to_cpu(oleaf->lf_depth) + 1;
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=d2…
Commit: d2a549268e462cc884622494b21325279087d813
Parent: 0929325f4c245d94df5e1fed06d5a2c44f0668fd
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Mon Jan 9 17:05:52 2012 -0600
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Mon Jan 9 17:05:52 2012 -0600
Fix for rhbz769731 - HA LVM failure to remove tag thwarts service relocation
A change in the behaviour of handling missing PVs by LVM has necessitated
an update to the HA LVM scripts. Without the update, a failed PV remains
in the VG until it is removed via 'vgreduce'. Since no updates to the metadata
can happen while the VG is in this state, the "tags" used by HA LVM cannot be
removed and relocation cannot take place.
---
rgmanager/src/resources/lvm_by_lv.sh | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/lvm_by_lv.sh b/rgmanager/src/resources/lvm_by_lv.sh
index da15a15..966214f 100644
--- a/rgmanager/src/resources/lvm_by_lv.sh
+++ b/rgmanager/src/resources/lvm_by_lv.sh
@@ -238,7 +238,19 @@ lv_activate_and_tag()
lvchange --deltag $tag $lv_path
if [ $? -ne 0 ]; then
ocf_log err "Unable to delete tag from $lv_path"
- return $OCF_ERR_GENERIC
+
+ # Newer versions of LVM require the missing PVs to
+ # be removed from the VG via a separate call before
+ # the tag can be removed.
+ ocf_log err "Attempting volume group clean-up and retry"
+ vgreduce --removemissing --force $OCF_RESKEY_vg_name
+
+ # Retry tag deletion
+ lvchange --deltag $tag $lv_path
+ if [ $? -ne 0 ]; then
+ ocf_log err "Failed to delete tag from $lv_path"
+ return $OCF_ERR_GENERIC
+ fi
fi
if [ `lvs --noheadings -o lv_tags $lv_path` == $tag ]; then
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=ea…
Commit: ead0d1031e46279775333b2f988f0722877a0687
Parent: 02850b642b64ec70c1bdbb411eb653624c135384
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Mon Jan 9 11:15:34 2012 +0100
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Mon Jan 9 11:15:34 2012 +0100
build: fix build error with gcc 4.7
drop unused LDFLAGS += -Wl
-Wl is used to pass options to the linker and as of gcc 4.7 it expects
the options to be there or call to the linker will fail.
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
libdlm/Makefile | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/libdlm/Makefile b/libdlm/Makefile
index bcb1b6a..185d9c2 100644
--- a/libdlm/Makefile
+++ b/libdlm/Makefile
@@ -80,8 +80,6 @@ CFLAGS += -D_GNU_SOURCE -g \
LIB_CFLAGS += $(CFLAGS) -D_REENTRANT
LLT_CFLAGS += $(CFLAGS)
-LDFLAGS += -Wl
-
LIB_LDFLAGS += $(LDFLAGS) -lpthread
LLT_LDFLAGS += $(LDFLAGS)
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=14…
Commit: 1498ce20c091845100456fd1f235658f6056d140
Parent: a75ba5bf6afb3cf6bd31493b1e6c8815cda19c3c
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jan 5 14:22:23 2012 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Jan 5 14:22:23 2012 -0600
dlm_controld: wait on different quorum conditions
enable_quorum option can be 0, 1, 2 to wait for quorum
never, only before fencing request, and always.
---
dlm_controld/cpg.c | 57 +++++++++++++++++++++++----------------------
dlm_controld/dlm_daemon.h | 2 +-
2 files changed, 30 insertions(+), 29 deletions(-)
diff --git a/dlm_controld/cpg.c b/dlm_controld/cpg.c
index e64bf54..183879e 100644
--- a/dlm_controld/cpg.c
+++ b/dlm_controld/cpg.c
@@ -682,25 +682,6 @@ static void request_fencing(struct lockspace *ls)
}
}
-/* we know that the quorum value here is consistent with the cpg events
- because the ringid's are in sync per the previous check_ringid_done */
-
-static int check_quorum_done(struct lockspace *ls)
-{
- if (!cfgd_enable_quorum) {
- log_group(ls, "check_quorum disabled");
- return 1;
- }
-
- if (!cluster_quorate) {
- log_group(ls, "check_quorum not quorate");
- return 0;
- }
-
- log_group(ls, "check_quorum done");
- return 1;
-}
-
/* wait for local fs_controld to ack each failed node */
static int check_fs_done(struct lockspace *ls)
@@ -709,10 +690,8 @@ static int check_fs_done(struct lockspace *ls)
int wait_count = 0;
/* no corresponding fs for this lockspace */
- if (!ls->fs_registered) {
- log_group(ls, "check_fs none registered");
+ if (!ls->fs_registered)
return 1;
- }
list_for_each_entry(node, &ls->node_history, list) {
if (!node->check_fs)
@@ -827,19 +806,41 @@ static void stop_kernel(struct lockspace *ls, uint32_t seq)
that have occured since the last change applied to dlm-kernel, not
just the latest change */
+/* we know that the cluster_quorate value here is consistent with the cpg events
+ because the ringid's are in sync per the check_ringid_done */
+
+/*
+ enable_quorum = 0
+ Never wait for quorum here.
+
+ enable_quorum = 1
+ Wait for quorum before calling request_fencing() in cases where
+ fencing is needed. Reason for using this would be if fencing
+ system doesn't wait for quorum before carrying out a fencing
+ request, and we want to avoid having partitioned inquorate nodes
+ fencing quorate nodes in another partition.
+
+ enable_quorum = 2
+ Always wait for quorum as a general condition here. This
+ means that lockspace join/leave operations would block waiting
+ for quorum. There's not any reason to do this per se, unless
+ that's the behavior the application using the dlm wants.
+*/
+
static int wait_conditions_done(struct lockspace *ls)
{
if (!check_ringid_done(ls))
return 0;
- /* It's convenient to be able to join and leave lockspaces without
- having quorum. If the fencing system does not wait for quorum
- before carrying out fencing requests, then we may want to wait for
- quorum here before requesting fencing, to avoid having partitioned
- nodes fence good nodes. */
+ if ((cfgd_enable_quorum > 1) && !cluster_quorate) {
+ log_group(ls, "wait for quorum");
+ return 0;
+ }
- if (need_fencing(ls) && !check_quorum_done(ls))
+ if ((cfgd_enable_quorum > 0) && need_fencing(ls) && !cluster_quorate) {
+ log_group(ls, "wait for quorum before fencing");
return 0;
+ }
request_fencing(ls);
diff --git a/dlm_controld/dlm_daemon.h b/dlm_controld/dlm_daemon.h
index 03adb3c..2d27caa 100644
--- a/dlm_controld/dlm_daemon.h
+++ b/dlm_controld/dlm_daemon.h
@@ -81,7 +81,7 @@
#define DEFAULT_DEBUG_LOGFILE 0
#define DEFAULT_ENABLE_FENCING 1
-#define DEFAULT_ENABLE_QUORUM 1
+#define DEFAULT_ENABLE_QUORUM 0
#define DEFAULT_ENABLE_FSCONTROL 0
#define DEFAULT_ENABLE_PLOCK 1
#define DEFAULT_PLOCK_DEBUG 0
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=34…
Commit: 34f59b17a3f5fdc00b4f6a906c9a1e1d23445dc2
Parent: e3a51f9addfa5443d8570d6ccdfbd67ecd9b4d6b
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Jan 6 13:56:29 2012 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Jan 6 13:56:29 2012 +0000
gfs2_edit: Check for error value from gfs2_get_bitmap
Spotted by coverity: gfs2_get_bitmap returns -1 on error and it was
being used as an array index in display_block_type.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/edit/hexedit.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index f58657b..02a4091 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -756,6 +756,10 @@ int display_block_type(int from_restore)
print_gfs2(" blk ");
for (b = blknum; b < blknum + 4; b++) {
btype = gfs2_get_bitmap(&sbd, b, rgd);
+ if (btype < 0) {
+ fprintf(stderr, "Failed to retrieve block state from bitmap\n");
+ exit(-1);
+ }
print_gfs2("0x%x-%s ", b,
allocdesc[sbd.gfs1][btype]);
}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=64…
Commit: 64ba5d035d8d477e0986e75c3d37e2625861bf9c
Parent: 07891324276c5414e6000b50bccafe9235bd4a4a
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Thu Jan 5 10:43:12 2012 -0500
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Thu Jan 5 11:33:05 2012 -0500
rgmanager: Fix dependency issue related to ordering
If you ordered two services the opposite way in cluster.conf
('b' first, which depends on 'a'), then rgmanager would fail
over 'b' despite the fact that 'a' was not running yet - this
is because the state of 'a' was not set to 'stopped' - so we
need to check for a node-death event in move_or_start().
Resolves: rhbz#743214
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/default_event_script.sl | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl
index f2c7bc1..62de2d2 100644
--- a/rgmanager/src/resources/default_event_script.sl
+++ b/rgmanager/src/resources/default_event_script.sl
@@ -156,7 +156,9 @@ define move_or_start(service, node_list)
depends = service_property(service, "depend");
if (depends != "") {
(,,, owner, state) = service_status(depends);
- if (owner < 0) {
+ if ((owner < 0) or
+ ((event_type == EVENT_NODE) and (owner == node_id) and
+ (node_state == 0))) {
debug(service, " is not runnable; dependency not met");
()=service_stop(service);
return ERR_DEPEND;
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=64…
Commit: 64f54ec761a16143c28fe414aa4fefef308bdc43
Parent: 93e33cb09d2567e9523a7098247c6c9df324c16b
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Wed Jan 4 23:01:07 2012 -0500
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Thu Jan 5 10:56:32 2012 -0500
rgmanager: Avoid duplicate restart of service
If B depends on A and both A and B are running on
node 1 and node 1 fails, the stop events generated
will inadvertently cause B to be restarted after
the initial failover.
This patch resolves this issue by comparing the
start times in central_processing mode.
A known limitation to this patch is that in order
for this patch to work correctly, the cluster nodes'
time must be approximately in sync.
Resolves: rhbz#743214
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/default_event_script.sl | 19 ++++++++++++++++++-
1 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl
index cdde066..2d5503f 100644
--- a/rgmanager/src/resources/default_event_script.sl
+++ b/rgmanager/src/resources/default_event_script.sl
@@ -444,6 +444,8 @@ define default_service_event_handler()
variable tmp;
variable owner;
variable state;
+ variable d_trans, s_trans;
+ variable s_state;
debug("Executing default service event handler");
@@ -498,17 +500,32 @@ define default_service_event_handler()
continue;
}
- (,,, owner, state) = service_status(services[x]);
+ (d_trans,,,, owner, state) = service_status(services[x], 1);
if ((service_state == "started") and (owner < 0) and
(state == "stopped")) {
info("Dependency met; starting ", services[x]);
nodes = allowed_nodes(services[x]);
()=move_or_start(services[x], nodes);
+ continue;
}
% service died - stop service(s) that depend on the dead
if ((service_owner < 0) and (owner >= 0) and
(depend_mode != "soft")) {
+
+ % grab the -current- state of the service here
+ % If the service is running, and its dependent service
+ % as above is running and the dependent service was
+ % started at or after the service, then stopping it
+ % will result in unwanted service outage.
+ (s_trans,,,, s_state) = service_status(service_name);
+ if ((s_state == "started") and (state == "started") and
+ (d_trans >= s_trans)) {
+ debug("Skipping ", services[x],
+ "; restart not needed");
+ continue;
+ }
+
info("Dependency lost; stopping ", services[x]);
()=service_stop(services[x]);
}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=e6…
Commit: e66cf5f585812e24f5e82a424d50cc2a4fec039d
Parent: 8ce53c09ea6fe55b18ae15ad8620dd1873ff43cb
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Thu Jan 5 10:43:12 2012 -0500
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Thu Jan 5 11:31:48 2012 -0500
rgmanager: Fix dependency issue related to ordering
If you ordered two services the opposite way in cluster.conf
('b' first, which depends on 'a'), then rgmanager would fail
over 'b' despite the fact that 'a' was not running yet - this
is because the state of 'a' was not set to 'stopped' - so we
need to check for a node-death event in move_or_start().
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/default_event_script.sl | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl
index bd445c0..c54c068 100644
--- a/rgmanager/src/resources/default_event_script.sl
+++ b/rgmanager/src/resources/default_event_script.sl
@@ -176,7 +176,9 @@ define move_or_start(service, node_list)
depends = service_property(service, "depend");
if (depends != "") {
(,,, owner, state) = service_status(depends);
- if (owner < 0) {
+ if ((owner < 0) or
+ ((event_type == EVENT_NODE) and (owner == node_id) and
+ (node_state == 0))) {
debug(service, " is not runnable; dependency not met");
()=service_stop(service);
return ERR_DEPEND;
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=4b…
Commit: 4b7a2a2cc9b87ec9e31d6d4b05ee11c5519deb41
Parent: 663efa987ba58aa79eb66dfdcdedbbd905886cf4
Author: Lon Hohberger <lhh(a)redhat.com>
AuthorDate: Thu Jan 5 10:43:12 2012 -0500
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Thu Jan 5 10:53:32 2012 -0500
rgmanager: Fix dependency issue related to ordering
If you ordered two services the opposite way in cluster.conf
('b' first, which depends on 'a'), then rgmanager would fail
over 'b' despite the fact that 'a' was not running yet - this
is because the state of 'a' was not set to 'stopped' - so we
need to check for a node-death event in move_or_start().
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/default_event_script.sl | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl
index bd445c0..4cdf519 100644
--- a/rgmanager/src/resources/default_event_script.sl
+++ b/rgmanager/src/resources/default_event_script.sl
@@ -176,7 +176,9 @@ define move_or_start(service, node_list)
depends = service_property(service, "depend");
if (depends != "") {
(,,, owner, state) = service_status(depends);
- if (owner < 0) {
+ if ((owner < 0) or
+ ((event_type == EVENT_NODE) and (owner == node_id) and
+ (node_state == 0))) {
debug(service, " is not runnable; dependency not met");
()=service_stop(service);
return ERR_DEPEND;
@@ -541,8 +543,8 @@ define default_service_event_handler()
(s_trans,,,,,, s_state) = service_status(service_name, 1);
if ((s_state == "started") and (state == "started") and
(d_trans >= s_trans)) {
- %debug("S:", service_name, " trans ", s_trans);
- %debug("D:", services[x], " trans ", d_trans);
+ debug("S:", service_name, " trans ", s_trans);
+ debug("D:", services[x], " trans ", d_trans);
debug("Skipping ", services[x],
"; restart not needed");