[Ocfs2-tools-commits] zab commits r606 - trunk/fsck.ocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Jan 26 18:13:29 CST 2005


Author: zab
Date: 2005-01-26 18:13:27 -0600 (Wed, 26 Jan 2005)
New Revision: 606

Modified:
   trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in
   trunk/fsck.ocfs2/journal.c
   trunk/fsck.ocfs2/pass4.c
Log:
o check that a journal has blocks to replay before doing so
o ask before truncating files in the orphan directory


Modified: trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in
===================================================================
--- trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in	2005-01-26 23:39:38 UTC (rev 605)
+++ trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in	2005-01-27 00:13:27 UTC (rev 606)
@@ -515,6 +515,8 @@
 Answering yes will read the directory block for the given directory and update
 its ".." entry to reflect its parent.
 
+\" pass4.c
+
 .SS "INODE_NOT_CONNECTED"
 Most all inodes in the system should be referenced by a directory entry. An inode was found which isn't referred to by any directory entry.
 
@@ -528,8 +530,14 @@
 
 Answering yes sets the inode's count to match the number of referring directory entries.
 
+.SS "INODE_ORPHANED"
+While files are being deleted they are placed in an internal directory.  If
+the machine crashes while this is taking place the files will be left in
+this directory.  Fsck has found an inode in this directory and would like
+to finish the job of truncating and removing it.
 
-\" pass4.c
+Answering yes removes the file data associated with the inode and frees
+the inode.
 
 .SH "SEE ALSO"
 .BR ocfs2(8)

Modified: trunk/fsck.ocfs2/journal.c
===================================================================
--- trunk/fsck.ocfs2/journal.c	2005-01-26 23:39:38 UTC (rev 605)
+++ trunk/fsck.ocfs2/journal.c	2005-01-27 00:13:27 UTC (rev 606)
@@ -508,13 +508,26 @@
 	return err;
 }
 
+/*
+ * We only need to replay the journals if the inode's flag is set and s_start
+ * indicates that there is actually pending data in the journals.
+ *
+ * In the simple case of an unclean shutdown we don't want to have to build up
+ * enough state to be able to truncate the inodes waiting in the orphan dir.
+ * ocfs2 in the kernel only fixes up the orphan dirs if the journal dirty flag
+ * is set.  So after replaying the journals we clear s_startin the journals to
+ * stop a second journal replay but leave the dirty bit set so that the kernel
+ * will truncate the orphaned inodes. 
+ */
 errcode_t o2fsck_should_replay_journals(ocfs2_filesys *fs, int *should)
 {
 	uint16_t i, max_nodes;
-	ocfs2_dinode *di;
 	char *buf = NULL;
 	uint64_t blkno;
 	errcode_t ret;
+	ocfs2_cached_inode *cinode = NULL;
+	int contig, is_dirty;
+	journal_superblock_t *jsb;
 
 	*should = 0;
 	max_nodes = OCFS2_RAW_SB(fs->fs_super)->s_max_nodes;
@@ -526,7 +539,7 @@
 		goto out;
 	}
 
-	di = (ocfs2_dinode *)buf;
+	jsb = (journal_superblock_t *)buf;
 
 	for (i = 0; i < max_nodes; i++) {
 		ret = ocfs2_lookup_system_inode(fs, JOURNAL_SYSTEM_INODE, i,
@@ -537,23 +550,55 @@
 			goto out;
 		}
 
-		ret = ocfs2_read_inode(fs, blkno, buf);
+		if (cinode) {
+			ocfs2_free_cached_inode(fs, cinode);
+			cinode = NULL;
+		}
+		ret = ocfs2_read_cached_inode(fs, blkno, &cinode);
 		if (ret) {
 			com_err(whoami, ret, "while reading cached inode "
 				"%"PRIu64" for node %d's journal", blkno, i);
 			goto out;
 		}
-		
-		verbosef("node %d JOURNAL_DIRTY_FL: %d\n", i,
-			 di->id1.journal1.ij_flags & OCFS2_JOURNAL_DIRTY_FL);
 
-		if (di->id1.journal1.ij_flags & OCFS2_JOURNAL_DIRTY_FL) 
+		ret = ocfs2_extent_map_init(fs, cinode);
+		if (ret) {
+			com_err(whoami, ret, "while initializing extent map");
+			goto out;
+		}
+
+		is_dirty = cinode->ci_inode->id1.journal1.ij_flags &
+			   OCFS2_JOURNAL_DIRTY_FL;
+		verbosef("node %d JOURNAL_DIRTY_FL: %d\n", i, is_dirty);
+		if (!is_dirty)
+			continue;
+
+		ret = ocfs2_extent_map_get_blocks(cinode, 0, 1, &blkno,
+						  &contig);
+		if (ret) {
+			com_err(whoami, ret, "while looking up the journal "
+				"super block in node %d's journal", i);
+			goto out;
+		}
+
+		/* XXX be smarter about reading in the whole super block if it
+		 * spans multiple blocks */
+		ret = ocfs2_read_journal_superblock(fs, blkno, buf);
+		if (ret) {
+			com_err(whoami, ret, "while reading the journal "
+				"super block in node %d's journal", i);
+			goto out;
+		}
+
+		if (jsb->s_start)
 			*should = 1;
 	}
 
 out:
 	if (buf)
 		ocfs2_free(&buf);
+	if (cinode)
+		ocfs2_free_cached_inode(fs, cinode);
 	return ret;
 	
 }

Modified: trunk/fsck.ocfs2/pass4.c
===================================================================
--- trunk/fsck.ocfs2/pass4.c	2005-01-26 23:39:38 UTC (rev 605)
+++ trunk/fsck.ocfs2/pass4.c	2005-01-27 00:13:27 UTC (rev 606)
@@ -108,6 +108,12 @@
 		goto out;
 	}
 
+	if (!prompt(ost, PY, PR_INODE_ORPHANED,
+		   "Inode %"PRIu64" was found in the orphan directory. "
+		   "Delete its contents and unlink it?", dirent->inode)) {
+		goto out;
+	}
+
 	ret = ocfs2_truncate(ost->ost_fs, dirent->inode, 0);
 	if (ret) {
 		com_err(whoami, ret, "while truncating orphan inode %"PRIu64,



More information about the Ocfs2-tools-commits mailing list