UBIFS: improve inode dumping function
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Wed, 25 May 2011 14:32:42 +0000 (17:32 +0300)
committerArtem Bityutskiy <dedekind1@gmail.com>
Mon, 4 Jul 2011 07:54:26 +0000 (10:54 +0300)
Teach 'dbg_dump_inode()' dump directory entries for directory inodes.
This requires few additional changes:
1. The 'c' argument of 'dbg_dump_inode()' cannot be const any more.
2. Users of 'dbg_dump_inode()' should not have 'tnc_mutex' locked.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
fs/ubifs/debug.c
fs/ubifs/debug.h
fs/ubifs/tnc.c

index c9609a6..4a2170d 100644 (file)
@@ -91,6 +91,28 @@ static const char *get_key_type(int type)
        }
 }
 
+static const char *get_dent_type(int type)
+{
+       switch (type) {
+       case UBIFS_ITYPE_REG:
+               return "file";
+       case UBIFS_ITYPE_DIR:
+               return "dir";
+       case UBIFS_ITYPE_LNK:
+               return "symlink";
+       case UBIFS_ITYPE_BLK:
+               return "blkdev";
+       case UBIFS_ITYPE_CHR:
+               return "char dev";
+       case UBIFS_ITYPE_FIFO:
+               return "fifo";
+       case UBIFS_ITYPE_SOCK:
+               return "socket";
+       default:
+               return "unknown/invalid type";
+       }
+}
+
 static void sprintf_key(const struct ubifs_info *c, const union ubifs_key *key,
                        char *buffer)
 {
@@ -234,9 +256,13 @@ static void dump_ch(const struct ubifs_ch *ch)
        printk(KERN_DEBUG "\tlen            %u\n", le32_to_cpu(ch->len));
 }
 
-void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode)
+void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode)
 {
        const struct ubifs_inode *ui = ubifs_inode(inode);
+       struct qstr nm = { .name = NULL };
+       union ubifs_key key;
+       struct ubifs_dent_node *dent, *pdent = NULL;
+       int count = 2;
 
        printk(KERN_DEBUG "Dump in-memory inode:");
        printk(KERN_DEBUG "\tinode          %lu\n", inode->i_ino);
@@ -270,6 +296,32 @@ void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode)
        printk(KERN_DEBUG "\tlast_page_read %lu\n", ui->last_page_read);
        printk(KERN_DEBUG "\tread_in_a_row  %lu\n", ui->read_in_a_row);
        printk(KERN_DEBUG "\tdata_len       %d\n", ui->data_len);
+
+       if (!S_ISDIR(inode->i_mode))
+               return;
+
+       printk(KERN_DEBUG "List of directory entries:\n");
+       ubifs_assert(!mutex_is_locked(&c->tnc_mutex));
+
+       lowest_dent_key(c, &key, inode->i_ino);
+       while (1) {
+               dent = ubifs_tnc_next_ent(c, &key, &nm);
+               if (IS_ERR(dent)) {
+                       if (PTR_ERR(dent) != -ENOENT)
+                               printk(KERN_DEBUG "error %ld\n", PTR_ERR(dent));
+                       break;
+               }
+
+               printk(KERN_DEBUG "\t%d: %s (%s)\n",
+                      count++, dent->name, get_dent_type(dent->type));
+
+               nm.name = dent->name;
+               nm.len = le16_to_cpu(dent->nlen);
+               kfree(pdent);
+               pdent = dent;
+               key_read(c, &dent->key, &key);
+       }
+       kfree(pdent);
 }
 
 void dbg_dump_node(const struct ubifs_info *c, const void *node)
@@ -1167,12 +1219,14 @@ int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir)
                          "but calculated size is %llu", dir->i_ino,
                          (unsigned long long)i_size_read(dir),
                          (unsigned long long)size);
+               dbg_dump_inode(c, dir);
                dump_stack();
                return -EINVAL;
        }
        if (dir->i_nlink != nlink) {
                ubifs_err("directory inode %lu has nlink %u, but calculated "
                          "nlink is %u", dir->i_ino, dir->i_nlink, nlink);
+               dbg_dump_inode(c, dir);
                dump_stack();
                return -EINVAL;
        }
index b59c43a..c6ad9ea 100644 (file)
@@ -214,7 +214,7 @@ const char *dbg_cstate(int cmt_state);
 const char *dbg_jhead(int jhead);
 const char *dbg_get_key_dump(const struct ubifs_info *c,
                             const union ubifs_key *key);
-void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode);
+void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode);
 void dbg_dump_node(const struct ubifs_info *c, const void *node);
 void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum,
                       int offs);
@@ -364,7 +364,7 @@ static inline const char *dbg_jhead(int jhead)                    { return ""; }
 static inline const char *
 dbg_get_key_dump(const struct ubifs_info *c,
                 const union ubifs_key *key)                      { return ""; }
-static inline void dbg_dump_inode(const struct ubifs_info *c,
+static inline void dbg_dump_inode(struct ubifs_info *c,
                                  const struct inode *inode)      { return; }
 static inline void dbg_dump_node(const struct ubifs_info *c,
                                 const void *node)                { return; }
@@ -418,7 +418,7 @@ static inline int dbg_chk_lpt_sz(struct ubifs_info *c,
                                 int action, int len)             { return 0; }
 static inline int dbg_check_synced_i_size(struct inode *inode)    { return 0; }
 static inline int dbg_check_dir_size(struct ubifs_info *c,
-                                    const struct inode *dir)     { return 0; }
+                               const struct inode *dir)          { return 0; }
 static inline int dbg_check_tnc(struct ubifs_info *c, int extra)  { return 0; }
 static inline int dbg_check_idx_size(struct ubifs_info *c,
                                     long long idx_size)          { return 0; }
index 91b4213..48b6ee6 100644 (file)
@@ -3337,9 +3337,10 @@ out_dump:
        ubifs_err("inode %lu has size %lld, but there are data at offset %lld "
                  "(data key %s)", (unsigned long)inode->i_ino, size,
                  ((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key));
+       mutex_unlock(&c->tnc_mutex);
        dbg_dump_inode(c, inode);
        dbg_dump_stack();
-       err = -EINVAL;
+       return -EINVAL;
 
 out_unlock:
        mutex_unlock(&c->tnc_mutex);