diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in index 50a21e528..9b402f0e8 100644 --- a/debugfs/Makefile.in +++ b/debugfs/Makefile.in @@ -21,11 +21,11 @@ DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \ lsdel.o dump.o set_fields.o logdump.o htree.o unused.o e2freefrag.o \ filefrag.o extent_cmds.o extent_inode.o zap.o create_inode.o \ create_inode_libarchive.o quota.o xattrs.o journal.o revoke.o \ - recovery.o do_journal.o + recovery.o do_journal.o do_orphan.o RO_DEBUG_OBJS= ro_debug_cmds.o ro_debugfs.o util.o ncheck.o icheck.o ls.o \ lsdel.o logdump.o htree.o e2freefrag.o filefrag.o extent_cmds.o \ - extent_inode.o quota.o xattrs.o + extent_inode.o quota.o xattrs.o do_orphan.o SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \ $(srcdir)/ncheck.c $(srcdir)/icheck.c $(srcdir)/lsdel.c \ @@ -35,7 +35,8 @@ SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \ $(srcdir)/../misc/create_inode.c \ $(srcdir)/../misc/create_inode_libarchive.c $(srcdir)/xattrs.c \ $(srcdir)/quota.c $(srcdir)/journal.c $(srcdir)/../e2fsck/revoke.c \ - $(srcdir)/../e2fsck/recovery.c $(srcdir)/do_journal.c + $(srcdir)/../e2fsck/recovery.c $(srcdir)/do_journal.c \ + $(srcdir)/do_orphan.c LIBS= $(LIBSUPPORT) $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \ $(LIBUUID) $(LIBMAGIC) $(SYSLIBS) $(LIBARCHIVE) @@ -367,9 +368,9 @@ create_inode.o: $(srcdir)/../misc/create_inode.c $(top_builddir)/lib/config.h \ $(srcdir)/../misc/create_inode_libarchive.h create_inode_libarchive.o: $(srcdir)/../misc/create_inode_libarchive.c \ $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \ - $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/../misc/create_inode.h \ - $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \ - $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \ + $(srcdir)/../misc/create_inode.h $(top_srcdir)/lib/et/com_err.h \ + $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \ + $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \ $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/ext2fs/ext2_io.h \ $(top_builddir)/lib/ext2fs/ext2_err.h \ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \ @@ -443,3 +444,14 @@ do_journal.o: $(srcdir)/do_journal.c $(top_builddir)/lib/config.h \ $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \ $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \ $(srcdir)/journal.h $(srcdir)/../e2fsck/jfs_user.h +do_orphan.o: $(srcdir)/do_orphan.c $(top_builddir)/lib/config.h \ + $(top_builddir)/lib/dirpaths.h $(srcdir)/debugfs.h $(top_srcdir)/lib/ss/ss.h \ + $(top_builddir)/lib/ss/ss_err.h $(top_srcdir)/lib/et/com_err.h \ + $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \ + $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \ + $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \ + $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \ + $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/../misc/create_inode.h \ + $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/support/quotaio.h \ + $(top_srcdir)/lib/support/dqblk_v2.h \ + $(top_srcdir)/lib/support/quotaio_tree.h diff --git a/debugfs/debug_cmds.ct b/debugfs/debug_cmds.ct index 1ff6c9dcd..f23ec3353 100644 --- a/debugfs/debug_cmds.ct +++ b/debugfs/debug_cmds.ct @@ -229,5 +229,8 @@ request do_journal_write, "Write a transaction to the journal", request do_journal_run, "Recover the journal", journal_run, jr; +request do_orphan_inodes, "List the orphan inodes on the file system", + orphan_inodes, orphan; + end; diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in index 2066c0f1d..08f41fdfa 100644 --- a/debugfs/debugfs.8.in +++ b/debugfs/debugfs.8.in @@ -643,6 +643,9 @@ flag causes the file system to be opened in exclusive mode. The options behave the same as the command-line options to .BR debugfs . .TP +.B orphan_inodes +List the orphan inodes in the file system. +.TP .BI punch " filespec start_blk [end_blk]" Delete the blocks in the inode ranging from .I start_blk diff --git a/debugfs/debugfs.h b/debugfs/debugfs.h index 88d929cbf..cbeb6f676 100644 --- a/debugfs/debugfs.h +++ b/debugfs/debugfs.h @@ -186,6 +186,9 @@ extern void do_journal_open(int argc, ss_argv_t argv, int sci_idx, void *infop); extern void do_journal_close(int argc, ss_argv_t argv, int sci_idx, void *infop); extern void do_journal_run(int argc, ss_argv_t argv, int sci_idx, void *infop); +/* orphan.c */ +extern void do_orphan_inodes(int argc, ss_argv_t argv, int sci_idx, void *infop); + /* quota.c */ extern void do_list_quota(int argc, ss_argv_t argv, int sci_idx, void *infop); extern void do_get_quota(int argc, ss_argv_t argv, int sci_idx, void *infop); diff --git a/debugfs/do_orphan.c b/debugfs/do_orphan.c new file mode 100644 index 000000000..ff1a03fdf --- /dev/null +++ b/debugfs/do_orphan.c @@ -0,0 +1,118 @@ +/* + * orphan.c --- list orphan inodes + * + */ + +#include "config.h" +#include +#include +#include + +#include "debugfs.h" + +/* + * Return 1 if there was an error, 0 on sucess + */ +static int print_orphan_inode(const char *progname, ext2_ino_t ino, + ext2_ino_t *next) +{ + struct ext2_inode inode; + + if (debugfs_read_inode(ino, &inode, progname)) + return 1; + printf("ino %-6u links_count %-3u size %-11llu\n", + ino, inode.i_links_count, + (unsigned long long) EXT2_I_SIZE(&inode)); + if (next) + *next = inode.i_dtime; + return 0; +} + +struct process_orphan_block_data { + const char *progname; + char *buf; + char *block_buf; + e2_blkcnt_t blocks; + int abort; + int clear; + errcode_t errcode; + ext2_ino_t ino; + __u32 generation; +}; + +static int process_orphan_block(ext2_filsys fs, + blk64_t *block_nr, + e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), + blk64_t ref_blk EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) +{ + struct process_orphan_block_data *pd = priv_data; + blk64_t blk = *block_nr; + __u32 *bdata; + int j, inodes_per_ob; + + inodes_per_ob = ext2fs_inodes_per_orphan_block(fs); + pd->errcode = io_channel_read_blk64(fs->io, blk, 1, pd->buf); + if (pd->errcode) { + pd->abort = 1; + return BLOCK_ABORT; + } + bdata = (__u32 *)pd->buf; + for (j = 0; j < inodes_per_ob; j++) { + if (!bdata[j]) + continue; + if (print_orphan_inode(pd->progname, + ext2fs_le32_to_cpu(bdata[j]), + NULL)) + break; + } + return 0; +} + + +void do_orphan_inodes(int argc, ss_argv_t argv, + int sci_idx EXT2FS_ATTR((unused)), + void *infop EXT2FS_ATTR((unused))) +{ + ext2_ino_t ino; + errcode_t retval; + struct process_orphan_block_data pd; + char *orphan_buf; + + if (check_fs_open(argv[0])) + return; + if (argc > 1) { + fprintf(stderr, "Usage: %s\n", argv[0]); + return; + } + ino = current_fs->super->s_last_orphan; + if (ino) + printf("Orphan inode list:\n"); + else + printf("Orphan inode list empty\n"); + while (ino) + if (print_orphan_inode(argv[0], ino, &ino)) + break; + if (!ext2fs_has_feature_orphan_file(current_fs->super)) + return; + printf("Dumping orphan file inode %u:\n", + current_fs->super->s_orphan_file_inum); + orphan_buf = malloc(current_fs->blocksize * 4); + if (!orphan_buf) { + fprintf(stderr, "Couldn't allocate orphan block buffer"); + return; + } + pd.buf = orphan_buf + 3 * current_fs->blocksize; + pd.progname = argv[0]; + retval = ext2fs_block_iterate3(current_fs, + current_fs->super->s_orphan_file_inum, + BLOCK_FLAG_DATA_ONLY, + orphan_buf, process_orphan_block, &pd); + if (retval) { + com_err(argv[0], retval, + "while calling ext2fs_block_iterate " + "for the orphan file"); + return; + } +} diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in index 1b3a91b6f..bd140e259 100644 --- a/lib/ext2fs/Makefile.in +++ b/lib/ext2fs/Makefile.in @@ -25,7 +25,8 @@ DEBUG_OBJS= debug_cmds.o extent_cmds.o tst_cmds.o debugfs.o util.o \ ncheck.o icheck.o ls.o lsdel.o dump.o set_fields.o logdump.o \ htree.o unused.o e2freefrag.o filefrag.o extent_inode.o zap.o \ xattrs.o quota.o tst_libext2fs.o create_inode.o \ - create_inode_libarchive.o journal.o revoke.o recovery.o do_journal.o + create_inode_libarchive.o journal.o revoke.o recovery.o \ + do_journal.o do_orphan.o DEBUG_SRCS= debug_cmds.c extent_cmds.c tst_cmds.c \ $(top_srcdir)/debugfs/debugfs.c \ @@ -50,7 +51,8 @@ DEBUG_SRCS= debug_cmds.c extent_cmds.c tst_cmds.c \ $(top_srcdir)/debugfs/journal.c \ $(top_srcdir)/e2fsck/revoke.c \ $(top_srcdir)/e2fsck/recovery.c \ - $(top_srcdir)/debugfs/do_journal.c + $(top_srcdir)/debugfs/do_journal.c \ + $(top_srcdir)/debugfs/do_orphan.c \ @TDB_CMT@TDB_OBJ= tdb.o @@ -453,6 +455,10 @@ do_journal.o: $(top_srcdir)/debugfs/do_journal.c $(E) " CC $<" $(Q) $(CC) $(DEBUGFS_CFLAGS) -c $< -o $@ +do_orphan.o: $(top_srcdir)/debugfs/do_orphan.c + $(E) " CC $<" + $(Q) $(CC) $(DEBUGFS_CFLAGS) -c $< -o $@ + xattrs.o: $(top_srcdir)/debugfs/xattrs.c $(E) " CC $<" $(Q) $(CC) $(DEBUGFS_CFLAGS) -c $< -o $@ @@ -1448,11 +1454,12 @@ create_inode.o: $(top_srcdir)/misc/create_inode.c \ $(top_srcdir)/misc/create_inode_libarchive.h create_inode_libarchive.o: $(top_srcdir)/misc/create_inode_libarchive.c \ $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \ - $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/misc/create_inode.h \ - $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \ - $(srcdir)/ext2_fs.h $(srcdir)/ext2fs.h $(srcdir)/ext3_extents.h \ - $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \ - $(srcdir)/ext2_ext_attr.h $(srcdir)/hashmap.h $(srcdir)/bitops.h \ + $(top_srcdir)/misc/create_inode.h $(top_srcdir)/lib/et/com_err.h \ + $(top_srcdir)/lib/e2p/e2p.h $(srcdir)/ext2_fs.h \ + $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \ + $(srcdir)/ext3_extents.h $(srcdir)/ext2_io.h \ + $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \ + $(srcdir)/hashmap.h $(srcdir)/bitops.h \ $(top_srcdir)/misc/create_inode_libarchive.h \ $(top_srcdir)/lib/support/nls-enable.h journal.o: $(top_srcdir)/debugfs/journal.c $(top_builddir)/lib/config.h \ @@ -1492,3 +1499,14 @@ do_journal.o: $(top_srcdir)/debugfs/do_journal.c $(top_builddir)/lib/config.h \ $(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/kernel-jbd.h \ $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h \ $(top_srcdir)/debugfs/journal.h $(srcdir)/../../e2fsck/jfs_user.h +do_orphan.o: $(top_srcdir)/debugfs/do_orphan.c $(top_builddir)/lib/config.h \ + $(top_builddir)/lib/dirpaths.h $(top_srcdir)/debugfs/debugfs.h \ + $(top_srcdir)/lib/ss/ss.h $(top_builddir)/lib/ss/ss_err.h \ + $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_fs.h \ + $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \ + $(srcdir)/ext3_extents.h $(srcdir)/ext2_io.h \ + $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \ + $(srcdir)/hashmap.h $(srcdir)/bitops.h \ + $(top_srcdir)/debugfs/../misc/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \ + $(top_srcdir)/lib/support/quotaio.h $(top_srcdir)/lib/support/dqblk_v2.h \ + $(top_srcdir)/lib/support/quotaio_tree.h