Gitweb:
http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: f8a4338b1c2978b935cb4fe9289663cce642a6ec
Parent: f25fe6a87d568285aa6f7cf6298f6f284e964977
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Fri Jan 22 09:01:15 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:30 2010 -0600
fsck.gfs2: link.c should log why it's making a change for debugging
This patch helps in debugging directory link problems by logging
the dinode and the reason why the directory link count is being
incremented or decremented.
rhbz#455300
---
gfs2/fsck/link.c | 31 +++++++++++++++++++++++--------
gfs2/fsck/link.h | 6 ++++--
gfs2/fsck/lost_n_found.c | 22 ++++++++++++++++------
gfs2/fsck/pass2.c | 40 ++++++++++++++++++++++++++++------------
gfs2/fsck/pass3.c | 4 ++--
5 files changed, 73 insertions(+), 30 deletions(-)
diff --git a/gfs2/fsck/link.c b/gfs2/fsck/link.c
index 59e258b..0314074 100644
--- a/gfs2/fsck/link.c
+++ b/gfs2/fsck/link.c
@@ -27,21 +27,28 @@ int set_link_count(uint64_t inode_no, uint32_t count)
return 0;
}
-int increment_link(struct gfs2_sbd *sbp, uint64_t inode_no)
+int increment_link(uint64_t inode_no, uint64_t referenced_from,
+ const char *why)
{
struct inode_info *ii = NULL;
ii = inodetree_find(inode_no);
/* If the list has entries, look for one that matches
* inode_no */
- if(ii) {
+ if (ii) {
ii->counted_links++;
- log_debug( _("Incremented counted links to %u for %"PRIu64" (0x%"
- PRIx64 ")\n"), ii->counted_links, inode_no, inode_no);
+ log_debug( _("Directory %lld (0x%llx) incremented counted "
+ "links to %u for %"PRIu64" (0x%" PRIx64 ") "
+ "via %s\n"),
+ (unsigned long long)referenced_from,
+ (unsigned long long)referenced_from,
+ ii->counted_links, inode_no, inode_no, why);
return 0;
}
- log_debug( _("No match found when incrementing link for %" PRIu64
- " (0x%" PRIx64 ")!\n"), inode_no, inode_no);
+ log_debug( _("Ref: %lld (0x%llx) No match found when incrementing "
+ "link for %" PRIu64 " (0x%" PRIx64 ")!\n"),
+ (unsigned long long)referenced_from,
+ (unsigned long long)referenced_from, inode_no, inode_no);
/* If no match was found, add a new entry and set its
* counted links to 1 */
ii = inodetree_insert(inode_no);
@@ -52,16 +59,24 @@ int increment_link(struct gfs2_sbd *sbp, uint64_t inode_no)
return 0;
}
-int decrement_link(struct gfs2_sbd *sbp, uint64_t inode_no)
+int decrement_link(uint64_t inode_no, uint64_t referenced_from,
+ const char *why)
{
struct inode_info *ii = NULL;
ii = inodetree_find(inode_no);
/* If the list has entries, look for one that matches
* inode_no */
- log_err( _("Decrementing %"PRIu64" (0x%" PRIx64 ")\n"),
inode_no, inode_no);
+ log_err( _("Decrementing %"PRIu64" (0x%" PRIx64 ") to
%d\n"),
+ inode_no, inode_no, ii->counted_links);
if(ii) {
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,
+ (unsigned long long)referenced_from,
+ ii->counted_links, inode_no, inode_no, why);
return 0;
}
log_debug( _("No match found when decrementing link for %" PRIu64
diff --git a/gfs2/fsck/link.h b/gfs2/fsck/link.h
index 7446b4a..f890575 100644
--- a/gfs2/fsck/link.h
+++ b/gfs2/fsck/link.h
@@ -2,7 +2,9 @@
#define _LINK_H
int set_link_count(uint64_t inode_no, uint32_t count);
-int increment_link(struct gfs2_sbd *sbp, uint64_t inode_no);
-int decrement_link(struct gfs2_sbd *sbp, uint64_t inode_no);
+int increment_link(uint64_t inode_no, uint64_t referenced_from,
+ const char *why);
+int decrement_link(uint64_t inode_no, uint64_t referenced_from,
+ const char *why);
#endif /* _LINK_H */
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 2c8bbea..2eee341 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -46,10 +46,16 @@ int add_inode_to_lf(struct gfs2_inode *ip){
* this */
gfs2_blockmap_set(bl, lf_dip->i_di.di_num.no_addr,
gfs2_inode_dir);
- increment_link(ip->i_sbd,
- ip->i_sbd->md.rooti->i_di.di_num.no_addr);
- increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr);
- increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr);
+ /* root inode links to lost+found */
+ increment_link(ip->i_sbd->md.rooti->i_di.di_num.no_addr,
+ lf_dip->i_di.di_num.no_addr, _("root"));
+ /* lost+found link for '.' from itself */
+ increment_link(lf_dip->i_di.di_num.no_addr,
+ lf_dip->i_di.di_num.no_addr, "\".\"");
+ /* lost+found link for '..' back to root */
+ increment_link(lf_dip->i_di.di_num.no_addr,
+ ip->i_sbd->md.rooti->i_di.di_num.no_addr,
+ "\"..\"");
}
}
if(ip->i_di.di_num.no_addr == lf_dip->i_di.di_num.no_addr) {
@@ -111,9 +117,13 @@ int add_inode_to_lf(struct gfs2_inode *ip){
dir_add(lf_dip, tmp_name, strlen(tmp_name), &(ip->i_di.di_num),
inode_type);
- increment_link(ip->i_sbd, ip->i_di.di_num.no_addr);
+ /* This inode is linked from lost+found */
+ increment_link(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(S_ISDIR(ip->i_di.di_mode))
- increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr);
+ increment_link(lf_dip->i_di.di_num.no_addr,
+ ip->i_di.di_mode, _("to lost+found"));
log_notice( _("Added inode #%llu to lost+found dir\n"),
(unsigned long long)ip->i_di.di_num.no_addr);
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 3052190..e04f73f 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -377,7 +377,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
/* FIXME: Should we continue on here
* and check the rest of the '.'
* entry? */
- increment_link(sbp, entryblock);
+ increment_link(entryblock,
+ ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -412,7 +414,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
log_err( _("Invalid '.' reference remains\n"));
/* Not setting ds->dotdir here since
* this '.' entry is invalid */
- increment_link(sbp, entryblock);
+ increment_link(entryblock,
+ ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -420,7 +424,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
}
ds->dotdir = 1;
- increment_link(sbp, entryblock);
+ increment_link(entryblock, ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
@@ -447,7 +452,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
/* FIXME: Should we continue on here
* and check the rest of the '..'
* entry? */
- increment_link(sbp, entryblock);
+ increment_link(entryblock,
+ ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -470,7 +477,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
return 1;
} else {
log_err( _("Bad '..' directory entry remains\n"));
- increment_link(sbp, entryblock);
+ increment_link(entryblock,
+ ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -487,7 +496,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
}
ds->dotdotdir = 1;
- increment_link(sbp, entryblock);
+ increment_link(entryblock, ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -496,7 +506,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
/* After this point we're only concerned with directories */
if(q != gfs2_inode_dir) {
log_debug( _("Found non-dir inode dentry\n"));
- increment_link(sbp, entryblock);
+ increment_link(entryblock, ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -524,7 +535,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent
*dent,
stack;
return -1;
}
- increment_link(sbp, entryblock);
+ increment_link(entryblock, ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
/* End of checks */
@@ -601,8 +613,10 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char
*dirname,
log_warn( _("Adding '.' entry\n"));
dir_add(sysinode, filename, filename_len,
&(sysinode->i_di.di_num), DT_DIR);
- increment_link(sysinode->i_sbd,
- sysinode->i_di.di_num.no_addr);
+ /* This system inode is linked to itself via '.' */
+ increment_link(sysinode->i_di.di_num.no_addr,
+ sysinode->i_di.di_num.no_addr,
+ "sysinode \".\"");
ds.entry_count++;
free(filename);
} else
@@ -781,8 +795,10 @@ int pass2(struct gfs2_sbd *sbp)
dir_add(ip, filename, filename_len,
&(ip->i_di.di_num), DT_DIR);
- increment_link(ip->i_sbd,
- ip->i_di.di_num.no_addr);
+ /* directory links to itself via '.' */
+ increment_link(ip->i_di.di_num.no_addr,
+ ip->i_di.di_num.no_addr,
+ _("\". (itself)\""));
ds.entry_count++;
free(filename);
log_err( _("The directory was fixed.\n"));
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 5f529f2..bef6d00 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -49,9 +49,9 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
if(gfs2_dirent_del(ip, filename, filename_len))
log_warn( _("Unable to remove \"..\" directory entry.\n"));
else
- decrement_link(sbp, olddotdot);
+ decrement_link(olddotdot, block, _("old \"..\""));
dir_add(ip, filename, filename_len, &pip->i_di.di_num, DT_DIR);
- increment_link(sbp, newdotdot);
+ increment_link(newdotdot, block, _("new \"..\""));
bmodified(ip->i_bh);
fsck_inode_put(&ip);
fsck_inode_put(&pip);