Hello all.

The following patch makes dump(8) honor nodump flag on directories. It's
actually ignored currently, forcing you setting it on all files in this
directory and its subdirectories. New behaviour is similar to Net and
Free (actual code was modelled after Free). Tested on i386 only.

I removed two macros that were used only once (WANTTODUMP
and CHANGEDSINCE), and added CHECKNODUMP instead. I assumed that
"#ifndef UF_NODUMP" case does not belong to us, is it right?

I also removed argument names in function declarations to make them
fit on a single line after adding new arguments.

-- 
  Best wishes,
    Vadim Zhukov

A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?


Index: traverse.c
===================================================================
RCS file: /cvs/src/sbin/dump/traverse.c,v
retrieving revision 1.24
diff -u -p -r1.24 traverse.c
--- traverse.c  27 Oct 2009 23:59:32 -0000      1.24
+++ traverse.c  10 Jul 2011 10:47:25 -0000
@@ -60,9 +60,9 @@ union dinode {
 #define        HASDUMPEDFILE   0x1
 #define        HASSUBDIRS      0x2
 
-static int dirindir(ino_t ino, daddr64_t blkno, int level, off_t *size);
-static void dmpindir(ino_t ino, daddr64_t blk, int level, off_t *size);
-static int searchdir(ino_t ino, daddr64_t blkno, long size, off_t filesize);
+static int dirindir(ino_t, daddr64_t, int, off_t *, off_t *, int);
+static void dmpindir(ino_t, daddr64_t, int, off_t *);
+static int searchdir(ino_t, daddr64_t, long, off_t, off_t *, int);
 
 /*
  * This is an estimation of the number of TP_BSIZE blocks in the file.
@@ -103,18 +103,9 @@ blockest(union dinode *dp)
        return (blkest + 1);
 }
 
-/* Auxiliary macro to pick up files changed since previous dump. */
-#define        CHANGEDSINCE(dp, t) \
-       (DIP(dp, di_mtime) >= (t) || DIP(dp, di_ctime) >= (t))
-
-/* The WANTTODUMP macro decides whether a file should be dumped. */
-#ifdef UF_NODUMP
-#define        WANTTODUMP(dp) \
-       (CHANGEDSINCE(dp, spcl.c_ddate) && \
-        (nonodump || (DIP(dp, di_flags) & UF_NODUMP) != UF_NODUMP))
-#else
-#define        WANTTODUMP(dp) CHANGEDSINCE(dp, spcl.c_ddate)
-#endif
+/* true if "nodump" flag has no effect here, i.e. dumping allowed */
+#define CHECKNODUMP(dp) \
+       (nonodump || (DIP((dp), di_flags) & UF_NODUMP) != UF_NODUMP)
 
 /*
  * Determine if given inode should be dumped
@@ -131,7 +122,7 @@ mapfileino(ino_t ino, off_t *tapesize, i
        SETINO(ino, usedinomap);
        if (mode == IFDIR)
                SETINO(ino, dumpdirmap);
-       if (WANTTODUMP(dp)) {
+       if (CHECKNODUMP(dp) && DIP(dp, di_mtime) >= spcl.c_ddate) {
                SETINO(ino, dumpinomap);
                if (mode != IFREG && mode != IFDIR && mode != IFLNK)
                        *tapesize += 1;
@@ -139,8 +130,11 @@ mapfileino(ino_t ino, off_t *tapesize, i
                        *tapesize += blockest(dp);
                return;
        }
-       if (mode == IFDIR)
+       if (mode == IFDIR) {
+               if (!CHECKNODUMP(dp))
+                       CLRINO(ino, usedinomap);
                *dirskipped = 1;
+       }
 }
 
 void
@@ -307,7 +301,7 @@ int
 mapdirs(ino_t maxino, off_t *tapesize)
 {
        union dinode *dp;
-       int i, isdir;
+       int i, isdir, nodump;
        char *map;
        ino_t ino;
        union dinode di;
@@ -320,7 +314,15 @@ mapdirs(ino_t maxino, off_t *tapesize)
                        isdir = *map++;
                else
                        isdir >>= 1;
-               if ((isdir & 1) == 0 || TSTINO(ino, dumpinomap))
+                /*
+                * If a directory has been removed from usedinomap, it
+                * either has the nodump flag set, or has inherited
+                * it.  Although a directory can't be in dumpinomap if
+                * it isn't in usedinomap, we have to go through it to
+                * propagate the nodump flag.
+                */
+               nodump = !nonodump && !TSTINO(ino, usedinomap);
+               if ((isdir & 1) == 0 || TSTINO(ino, dumpinomap) && !nodump)
                        continue;
                dp = getino(ino, &i);
                /*
@@ -335,7 +337,7 @@ mapdirs(ino_t maxino, off_t *tapesize)
                        if (DIP(&di, di_db[i]) != 0)
                                ret |= searchdir(ino, DIP(&di, di_db[i]),
                                    sblksize(sblock, DIP(dp, di_size), i),
-                                   filesize);
+                                   filesize, tapesize, nodump);
                        if (ret & HASDUMPEDFILE)
                                filesize = 0;
                        else
@@ -344,7 +346,8 @@ mapdirs(ino_t maxino, off_t *tapesize)
                for (i = 0; filesize > 0 && i < NIADDR; i++) {
                        if (DIP(&di, di_ib[i]) == 0)
                                continue;
-                       ret |= dirindir(ino, DIP(&di, di_ib[i]), i, &filesize);
+                       ret |= dirindir(ino, DIP(&di, di_ib[i]), i, &filesize,
+                           tapesize, nodump);
                }
                if (ret & HASDUMPEDFILE) {
                        SETINO(ino, dumpinomap);
@@ -352,7 +355,11 @@ mapdirs(ino_t maxino, off_t *tapesize)
                        change = 1;
                        continue;
                }
-               if ((ret & HASSUBDIRS) == 0) {
+                if (nodump) {
+                        if (ret & HASSUBDIRS)
+                                change = 1;     /* subdirs inherit nodump */
+                        CLRINO(ino, dumpdirmap);
+                } else if ((ret & HASSUBDIRS) == 0) {
                        if (!TSTINO(ino, dumpinomap)) {
                                CLRINO(ino, dumpdirmap);
                                change = 1;
@@ -368,7 +375,8 @@ mapdirs(ino_t maxino, off_t *tapesize)
  * require the directory to be dumped.
  */
 static int
-dirindir(ino_t ino, daddr64_t blkno, int ind_level, off_t *filesize)
+dirindir(ino_t ino, daddr64_t blkno, int ind_level, off_t *filesize,
+    off_t *tapesize, int nodump)
 {
        int ret = 0;
        int i;
@@ -383,7 +391,7 @@ dirindir(ino_t ino, daddr64_t blkno, int
                                blkno = ((int64_t *)idblk)[i];
                        if (blkno != 0)
                                ret |= searchdir(ino, blkno, sblock->fs_bsize,
-                                       *filesize);
+                                       *filesize, tapesize, nodump);
                        if (ret & HASDUMPEDFILE)
                                *filesize = 0;
                        else
@@ -398,7 +406,8 @@ dirindir(ino_t ino, daddr64_t blkno, int
                else
                        blkno = ((int64_t *)idblk)[i];
                if (blkno != 0)
-                       ret |= dirindir(ino, blkno, ind_level, filesize);
+                       ret |= dirindir(ino, blkno, ind_level, filesize,
+                           tapesize, nodump);
        }
        return (ret);
 }
@@ -409,12 +418,14 @@ dirindir(ino_t ino, daddr64_t blkno, int
  * contains any subdirectories.
  */
 static int
-searchdir(ino_t ino, daddr64_t blkno, long size, off_t filesize)
+searchdir(ino_t ino, daddr64_t blkno, long size, off_t filesize,
+    off_t *tapesize, int nodump)
 {
        struct direct *dp;
+       union dinode *ip;
        long loc;
        static caddr_t dblk;
-       int ret = 0;
+       int mode, ret = 0;
 
        if (dblk == NULL && (dblk = malloc(sblock->fs_bsize)) == NULL)
                quit("searchdir: cannot allocate indirect memory.\n");
@@ -436,15 +447,32 @@ searchdir(ino_t ino, daddr64_t blkno, lo
                        if (dp->d_name[1] == '.' && dp->d_name[2] == '\0')
                                continue;
                }
-               if (TSTINO(dp->d_ino, dumpinomap)) {
-                       ret |= HASDUMPEDFILE;
-                       if (ret & HASSUBDIRS)
-                               break;
-               }
-               if (TSTINO(dp->d_ino, dumpdirmap)) {
-                       ret |= HASSUBDIRS;
-                       if (ret & HASDUMPEDFILE)
-                               break;
+               if (nodump) {
+                        ip = getino(dp->d_ino, &mode);
+                        if (TSTINO(dp->d_ino, dumpinomap)) {
+                                CLRINO(dp->d_ino, dumpinomap);
+                                *tapesize -= blockest(ip);
+                        }
+                        /*
+                         * Add back to dumpdirmap and remove from usedinomap
+                         * to propagate nodump.
+                         */
+                        if (mode == IFDIR) {
+                                SETINO(dp->d_ino, dumpdirmap);
+                                CLRINO(dp->d_ino, usedinomap);
+                                ret |= HASSUBDIRS;
+                        }
+               } else {
+                       if (TSTINO(dp->d_ino, dumpinomap)) {
+                               ret |= HASDUMPEDFILE;
+                               if (ret & HASSUBDIRS)
+                                       break;
+                       }
+                       if (TSTINO(dp->d_ino, dumpdirmap)) {
+                               ret |= HASSUBDIRS;
+                               if (ret & HASDUMPEDFILE)
+                                       break;
+                       }
                }
        }
        return (ret);

Reply via email to