Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 9383e745e23602bc45f9c92184feea59 > files > 31

gfs2-utils-0.1.62-28.el5.src.rpm

commit 7c8cb8d5d6d1e08c5f83eef844ceff89a6567d64
Author: Bob Peterson <bob@ganesha.peterson>
Date:   Fri Jan 22 09:01:15 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

diff --git a/gfs2/fsck/link.c b/gfs2/fsck/link.c
index b6870c8..a39db33 100644
--- a/gfs2/fsck/link.c
+++ b/gfs2/fsck/link.c
@@ -40,21 +40,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);
@@ -65,16 +72,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 0509255..c43cda3 100644
--- a/gfs2/fsck/link.h
+++ b/gfs2/fsck/link.h
@@ -16,7 +16,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 05318f0..90354d9 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -59,10 +59,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) {
@@ -117,9 +123,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 7c8a71c..36f2f6b 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -390,7 +390,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;
@@ -425,7 +427,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;
@@ -433,7 +437,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++;
 
@@ -460,7 +465,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;
@@ -483,7 +490,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;
@@ -500,7 +509,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;
@@ -509,7 +519,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;
@@ -537,7 +548,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 */
@@ -614,8 +626,10 @@ 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
@@ -794,8 +808,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 fa66f29..719a665 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -62,9 +62,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);