[Ocfs2-tools-commits] zab commits r448 - in trunk/fsck.ocfs2: . include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Dec 2 14:51:07 CST 2004


Author: zab
Date: 2004-12-02 14:51:05 -0600 (Thu, 02 Dec 2004)
New Revision: 448

Modified:
   trunk/fsck.ocfs2/include/fsck.h
   trunk/fsck.ocfs2/include/util.h
   trunk/fsck.ocfs2/pass2.c
   trunk/fsck.ocfs2/pass3.c
   trunk/fsck.ocfs2/pass4.c
   trunk/fsck.ocfs2/util.c
Log:
o reconnect disconnected inodes as /lost+found/#ino, like e2fsck
o add a helper to read an inode and get its file type from i_mode
o record lost+found's inode in our state
o fix a bug in the icount tracking after adding lost+found
o add info to minor assertion printf


Modified: trunk/fsck.ocfs2/include/fsck.h
===================================================================
--- trunk/fsck.ocfs2/include/fsck.h	2004-12-02 18:54:35 UTC (rev 447)
+++ trunk/fsck.ocfs2/include/fsck.h	2004-12-02 20:51:05 UTC (rev 448)
@@ -52,6 +52,7 @@
 	o2fsck_dirblocks	ost_dirblocks;
 
 	uint32_t	ost_fs_generation;
+	uint64_t	ost_lostfound_ino;
 
 	struct rb_root	ost_dir_parents;
 

Modified: trunk/fsck.ocfs2/include/util.h
===================================================================
--- trunk/fsck.ocfs2/include/util.h	2004-12-02 18:54:35 UTC (rev 447)
+++ trunk/fsck.ocfs2/include/util.h	2004-12-02 20:51:05 UTC (rev 448)
@@ -47,5 +47,7 @@
 void o2fsck_mark_cluster_allocated(o2fsck_state *ost, uint32_t cluster);
 void o2fsck_mark_clusters_allocated(o2fsck_state *ost, uint32_t cluster,
 				    uint32_t num);
+errcode_t o2fsck_type_from_dinode(o2fsck_state *ost, uint64_t ino,
+				  uint8_t *type);
 
 #endif /* __O2FSCK_UTIL_H__ */

Modified: trunk/fsck.ocfs2/pass2.c
===================================================================
--- trunk/fsck.ocfs2/pass2.c	2004-12-02 18:54:35 UTC (rev 447)
+++ trunk/fsck.ocfs2/pass2.c	2004-12-02 20:51:05 UTC (rev 448)
@@ -304,8 +304,6 @@
 static int fix_dirent_filetype(o2fsck_state *ost, o2fsck_dirblock_entry *dbe,
 				struct ocfs2_dir_entry *dirent, int offset)
 {
-	char *buf;
-	ocfs2_dinode *dinode;
 	uint8_t expected_type;
 	errcode_t err;
 	int was_set;
@@ -330,20 +328,10 @@
 		goto check;
 	}
 
-	err = ocfs2_malloc_block(ost->ost_fs->fs_io, &buf);
-	if (err)
-		fatal_error(err, "while allocating inode buffer to verify an "
-				"inode's file type");
+	err = o2fsck_type_from_dinode(ost, dirent->inode, &expected_type);
+	if (err) /* XXX propogate this? */
+		goto out;
 
-	err = ocfs2_read_inode(ost->ost_fs, dirent->inode, buf);
-	if (err)
-		fatal_error(err, "reading inode %"PRIu64" when verifying "
-			"an entry's file type", dirent->inode);
-
-	dinode = (ocfs2_dinode *)buf; 
-	expected_type = ocfs_type_by_mode[(dinode->i_mode & S_IFMT)>>S_SHIFT];
-	ocfs2_free(&buf);
-
 check:
 	if ((dirent->file_type != expected_type) &&
 	    prompt(ost, PY, 0, "Directory entry %.*s contains file type %s (%u) "
@@ -358,7 +346,7 @@
 		return OCFS2_DIRENT_CHANGED;
 	}
 
-
+out:
 	return 0;
 }
 

Modified: trunk/fsck.ocfs2/pass3.c
===================================================================
--- trunk/fsck.ocfs2/pass3.c	2004-12-02 18:54:35 UTC (rev 447)
+++ trunk/fsck.ocfs2/pass3.c	2004-12-02 20:51:05 UTC (rev 448)
@@ -30,6 +30,7 @@
  */
 #include <inttypes.h>
 #include <string.h>
+#include <limits.h>
 
 #include <ocfs2.h>
 
@@ -76,11 +77,11 @@
 {
 	char name[] = "lost+found";
 	int namelen = sizeof(name) - 1;
-	uint64_t blkno = 0;
+	uint64_t blkno;
 	errcode_t ret;
 
 	ret = ocfs2_lookup(ost->ost_fs, ost->ost_fs->fs_root_blkno, name,
-			   namelen, NULL, &blkno);
+			   namelen, NULL, &ost->ost_lostfound_ino);
 	if (ret == 0)
 		return;
 
@@ -88,7 +89,6 @@
 		    "that we an possibly fill it with orphaned inodes?"))
 		return;
 
-	blkno = 0;
 	ret = ocfs2_new_inode(ost->ost_fs, &blkno, 0755 | S_IFDIR);
 	if (ret) {
 		com_err(whoami, ret, "while trying to allocate a new inode "
@@ -113,8 +113,6 @@
 		goto out;
 	}
 
-	blkno = 0;
-
 	/* XXX maybe this should be a helper to clean up the dir tracking
 	 * for any new dir.  "2" for both the l+f dirent pointing to the
 	 * inode and the "." dirent in its dirblock */
@@ -126,6 +124,8 @@
 	/* we've already iterated through the dirblocks in pass2 so there
 	 * is no need to register l+f's new dir block */
 
+	ost->ost_lostfound_ino = blkno;
+	blkno = 0;
 out:
 	if (blkno) {
 		ret = ocfs2_delete_inode(ost->ost_fs, blkno);
@@ -199,18 +199,74 @@
 /* add a directory entry that points to a given inode in lost+found. */
 void o2fsck_reconnect_file(o2fsck_state *ost, uint64_t inode)
 {
+	static char iname[NAME_MAX + 1];
+	char name[] = "lost+found";
+	int namelen = sizeof(name) - 1;
 	o2fsck_dir_parent *dp;
-	fatal_error(OCFS2_ET_INTERNAL_FAILURE, "not implemented yet");
-	/* up the icount ref */
-	dp = o2fsck_dir_parent_lookup(&ost->ost_dir_parents,
-				dp->dp_ino);
-	if (dp == NULL)
-		fatal_error(OCFS2_ET_INTERNAL_FAILURE,
-				"no dir parents for reconnected inode "
-				"%"PRIu64, dp->dp_ino);
-	dp->dp_dirent = 1/* XXX lost and found */;
-	fix_dot_dot(ost, dp);
-	/* XXX mark invalid if this fails */
+	errcode_t ret;
+	uint8_t type;
+	int len;
+
+	if (ost->ost_lostfound_ino == 0) {
+		ret = ocfs2_lookup(ost->ost_fs, ost->ost_fs->fs_root_blkno,
+				   name, namelen, NULL,
+				   &ost->ost_lostfound_ino);
+		if (ret) {
+			com_err(whoami, ret, "while trying to find the "
+				"/lost+found directory so that inode "
+				"%"PRIu64" could be moved there.", inode);
+			goto out;
+		}
+	}
+
+	len = snprintf(iname, sizeof(iname), "#%"PRIu64, inode);
+	if (len <= 0) {
+		ret = OCFS2_ET_NO_MEMORY;
+		com_err(whoami, ret, "while trying to build a new file name "
+			"for inode %"PRIu64" to use in /lost+found", inode);
+		goto out;
+	}
+
+	ret = o2fsck_type_from_dinode(ost, inode, &type);
+	if (ret)
+		goto out;
+
+	/* XXX I gotta say, ocfs2_link_and_expand() seems pretty reasonable */
+	ret = ocfs2_link(ost->ost_fs, ost->ost_lostfound_ino, iname, inode,
+			 type);
+	if (ret) {
+		if (ret == OCFS2_ET_DIR_NO_SPACE) {
+			ret = ocfs2_expand_dir(ost->ost_fs,
+					       ost->ost_lostfound_ino,
+					       ost->ost_fs->fs_root_blkno);
+			if (ret == 0)
+				ret = ocfs2_link(ost->ost_fs,
+						 ost->ost_lostfound_ino,
+						 iname, inode, type);
+		}
+		com_err(whoami, ret, "while trying to link inode %"PRIu64" "
+			"into /lost+found", inode);
+		goto out;
+	}
+
+	/* add another ref to account for this new dirent */
+	o2fsck_icount_delta(ost->ost_icount_refs, inode, 1);
+
+	/* if we just added a directory to l+f we need to track that 
+	 * the new dirent points to the dir.  we leave the dot_dot tracking
+	 * intact because we didn't change that in the dirblock.. */
+	if (type == OCFS2_FT_DIR) {
+		dp = o2fsck_dir_parent_lookup(&ost->ost_dir_parents, inode);
+		if (dp == NULL) {
+			ret = OCFS2_ET_INTERNAL_FAILURE;
+			com_err(whoami, ret, "while looking up the directory "
+				"parent structure for inode %"PRIu64, inode);
+			goto out;
+		}
+		dp->dp_dirent = ost->ost_lostfound_ino;
+	}
+
+out:
 	return;
 }
 

Modified: trunk/fsck.ocfs2/pass4.c
===================================================================
--- trunk/fsck.ocfs2/pass4.c	2004-12-02 18:54:35 UTC (rev 447)
+++ trunk/fsck.ocfs2/pass4.c	2004-12-02 20:51:05 UTC (rev 448)
@@ -119,7 +119,10 @@
 
 		if (ref_ret != inode_ret || ref_blkno != inode_blkno) {
 			printf("fsck's internal inode link count tracking "
-			       "isn't consistent\n");
+			       "isn't consistent. (ref_ret = %d ref_blkno = "
+			       "%"PRIu64" inode_ret = %d inode_blkno = "
+			       "%"PRIu64"\n", (int)ref_ret, ref_blkno,
+			       (int)inode_ret, inode_blkno);
 			ret = OCFS2_ET_INTERNAL_FAILURE;
 			break;
 		}

Modified: trunk/fsck.ocfs2/util.c
===================================================================
--- trunk/fsck.ocfs2/util.c	2004-12-02 18:54:35 UTC (rev 447)
+++ trunk/fsck.ocfs2/util.c	2004-12-02 20:51:05 UTC (rev 448)
@@ -68,3 +68,36 @@
 	while(num--)
 		o2fsck_mark_cluster_allocated(ost, cluster++);
 }
+
+errcode_t o2fsck_type_from_dinode(o2fsck_state *ost, uint64_t ino,
+				  uint8_t *type)
+{
+	char *buf = NULL;
+	errcode_t ret;
+	ocfs2_dinode *dinode;
+	char *whoami = __FUNCTION__;
+
+	*type = 0;
+
+	ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &buf);
+	if (ret) {
+		com_err(whoami, ret, "while allocating an inode buffer to "
+			"read and discover the type of inode %"PRIu64, ino);
+		goto out;
+	}
+
+	ret = ocfs2_read_inode(ost->ost_fs, ino, buf);
+	if (ret) {
+		com_err(whoami, ret, "while reading inode %"PRIu64" to "
+			"discover its file type", ino);
+		goto out;
+	}
+
+	dinode = (ocfs2_dinode *)buf; 
+	*type = ocfs_type_by_mode[(dinode->i_mode & S_IFMT)>>S_SHIFT];
+
+out:
+	if (buf)
+		ocfs2_free(&buf);
+	return ret;
+}



More information about the Ocfs2-tools-commits mailing list