]> git.wh0rd.org - dump.git/blobdiff - dump/traverse.c
Fix nodump or exclude inodes propagation on directory tree.
[dump.git] / dump / traverse.c
index 147717ad37095eb80a40032550f92f39ec80ac6e..09bcded2f35e22e261255596253205179e889a4f 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: traverse.c,v 1.42 2002/01/25 15:08:59 stelian Exp $";
+       "$Id: traverse.c,v 1.46 2002/05/16 21:22:36 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -143,15 +143,14 @@ int dump_fs_open(const char *disk, ext2_filsys *fs)
                dump_ino_t journal_ino = ext2_journal_ino(es);
 
                if (es->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV){
-                       fprintf(stderr, "This an journal, not a filesystem!\n");
+                       msg("This is a journal, not a filesystem!\n");
                        retval = EXT2_ET_UNSUPP_FEATURE;
                        ext2fs_close(*fs);
                }
                else if ((retval = es->s_feature_incompat &
                                        ~(EXT2_LIB_FEATURE_INCOMPAT_SUPP |
                                          EXT3_FEATURE_INCOMPAT_RECOVER))) {
-                       fprintf(stderr,
-                               "Unsupported feature(s) 0x%x in filesystem\n",
+                       msg("Unsupported feature(s) 0x%x in filesystem\n",
                                retval);
                        retval = EXT2_ET_UNSUPP_FEATURE;
                        ext2fs_close(*fs);
@@ -218,8 +217,12 @@ blockest(struct dinode const *dp)
 }
 
 /* Auxiliary macro to pick up files changed since previous dump. */
+#define CSINCE(dp, t) \
+       ((dp)->di_ctime >= (t))
+#define MSINCE(dp, t) \
+       ((dp)->di_mtime >= (t))
 #define        CHANGEDSINCE(dp, t) \
-       ((dp)->di_mtime >= (t) || (dp)->di_ctime >= (t))
+       (CSINCE(dp, t) || MSINCE(dp, t))
 
 /* The NODUMP_FLAG macro tests if a file has the nodump flag. */
 #ifdef UF_NODUMP
@@ -267,6 +270,8 @@ mapfileino(dump_ino_t ino, struct dinode const *dp, long *tapesize, int *dirskip
                SETINO(ino, dumpdirmap);
        if (WANTTODUMP(dp, ino)) {
                SETINO(ino, dumpinomap);
+               if (!MSINCE(dp, spcl.c_ddate))
+                       SETINO(ino, metainomap);
                if (mode != IFREG && mode != IFDIR && mode != IFLNK)
                        *tapesize += 1;
                else
@@ -663,12 +668,13 @@ searchdir(struct ext2_dir_entry *dp, int offset, int blocksize, char *buf, void
                ip = getino(dp->inode);
                if (TSTINO(dp->inode, dumpinomap)) {
                        CLRINO(dp->inode, dumpinomap);
-                       CLRINO(dp->inode, usedinomap);
                        *tapesize -= blockest(ip);
                }
-               /* Add dir back to the dir map, to propagate nodump */
+               /* Add dir back to the dir map and remove from
+                * usedinomap to propagate nodump */
                if ((ip->di_mode & IFMT) == IFDIR) {
                        SETINO(dp->inode, dumpdirmap);
+                       CLRINO(dp->inode, usedinomap);
                        *ret |= HASSUBDIRS;
                }
        } else {
@@ -774,7 +780,7 @@ dumponeblock(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt,
  * Dump the contents of an inode to tape.
  */
 void
-dumpino(struct dinode *dp, dump_ino_t ino)
+dumpino(struct dinode *dp, dump_ino_t ino, int metaonly)
 {
        unsigned long cnt;
        fsizeT size, remaining;
@@ -786,7 +792,12 @@ dumpino(struct dinode *dp, dump_ino_t ino)
 #else
        int ind_level;
 #endif
-       u_quad_t i_size = dp->di_size + ((u_quad_t) dp->di_size_high << 32);
+       u_quad_t i_size;
+       
+       if (metaonly)
+               i_size = 0;
+       else 
+               i_size = dp->di_size + ((u_quad_t) dp->di_size_high << 32);
 
        if (newtape) {
                newtape = 0;
@@ -815,6 +826,15 @@ dumpino(struct dinode *dp, dump_ino_t ino)
 #endif /* __linux__ */
        spcl.c_type = TS_INODE;
        spcl.c_count = 0;
+
+       if (metaonly && (dp->di_mode & S_IFMT)) {
+               spcl.c_flags |= DR_METAONLY;
+               spcl.c_count = 0;
+               writeheader(ino);
+               spcl.c_flags &= ~DR_METAONLY;
+               return;
+       }
+
        switch (dp->di_mode & S_IFMT) {
 
        case 0: