OSDN Git Service

libext2fs: display partial path if fs corrupted in ext2fs_get_pathname()
authorTheodore Ts'o <tytso@mit.edu>
Tue, 17 Jan 2012 20:38:31 +0000 (15:38 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 17 Jan 2012 20:38:31 +0000 (15:38 -0500)
The function ext2fs_get_pathname() used to return EXT2_ET_NO_DIRECTORY
if one of the directories in an inode's pathname is not a directory.
This is not very useful in an emergency, when the file system is
corrupted.  This commit will cause ext2fs_get_pathname() to return a
partial pathname, which should help system administrators trying to
use debugfs to investigate a corrupted file system.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
lib/ext2fs/get_pathname.c
tests/f_badroot/expect.1
tests/f_dupdot/expect.1
tests/f_expand/expect.1.gz
tests/f_orphan_dotdot_ft/expect.1

index e259eee..3320994 100644 (file)
@@ -74,7 +74,7 @@ static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir,
                                         char *buf, char **name)
 {
        struct get_pathname_struct gp;
-       char    *parent_name, *ret;
+       char    *parent_name = 0, *ret;
        errcode_t       retval;
 
        if (dir == ino) {
@@ -99,7 +99,19 @@ static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir,
        gp.errcode = 0;
 
        retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp);
-       if (retval)
+       if (retval == EXT2_ET_NO_DIRECTORY) {
+               char buf[32];
+
+               if (ino)
+                       snprintf(buf, sizeof(buf), "<%u>/<%u>", dir, ino);
+               else
+                       snprintf(buf, sizeof(buf), "<%u>", dir);
+               retval = ext2fs_get_mem(strlen(buf)+1, name);
+               if (retval)
+                       goto cleanup;
+               strcpy(*name, buf);
+               return 0;
+       } else if (retval)
                goto cleanup;
        if (gp.errcode) {
                retval = gp.errcode;
@@ -132,12 +144,11 @@ static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir,
        else
                strcat(ret, "???");
        *name = ret;
-       ext2fs_free_mem(&parent_name);
        retval = 0;
 
 cleanup:
-       if (gp.name)
-               ext2fs_free_mem(&gp.name);
+       ext2fs_free_mem(&parent_name);
+       ext2fs_free_mem(&gp.name);
        return retval;
 }
 
index 66ff32e..f9d01e5 100644 (file)
@@ -4,7 +4,7 @@ Pass 1: Checking inodes, blocks, and sizes
 Root inode is not a directory.  Clear? yes
 
 Pass 2: Checking directory structure
-Entry '..' in ??? (11) has deleted/unused inode 2.  Clear? yes
+Entry '..' in <2>/<11> (11) has deleted/unused inode 2.  Clear? yes
 
 Pass 3: Checking directory connectivity
 Root inode not allocated.  Allocate? yes
index 611f870..afce8d6 100644 (file)
@@ -1,9 +1,9 @@
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
-Entry '.' in ??? (12) is duplicate '.' entry.
+Entry '.' in <14>/<12> (12) is duplicate '.' entry.
 Fix? yes
 
-Entry '..' in ??? (12) is duplicate '..' entry.
+Entry '..' in <14>/<12> (12) is duplicate '..' entry.
 Fix? yes
 
 Pass 3: Checking directory connectivity
index 91799bb..1015e15 100644 (file)
Binary files a/tests/f_expand/expect.1.gz and b/tests/f_expand/expect.1.gz differ
index ac309e8..6a1373f 100644 (file)
@@ -7,23 +7,23 @@ Pass 2: Checking directory structure
 Entry 'dir' in / (2) has an incorrect filetype (was 2, should be 6).
 Fix? yes
 
-Entry '..' in ??? (13) has an incorrect filetype (was 2, should be 6).
+Entry '..' in <12>/<13> (13) has an incorrect filetype (was 2, should be 6).
 Fix? yes
 
-Entry '..' in ??? (14) has an incorrect filetype (was 2, should be 6).
+Entry '..' in <12>/<14> (14) has an incorrect filetype (was 2, should be 6).
 Fix? yes
 
-Entry '..' in ??? (15) has an incorrect filetype (was 2, should be 6).
+Entry '..' in <12>/<15> (15) has an incorrect filetype (was 2, should be 6).
 Fix? yes
 
 Pass 3: Checking directory connectivity
-Unconnected directory inode 13 (???)
+Unconnected directory inode 13 (<12>/<13>)
 Connect to /lost+found? yes
 
-Unconnected directory inode 14 (???)
+Unconnected directory inode 14 (<12>/<14>)
 Connect to /lost+found? yes
 
-Unconnected directory inode 15 (???)
+Unconnected directory inode 15 (<12>/<15>)
 Connect to /lost+found? yes
 
 Pass 4: Checking reference counts