/* * dump_dir_block() * */ void dump_dir_block(FILE *out, char *buf) { struct ocfs2_dir_entry *dirent; int offset = 0; int end = ocfs2_dir_trailer_blk_off(gbls.fs); struct ocfs2_dir_block_trailer *trailer = ocfs2_dir_trailer_from_block(gbls.fs, buf); struct list_dir_opts ls_opts = { .fs = gbls.fs, .out = out, }; if (!strncmp((char *)trailer->db_signature, OCFS2_DIR_TRAILER_SIGNATURE, sizeof(trailer->db_signature))) dump_dir_trailer(out, trailer); else end = gbls.fs->fs_blocksize; fprintf(out, "\tEntries:\n"); while (offset < end) { dirent = (struct ocfs2_dir_entry *) (buf + offset); if (((offset + dirent->rec_len) > end) || (dirent->rec_len < 8) || ((dirent->rec_len % 4) != 0) || (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) { /* Corrupted */ return; } dump_dir_entry(dirent, 0, offset, gbls.fs->fs_blocksize, NULL, &ls_opts); offset += dirent->rec_len; } } static void dump_dx_entry(FILE *out, int i, struct ocfs2_dx_entry *dx_entry) { fprintf(out, "\t %-2d (0x%08x 0x%08x) %-13"PRIu64"\n", i, dx_entry->dx_major_hash, dx_entry->dx_minor_hash, (uint64_t)dx_entry->dx_dirent_blk); }
errcode_t ocfs2_convert_inline_data_to_extents(ocfs2_cached_inode *ci) { errcode_t ret; uint32_t bytes, n_clusters; uint64_t p_start; char *inline_data = NULL; struct ocfs2_dinode *di = ci->ci_inode; ocfs2_filesys *fs = ci->ci_fs; uint64_t bpc = fs->fs_clustersize/fs->fs_blocksize; unsigned int new_size; if (di->i_size) { ret = ocfs2_malloc_block(fs->fs_io, &inline_data); if (ret) goto out; ret = ocfs2_inline_data_read(di, inline_data, fs->fs_blocksize, 0, &bytes); if (ret) goto out; } ocfs2_dinode_new_extent_list(fs, di); di->i_dyn_features &= ~OCFS2_INLINE_DATA_FL; ret = ocfs2_new_clusters(fs, 1, 1, &p_start, &n_clusters); if (ret || n_clusters == 0) goto out; ret = empty_blocks(fs, p_start, bpc); if (ret) goto out; if (di->i_size) { if (S_ISDIR(di->i_mode)) { if (ocfs2_supports_dir_trailer(fs)) new_size = ocfs2_dir_trailer_blk_off(fs); else new_size = fs->fs_blocksize; ocfs2_expand_last_dirent(inline_data, di->i_size, new_size); if (ocfs2_supports_dir_trailer(fs)) ocfs2_init_dir_trailer(fs, di, p_start, inline_data); di->i_size = fs->fs_blocksize; ret = ocfs2_write_dir_block(fs, di, p_start, inline_data); } else ret = io_write_block(fs->fs_io, p_start, 1, inline_data); if (ret) goto out; } ret = ocfs2_cached_inode_insert_extent(ci, 0, p_start, n_clusters, 0); if (ret) goto out; ret = ocfs2_write_cached_inode(fs, ci); out: if (inline_data) ocfs2_free(&inline_data); return ret; }
/* * dump_jbd_metadata() * */ void dump_jbd_metadata(FILE *out, enum ocfs2_block_type type, char *buf, uint64_t blknum) { struct ocfs2_dir_block_trailer *trailer; struct ocfs2_xattr_block *xb; struct ocfs2_xattr_header *xh; struct ocfs2_refcount_block *rb; struct ocfs2_dx_root_block *dx_root; struct ocfs2_dx_leaf *dx_leaf; struct ocfs2_dinode *di; struct ocfs2_extent_block *eb; fprintf(out, "\tBlock %"PRIu64": ", blknum); switch (type) { case OCFS2_BLOCK_INODE: case OCFS2_BLOCK_SUPERBLOCK: fprintf(out, "Inode\n"); di = (struct ocfs2_dinode *)buf; ocfs2_swap_inode_to_cpu(gbls.fs, di); dump_inode(out, di); if (di->i_flags & OCFS2_LOCAL_ALLOC_FL) dump_local_alloc(out, &(di->id2.i_lab)); else if (di->i_flags & OCFS2_CHAIN_FL) dump_chain_list(out, &(di->id2.i_chain)); else if (S_ISLNK(di->i_mode) && !di->i_clusters) dump_fast_symlink(out, (char *)di->id2.i_symlink); else if (di->i_flags & OCFS2_DEALLOC_FL) dump_truncate_log(out, &(di->id2.i_dealloc)); else if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL)) dump_extent_list(out, &(di->id2.i_list)); fprintf(out, "\n"); break; case OCFS2_BLOCK_EXTENT_BLOCK: fprintf(out, "Extent\n"); eb = (struct ocfs2_extent_block *)buf; ocfs2_swap_extent_block_to_cpu(gbls.fs, eb); dump_extent_block(out, eb); dump_extent_list(out, &(eb->h_list)); fprintf(out, "\n"); break; case OCFS2_BLOCK_GROUP_DESCRIPTOR: fprintf(out, "Group\n"); ocfs2_swap_group_desc_to_cpu(gbls.fs, (struct ocfs2_group_desc *)buf); dump_group_descriptor(out, (struct ocfs2_group_desc *)buf, 0); fprintf(out, "\n"); break; case OCFS2_BLOCK_DIR_BLOCK: fprintf(out, "Dirblock\n"); /* * We know there's a trailer, because that's how it * was detected */ ocfs2_swap_dir_entries_to_cpu(buf, ocfs2_dir_trailer_blk_off(gbls.fs)); trailer = ocfs2_dir_trailer_from_block(gbls.fs, buf); ocfs2_swap_dir_trailer(trailer); dump_dir_block(out, buf); fprintf(out, "\n"); break; case OCFS2_BLOCK_XATTR: fprintf(out, "Xattr\n"); xb = (struct ocfs2_xattr_block *)buf; ocfs2_swap_xattr_block_to_cpu(gbls.fs, xb); if (!(xb->xb_flags & OCFS2_XATTR_INDEXED)) { xh = &xb->xb_attrs.xb_header; dump_xattr(out, xh); } fprintf(out, "\n"); break; case OCFS2_BLOCK_REFCOUNT: fprintf(out, "Refcount\n"); rb = (struct ocfs2_refcount_block *)buf; ocfs2_swap_refcount_block_to_cpu(gbls.fs, rb); dump_refcount_block(out, rb); fprintf(out, "\n"); break; case OCFS2_BLOCK_DXROOT: fprintf(out, "DxRoot\n"); dx_root = (struct ocfs2_dx_root_block *)buf; ocfs2_swap_dx_root_to_cpu(gbls.fs, dx_root); dump_dx_root(out, dx_root); fprintf(out, "\n"); break; case OCFS2_BLOCK_DXLEAF: fprintf(out, "DxLeaf\n"); dx_leaf = (struct ocfs2_dx_leaf *)buf; ocfs2_swap_dx_leaf_to_cpu(dx_leaf); dump_dx_leaf(out, dx_leaf); fprintf(out, "\n"); break; default: fprintf(out, "TODO\n\n"); break; } return ; }