summaryrefslogtreecommitdiffstats
path: root/sbin/dump
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2001-03-03 11:35:50 +0000
committerobrien <obrien@FreeBSD.org>2001-03-03 11:35:50 +0000
commit0de716225854882caefa74da728558e702649999 (patch)
tree83e1c754365dba16772d0690d27daeb677321801 /sbin/dump
parentc2257f6c8a69b4a7cae98128bd89f28f3893f3c5 (diff)
downloadFreeBSD-src-0de716225854882caefa74da728558e702649999.zip
FreeBSD-src-0de716225854882caefa74da728558e702649999.tar.gz
Support inheritance of the "nodump" flag down a hierarchy.
Submitted by: Dima Dorfman <dima@unixfreak.org> Obtained from: NetBSD
Diffstat (limited to 'sbin/dump')
-rw-r--r--sbin/dump/dump.816
-rw-r--r--sbin/dump/traverse.c92
2 files changed, 82 insertions, 26 deletions
diff --git a/sbin/dump/dump.8 b/sbin/dump/dump.8
index 58dbfb8..6537c0c 100644
--- a/sbin/dump/dump.8
+++ b/sbin/dump/dump.8
@@ -243,6 +243,22 @@ Is like W, but prints only those filesystems which need to be dumped.
.El
.Pp
.Nm Dump
+honors the user
+.Dq nodump
+flag
+.Pq Dv UF_NODUMP
+on regular files and directories.
+If a directory is marked
+.Dq nodump ,
+the latter and all files and directories under it will not be backed
+up.
+That is,
+.Nm
+propagates the
+.Dq nodump
+flag on directories.
+.Pp
+.Nm Dump
requires operator intervention on these conditions:
end of tape,
end of dump,
diff --git a/sbin/dump/traverse.c b/sbin/dump/traverse.c
index f52413c..72c4075 100644
--- a/sbin/dump/traverse.c
+++ b/sbin/dump/traverse.c
@@ -74,9 +74,11 @@ typedef quad_t fsizeT;
typedef long fsizeT;
#endif
-static int dirindir __P((ino_t ino, daddr_t blkno, int level, long *size));
+static int dirindir __P((ino_t ino, daddr_t blkno, int level, long *size,
+ long *tapesize, int nodump));
static void dmpindir __P((ino_t ino, daddr_t blk, int level, fsizeT *size));
-static int searchdir __P((ino_t ino, daddr_t blkno, long size, long filesize));
+static int searchdir __P((ino_t ino, daddr_t blkno, long size, long filesize,
+ long *tapesize, int nodump));
/*
* This is an estimation of the number of TP_BSIZE blocks in the file.
@@ -152,10 +154,14 @@ mapfiles(maxino, tapesize)
dp = getino(ino);
if ((mode = (dp->di_mode & IFMT)) == 0)
continue;
- SETINO(ino, usedinomap);
+ /*
+ * All dirs go in dumpdirmap; only inodes that are to
+ * be dumped go in usedinomap and dumpinomap, however.
+ */
if (mode == IFDIR)
SETINO(ino, dumpdirmap);
if (WANTTODUMP(dp)) {
+ SETINO(ino, usedinomap);
SETINO(ino, dumpinomap);
if (mode != IFREG && mode != IFDIR && mode != IFLNK)
*tapesize += 1;
@@ -192,9 +198,10 @@ mapdirs(maxino, tapesize)
long *tapesize;
{
register struct dinode *dp;
- register int i, isdir;
+ register int i, isdir, nodump;
register char *map;
register ino_t ino;
+ struct dinode di;
long filesize;
int ret, change = 0;
@@ -204,24 +211,34 @@ mapdirs(maxino, 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 = (TSTINO(ino, usedinomap) == 0);
+ if ((isdir & 1) == 0 || (TSTINO(ino, dumpinomap) && !nodump))
continue;
dp = getino(ino);
- filesize = dp->di_size;
+ di = *dp; /* inode buf may change in searchdir(). */
+ filesize = di.di_size;
for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) {
- if (dp->di_db[i] != 0)
- ret |= searchdir(ino, dp->di_db[i],
+ if (di.di_db[i] != 0)
+ ret |= searchdir(ino, di.di_db[i],
(long)dblksize(sblock, dp, i),
- filesize);
+ filesize, tapesize, nodump);
if (ret & HASDUMPEDFILE)
filesize = 0;
else
filesize -= sblock->fs_bsize;
}
for (i = 0; filesize > 0 && i < NIADDR; i++) {
- if (dp->di_ib[i] == 0)
+ if (di.di_ib[i] == 0)
continue;
- ret |= dirindir(ino, dp->di_ib[i], i, &filesize);
+ ret |= dirindir(ino, di.di_ib[i], i, &filesize,
+ tapesize, nodump);
}
if (ret & HASDUMPEDFILE) {
SETINO(ino, dumpinomap);
@@ -229,12 +246,15 @@ mapdirs(maxino, 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;
}
- }
}
return (change);
}
@@ -245,11 +265,13 @@ mapdirs(maxino, tapesize)
* require the directory to be dumped.
*/
static int
-dirindir(ino, blkno, ind_level, filesize)
+dirindir(ino, blkno, ind_level, filesize, tapesize, nodump)
ino_t ino;
daddr_t blkno;
int ind_level;
long *filesize;
+ long *tapesize;
+ int nodump;
{
int ret = 0;
register int i;
@@ -261,7 +283,7 @@ dirindir(ino, blkno, ind_level, filesize)
blkno = idblk[i];
if (blkno != 0)
ret |= searchdir(ino, blkno, sblock->fs_bsize,
- *filesize);
+ *filesize, tapesize, nodump);
if (ret & HASDUMPEDFILE)
*filesize = 0;
else
@@ -273,7 +295,8 @@ dirindir(ino, blkno, ind_level, filesize)
for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
blkno = idblk[i];
if (blkno != 0)
- ret |= dirindir(ino, blkno, ind_level, filesize);
+ ret |= dirindir(ino, blkno, ind_level, filesize,
+ tapesize, nodump);
}
return (ret);
}
@@ -284,13 +307,16 @@ dirindir(ino, blkno, ind_level, filesize)
* contains any subdirectories.
*/
static int
-searchdir(ino, blkno, size, filesize)
+searchdir(ino, blkno, size, filesize, tapesize, nodump)
ino_t ino;
daddr_t blkno;
register long size;
long filesize;
+ long *tapesize;
+ int nodump;
{
register struct direct *dp;
+ register struct dinode *ip;
register long loc, ret = 0;
char dblk[MAXBSIZE];
@@ -312,15 +338,29 @@ searchdir(ino, blkno, size, filesize)
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);
+ if (TSTINO(dp->d_ino, dumpinomap)) {
+ CLRINO(dp->d_ino, dumpinomap);
+ CLRINO(dp->d_ino, usedinomap);
+ *tapesize -= blockest(ip);
+ }
+ /* Add back to dumpdirmap to propagate nodump. */
+ if ((ip->di_mode & IFMT) == IFDIR) {
+ SETINO(dp->d_ino, dumpdirmap);
+ 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);
OpenPOWER on IntegriCloud