Support inheritance of the "nodump" flag down a hierarchy.

Submitted by:	Dima Dorfman <dima@unixfreak.org>
Obtained from:	NetBSD
This commit is contained in:
obrien 2001-03-03 11:35:50 +00:00
parent c2257f6c8a
commit 0de7162258
2 changed files with 82 additions and 26 deletions

View File

@ -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,

View File

@ -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);