Support inheritance of the "nodump" flag down a hierarchy.
Submitted by: Dima Dorfman <dima@unixfreak.org> Obtained from: NetBSD
This commit is contained in:
parent
f2fdbb57ca
commit
801382fa98
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=73375
@ -243,6 +243,22 @@ Is like W, but prints only those filesystems which need to be dumped.
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
.Nm Dump
|
.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:
|
requires operator intervention on these conditions:
|
||||||
end of tape,
|
end of tape,
|
||||||
end of dump,
|
end of dump,
|
||||||
|
@ -74,9 +74,11 @@ typedef quad_t fsizeT;
|
|||||||
typedef long fsizeT;
|
typedef long fsizeT;
|
||||||
#endif
|
#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 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.
|
* This is an estimation of the number of TP_BSIZE blocks in the file.
|
||||||
@ -152,10 +154,14 @@ mapfiles(maxino, tapesize)
|
|||||||
dp = getino(ino);
|
dp = getino(ino);
|
||||||
if ((mode = (dp->di_mode & IFMT)) == 0)
|
if ((mode = (dp->di_mode & IFMT)) == 0)
|
||||||
continue;
|
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)
|
if (mode == IFDIR)
|
||||||
SETINO(ino, dumpdirmap);
|
SETINO(ino, dumpdirmap);
|
||||||
if (WANTTODUMP(dp)) {
|
if (WANTTODUMP(dp)) {
|
||||||
|
SETINO(ino, usedinomap);
|
||||||
SETINO(ino, dumpinomap);
|
SETINO(ino, dumpinomap);
|
||||||
if (mode != IFREG && mode != IFDIR && mode != IFLNK)
|
if (mode != IFREG && mode != IFDIR && mode != IFLNK)
|
||||||
*tapesize += 1;
|
*tapesize += 1;
|
||||||
@ -192,9 +198,10 @@ mapdirs(maxino, tapesize)
|
|||||||
long *tapesize;
|
long *tapesize;
|
||||||
{
|
{
|
||||||
register struct dinode *dp;
|
register struct dinode *dp;
|
||||||
register int i, isdir;
|
register int i, isdir, nodump;
|
||||||
register char *map;
|
register char *map;
|
||||||
register ino_t ino;
|
register ino_t ino;
|
||||||
|
struct dinode di;
|
||||||
long filesize;
|
long filesize;
|
||||||
int ret, change = 0;
|
int ret, change = 0;
|
||||||
|
|
||||||
@ -204,24 +211,34 @@ mapdirs(maxino, tapesize)
|
|||||||
isdir = *map++;
|
isdir = *map++;
|
||||||
else
|
else
|
||||||
isdir >>= 1;
|
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;
|
continue;
|
||||||
dp = getino(ino);
|
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++) {
|
for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) {
|
||||||
if (dp->di_db[i] != 0)
|
if (di.di_db[i] != 0)
|
||||||
ret |= searchdir(ino, dp->di_db[i],
|
ret |= searchdir(ino, di.di_db[i],
|
||||||
(long)dblksize(sblock, dp, i),
|
(long)dblksize(sblock, dp, i),
|
||||||
filesize);
|
filesize, tapesize, nodump);
|
||||||
if (ret & HASDUMPEDFILE)
|
if (ret & HASDUMPEDFILE)
|
||||||
filesize = 0;
|
filesize = 0;
|
||||||
else
|
else
|
||||||
filesize -= sblock->fs_bsize;
|
filesize -= sblock->fs_bsize;
|
||||||
}
|
}
|
||||||
for (i = 0; filesize > 0 && i < NIADDR; i++) {
|
for (i = 0; filesize > 0 && i < NIADDR; i++) {
|
||||||
if (dp->di_ib[i] == 0)
|
if (di.di_ib[i] == 0)
|
||||||
continue;
|
continue;
|
||||||
ret |= dirindir(ino, dp->di_ib[i], i, &filesize);
|
ret |= dirindir(ino, di.di_ib[i], i, &filesize,
|
||||||
|
tapesize, nodump);
|
||||||
}
|
}
|
||||||
if (ret & HASDUMPEDFILE) {
|
if (ret & HASDUMPEDFILE) {
|
||||||
SETINO(ino, dumpinomap);
|
SETINO(ino, dumpinomap);
|
||||||
@ -229,12 +246,15 @@ mapdirs(maxino, tapesize)
|
|||||||
change = 1;
|
change = 1;
|
||||||
continue;
|
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)) {
|
if (!TSTINO(ino, dumpinomap)) {
|
||||||
CLRINO(ino, dumpdirmap);
|
CLRINO(ino, dumpdirmap);
|
||||||
change = 1;
|
change = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (change);
|
return (change);
|
||||||
}
|
}
|
||||||
@ -245,11 +265,13 @@ mapdirs(maxino, tapesize)
|
|||||||
* require the directory to be dumped.
|
* require the directory to be dumped.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
dirindir(ino, blkno, ind_level, filesize)
|
dirindir(ino, blkno, ind_level, filesize, tapesize, nodump)
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
daddr_t blkno;
|
daddr_t blkno;
|
||||||
int ind_level;
|
int ind_level;
|
||||||
long *filesize;
|
long *filesize;
|
||||||
|
long *tapesize;
|
||||||
|
int nodump;
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
register int i;
|
register int i;
|
||||||
@ -261,7 +283,7 @@ dirindir(ino, blkno, ind_level, filesize)
|
|||||||
blkno = idblk[i];
|
blkno = idblk[i];
|
||||||
if (blkno != 0)
|
if (blkno != 0)
|
||||||
ret |= searchdir(ino, blkno, sblock->fs_bsize,
|
ret |= searchdir(ino, blkno, sblock->fs_bsize,
|
||||||
*filesize);
|
*filesize, tapesize, nodump);
|
||||||
if (ret & HASDUMPEDFILE)
|
if (ret & HASDUMPEDFILE)
|
||||||
*filesize = 0;
|
*filesize = 0;
|
||||||
else
|
else
|
||||||
@ -273,7 +295,8 @@ dirindir(ino, blkno, ind_level, filesize)
|
|||||||
for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
|
for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
|
||||||
blkno = idblk[i];
|
blkno = idblk[i];
|
||||||
if (blkno != 0)
|
if (blkno != 0)
|
||||||
ret |= dirindir(ino, blkno, ind_level, filesize);
|
ret |= dirindir(ino, blkno, ind_level, filesize,
|
||||||
|
tapesize, nodump);
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -284,13 +307,16 @@ dirindir(ino, blkno, ind_level, filesize)
|
|||||||
* contains any subdirectories.
|
* contains any subdirectories.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
searchdir(ino, blkno, size, filesize)
|
searchdir(ino, blkno, size, filesize, tapesize, nodump)
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
daddr_t blkno;
|
daddr_t blkno;
|
||||||
register long size;
|
register long size;
|
||||||
long filesize;
|
long filesize;
|
||||||
|
long *tapesize;
|
||||||
|
int nodump;
|
||||||
{
|
{
|
||||||
register struct direct *dp;
|
register struct direct *dp;
|
||||||
|
register struct dinode *ip;
|
||||||
register long loc, ret = 0;
|
register long loc, ret = 0;
|
||||||
char dblk[MAXBSIZE];
|
char dblk[MAXBSIZE];
|
||||||
|
|
||||||
@ -312,15 +338,29 @@ searchdir(ino, blkno, size, filesize)
|
|||||||
if (dp->d_name[1] == '.' && dp->d_name[2] == '\0')
|
if (dp->d_name[1] == '.' && dp->d_name[2] == '\0')
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (TSTINO(dp->d_ino, dumpinomap)) {
|
if (nodump) {
|
||||||
ret |= HASDUMPEDFILE;
|
ip = getino(dp->d_ino);
|
||||||
if (ret & HASSUBDIRS)
|
if (TSTINO(dp->d_ino, dumpinomap)) {
|
||||||
break;
|
CLRINO(dp->d_ino, dumpinomap);
|
||||||
}
|
CLRINO(dp->d_ino, usedinomap);
|
||||||
if (TSTINO(dp->d_ino, dumpdirmap)) {
|
*tapesize -= blockest(ip);
|
||||||
ret |= HASSUBDIRS;
|
}
|
||||||
if (ret & HASDUMPEDFILE)
|
/* Add back to dumpdirmap to propagate nodump. */
|
||||||
break;
|
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);
|
return (ret);
|
||||||
|
Loading…
Reference in New Issue
Block a user