Whamcloud - gitweb
libext2fs: handle inline_data in block iterator function
[tools/e2fsprogs.git] / debugfs / debugfs.c
index cf7670b..29c0161 100644 (file)
@@ -181,7 +181,8 @@ void do_open_filesys(int argc, char **argv)
                                return;
                        break;
                case 's':
-                       err = strtoblk(argv[0], optarg, &superblock);
+                       err = strtoblk(argv[0], optarg,
+                                      "superblock block number", &superblock);
                        if (err)
                                return;
                        break;
@@ -284,12 +285,10 @@ void do_init_filesys(int argc, char **argv)
                return;
 
        memset(&param, 0, sizeof(struct ext2_super_block));
-       err = strtoblk(argv[0], argv[2], &blocks);
+       err = strtoblk(argv[0], argv[2], "blocks count", &blocks);
        if (err)
                return;
        ext2fs_blocks_count_set(&param, blocks);
-       if (err)
-               return;
        retval = ext2fs_initialize(argv[1], 0, &param,
                                   unix_io_manager, &current_fs);
        if (retval) {
@@ -373,8 +372,7 @@ void do_show_super_stats(int argc, char *argv[])
                return;
        }
 
-       gdt_csum = EXT2_HAS_RO_COMPAT_FEATURE(current_fs->super,
-                                             EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
+       gdt_csum = ext2fs_has_group_desc_csum(current_fs);
        for (i = 0; i < current_fs->group_desc_count; i++) {
                fprintf(out, " Group %2d: block bitmap at %llu, "
                        "inode bitmap at %llu, "
@@ -544,34 +542,45 @@ static void internal_dump_inode_extra(FILE *out,
                                inode->i_extra_isize);
                return;
        }
-       storage_size = EXT2_INODE_SIZE(current_fs->super) -
-                       EXT2_GOOD_OLD_INODE_SIZE -
-                       inode->i_extra_isize;
-       magic = (__u32 *)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
-                       inode->i_extra_isize);
-       if (*magic == EXT2_EXT_ATTR_MAGIC) {
-               fprintf(out, "Extended attributes stored in inode body: \n");
-               end = (char *) inode + EXT2_INODE_SIZE(current_fs->super);
-               start = (char *) magic + sizeof(__u32);
-               entry = (struct ext2_ext_attr_entry *) start;
-               while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
-                       struct ext2_ext_attr_entry *next =
-                               EXT2_EXT_ATTR_NEXT(entry);
-                       if (entry->e_value_size > storage_size ||
-                                       (char *) next >= end) {
-                               fprintf(out, "invalid EA entry in inode\n");
-                               return;
-                       }
-                       fprintf(out, "  ");
-                       dump_xattr_string(out, EXT2_EXT_ATTR_NAME(entry),
-                                         entry->e_name_len);
-                       fprintf(out, " = \"");
-                       dump_xattr_string(out, start + entry->e_value_offs,
-                                               entry->e_value_size);
-                       fprintf(out, "\" (%u)\n", entry->e_value_size);
-                       entry = next;
-               }
-       }
+}
+
+/* Dump extended attributes */
+static int dump_attr(char *name, char *value, size_t value_len, void *data)
+{
+       FILE *out = data;
+
+       fprintf(out, "  ");
+       dump_xattr_string(out, name, strlen(name));
+       fprintf(out, " = \"");
+       dump_xattr_string(out, value, value_len);
+       fprintf(out, "\" (%zu)\n", value_len);
+
+       return 0;
+}
+
+static void dump_inode_attributes(FILE *out, ext2_ino_t ino)
+{
+       struct ext2_xattr_handle *h;
+       errcode_t err;
+
+       err = ext2fs_xattrs_open(current_fs, ino, &h);
+       if (err)
+               return;
+
+       err = ext2fs_xattrs_read(h);
+       if (err)
+               goto out;
+
+       if (ext2fs_xattrs_count(h) == 0)
+               goto out;
+
+       fprintf(out, "Extended attributes:\n");
+       err = ext2fs_xattrs_iterate(h, dump_attr, out);
+       if (err)
+               goto out;
+
+out:
+       err = ext2fs_xattrs_close(&h);
 }
 
 static void dump_blocks(FILE *f, const char *prefix, ext2_ino_t inode)
@@ -819,6 +828,20 @@ void internal_dump_inode(FILE *out, const char *prefix,
        if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
                internal_dump_inode_extra(out, prefix, inode_num,
                                          (struct ext2_inode_large *) inode);
+       dump_inode_attributes(out, inode_num);
+       if (current_fs->super->s_creator_os == EXT2_OS_LINUX &&
+           current_fs->super->s_feature_ro_compat &
+               EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) {
+               __u32 crc = inode->i_checksum_lo;
+               if (is_large_inode &&
+                   large_inode->i_extra_isize >=
+                               (offsetof(struct ext2_inode_large,
+                                         i_checksum_hi) -
+                                EXT2_GOOD_OLD_INODE_SIZE))
+                       crc |= ((__u32)large_inode->i_checksum_hi) << 16;
+               fprintf(out, "Inode checksum: 0x%08x\n", crc);
+       }
+
        if (LINUX_S_ISLNK(inode->i_mode) && ext2fs_inode_data_blocks(current_fs,inode) == 0)
                fprintf(out, "%sFast_link_dest: %.*s\n", prefix,
                        (int) inode->i_size, (char *)inode->i_block);
@@ -1901,11 +1924,10 @@ static void kill_file_by_inode(ext2_ino_t inode)
        inode_buf.i_dtime = current_fs->now ? current_fs->now : time(0);
        if (debugfs_write_inode(inode, &inode_buf, 0))
                return;
-       if (!ext2fs_inode_has_valid_blocks2(current_fs, &inode_buf))
-               return;
-
-       ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, NULL,
-                             release_blocks_proc, NULL);
+       if (ext2fs_inode_has_valid_blocks2(current_fs, &inode_buf)) {
+               ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY,
+                                     NULL, release_blocks_proc, NULL);
+       }
        printf("\n");
        ext2fs_inode_alloc_stats2(current_fs, inode, -1,
                                  LINUX_S_ISDIR(inode_buf.i_mode));
@@ -1972,9 +1994,9 @@ static int rmdir_proc(ext2_ino_t dir EXT2FS_ATTR((unused)),
 
        if (dirent->inode == 0)
                return 0;
-       if (((dirent->name_len&0xFF) == 1) && (dirent->name[0] == '.'))
+       if ((ext2fs_dirent_name_len(dirent) == 1) && (dirent->name[0] == '.'))
                return 0;
-       if (((dirent->name_len&0xFF) == 2) && (dirent->name[0] == '.') &&
+       if ((ext2fs_dirent_name_len(dirent) == 2) && (dirent->name[0] == '.') &&
            (dirent->name[1] == '.')) {
                rds->parent = dirent->inode;
                return 0;
@@ -2100,7 +2122,7 @@ void do_bmap(int argc, char *argv[])
        ino = string_to_inode(argv[1]);
        if (!ino)
                return;
-       err = strtoblk(argv[0], argv[2], &blk);
+       err = strtoblk(argv[0], argv[2], "logical block", &blk);
        if (err)
                return;
 
@@ -2247,11 +2269,11 @@ void do_punch(int argc, char *argv[])
        ino = string_to_inode(argv[1]);
        if (!ino)
                return;
-       err = strtoblk(argv[0], argv[2], &start);
+       err = strtoblk(argv[0], argv[2], "logical block", &start);
        if (err)
                return;
        if (argc == 4) {
-               err = strtoblk(argv[0], argv[3], &end);
+               err = strtoblk(argv[0], argv[3], "logical block", &end);
                if (err)
                        return;
        } else
@@ -2313,6 +2335,7 @@ try_again:
 
 void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[])
 {
+#if CONFIG_MMP
        struct ext2_super_block *sb;
        struct mmp_struct *mmp_s;
        time_t t;
@@ -2351,6 +2374,11 @@ void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[])
        fprintf(stdout, "node_name: %s\n", mmp_s->mmp_nodename);
        fprintf(stdout, "device_name: %s\n", mmp_s->mmp_bdevname);
        fprintf(stdout, "magic: 0x%x\n", mmp_s->mmp_magic);
+       fprintf(stdout, "checksum: 0x%08x\n", mmp_s->mmp_checksum);
+#else
+       fprintf(stdout, "MMP is unsupported, please recompile with "
+                       "--enable-mmp\n");
+#endif
 }
 
 static int source_file(const char *cmd_file, int ss_idx)
@@ -2415,9 +2443,9 @@ int main(int argc, char **argv)
        int             catastrophic = 0;
        char            *data_filename = 0;
 #ifdef READ_ONLY
-       const char      *opt_string = "icR:f:b:s:Vd:D";
+       const char      *opt_string = "nicR:f:b:s:Vd:D";
 #else
-       const char      *opt_string = "iwcR:f:b:s:Vd:D";
+       const char      *opt_string = "niwcR:f:b:s:Vd:D";
 #endif
 
        if (debug_prog_name == 0)
@@ -2444,6 +2472,9 @@ int main(int argc, char **argv)
                case 'i':
                        open_flags |= EXT2_FLAG_IMAGE_FILE;
                        break;
+               case 'n':
+                       open_flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+                       break;
 #ifndef READ_ONLY
                case 'w':
                        open_flags |= EXT2_FLAG_RW;
@@ -2457,7 +2488,9 @@ int main(int argc, char **argv)
                                                "block size", 0);
                        break;
                case 's':
-                       retval = strtoblk(argv[0], optarg, &superblock);
+                       retval = strtoblk(argv[0], optarg,
+                                         "superblock block number",
+                                         &superblock);
                        if (retval)
                                return 1;
                        break;