[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