#ifndef lint
static const char rcsid[] =
- "$Id: traverse.c,v 1.31 2001/03/28 12:59:48 stelian Exp $";
+ "$Id: traverse.c,v 1.39 2001/11/11 00:06:39 stelian Exp $";
#endif /* not lint */
#include <config.h>
#include <sys/param.h>
#include <sys/stat.h>
#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
#include <linux/ext2_fs.h>
+#endif
#include <ext2fs/ext2fs.h>
#include <bsdcompat.h>
#include <compaterr.h>
static int searchdir __P((dump_ino_t ino, daddr_t blkno, long size, long filesize));
#endif
static void mapfileino __P((dump_ino_t ino, struct dinode const *dp, long *tapesize, int *dirskipped));
-static int exclude_ino __P((dump_ino_t ino));
-extern dump_ino_t iexclude_list[IEXCLUDE_MAXNUM]; /* the inode exclude list */
-extern int iexclude_num; /* number of elements in list */
#ifdef HAVE_EXT2_JOURNAL_INUM
#define ext2_journal_ino(sb) (sb->s_journal_inum)
else {
if (es->s_feature_compat &
EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
- journal_ino && !exclude_ino(journal_ino)) {
- iexclude_list[iexclude_num++] = journal_ino;
- msg("Exclude ext3 journal inode %u\n",
- journal_ino);
- }
- if (!exclude_ino(EXT2_RESIZE_INO))
- iexclude_list[iexclude_num++] = EXT2_RESIZE_INO;
+ journal_ino)
+ do_exclude_ino(journal_ino, "journal inode");
+ do_exclude_ino(EXT2_RESIZE_INO, "resize inode");
}
}
return retval;
return (blkest + 1);
}
-/*
- * This tests whether an inode is in the exclude list
- */
-int
-exclude_ino(dump_ino_t ino)
-{
- /* 04-Feb-00 ILC */
- if (iexclude_num) { /* if there are inodes in the exclude list */
- int idx; /* then check this inode against it */
- for (idx = 0; idx < iexclude_num; idx++)
- if (ino == iexclude_list[idx])
- return 1;
- }
- return 0;
-}
-
/* Auxiliary macro to pick up files changed since previous dump. */
#define CHANGEDSINCE(dp, t) \
((dp)->di_mtime >= (t) || (dp)->di_ctime >= (t))
}
#endif /* __linux__ */
+#ifdef __linux__
+int
+maponefile(dump_ino_t maxino, long *tapesize, char *directory)
+{
+ errcode_t retval;
+ ext2_ino_t dir_ino;
+ char dir_name [MAXPATHLEN];
+ int i, anydirskipped = 0;
+
+ /*
+ * Mark every directory in the path as being dumped
+ */
+ for (i = 0; i < strlen (directory); i++) {
+ if (directory[i] == '/') {
+ strncpy (dir_name, directory, i);
+ dir_name[i] = '\0';
+ retval = ext2fs_namei(fs, ROOTINO, ROOTINO,
+ dir_name, &dir_ino);
+ if (retval) {
+ com_err(disk, retval,
+ "while translating %s", dir_name);
+ exit(X_ABORT);
+ }
+ mapfileino((dump_ino_t) dir_ino, 0,
+ tapesize, &anydirskipped);
+ }
+ }
+ /*
+ * Mark the final directory
+ */
+ retval = ext2fs_namei(fs, ROOTINO, ROOTINO, directory, &dir_ino);
+ if (retval) {
+ com_err(disk, retval, "while translating %s", directory);
+ exit(X_ABORT);
+ }
+ mapfileino((dump_ino_t)dir_ino, 0, tapesize, &anydirskipped);
+
+ mapfileino(ROOTINO, 0, tapesize, &anydirskipped);
+
+ /*
+ * Restore gets very upset if the root is not dumped,
+ * so ensure that it always is dumped.
+ */
+ SETINO(ROOTINO, dumpdirmap);
+ return anydirskipped;
+}
+#endif /* __linux__ */
+
#ifdef __linux__
struct mapfile_context {
long *tapesize;
dumpino(struct dinode *dp, dump_ino_t ino)
{
unsigned long cnt;
- fsizeT size;
+ fsizeT size, remaining;
char buf[TP_BSIZE];
struct old_bsd_inode obi;
+ int i;
#ifdef __linux__
struct block_context bc;
#else
bc.next_block = NDADDR;
ext2fs_block_iterate2(fs, (ext2_ino_t)ino, 0, NULL, dumponeblock, (void *)&bc);
+ /* deal with holes at the end of the inode */
+ if (i_size > ((u_quad_t)bc.next_block) * sblock->fs_fsize) {
+ remaining = i_size - ((u_quad_t)bc.next_block) * sblock->fs_fsize;
+ for (i = 0; i < howmany(remaining, sblock->fs_fsize); i++) {
+ bc.buf[bc.cnt++] = 0;
+ if (bc.cnt == bc.max) {
+ blksout (bc.buf, bc.cnt, bc.ino);
+ bc.cnt = 0;
+ }
+ }
+ }
if (bc.cnt > 0) {
blksout (bc.buf, bc.cnt, bc.ino);
}
/*
* Read a chunk of data from the disk.
* Try to recover from hard errors by reading in sector sized pieces.
- * Error recovery is attempted at most BREADEMAX times before seeking
+ * Error recovery is attempted at most breademax times before seeking
* consent from the operator to continue.
*/
int breaderrors = 0;
-#define BREADEMAX 32
void
bread(daddr_t blkno, char *buf, int size)
else
msg("short read error from %s: [block %d]: count=%d, got=%d\n",
disk, blkno, size, cnt);
- if (++breaderrors > BREADEMAX) {
+ if (++breaderrors > breademax) {
msg("More than %d block read errors from %d\n",
- BREADEMAX, disk);
+ breademax, disk);
broadcast("DUMP IS AILING!\n");
msg("This is an unrecoverable error.\n");
if (!query("Do you want to attempt to continue?")){