Several fixes for units errors:
1) Do not assume that the superblock will be of size fs->fs_bsize. This fixes a panic when taking a snapshot on a filesystem with a block size bigger than 8K. 2) Properly calculate the number of fragments that follow the superblock summary information. This fixes a bug with inconsistent snapshots. 3) When cleaning up a snapshot that is about to be removed, properly calculate the number of blocks that need to be checked. This fixes a bug that created partially allocated inodes. 4) When moving blocks from a snapshot that is about to be removed to another snapshot, properly account for the reduced number of blocks in the snapshot from which they are taken. This fixes a bug in which the number of blocks released from a snapshot did not match the number that it claimed to have.
This commit is contained in:
parent
72272f83b2
commit
27b047acf0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=76356
@ -229,7 +229,7 @@ ffs_snapshot(mp, snapfile)
|
||||
/*
|
||||
* Allocate copies for the superblock and its summary information.
|
||||
*/
|
||||
error = UFS_BALLOC(vp, (off_t)(SBOFF), fs->fs_bsize, KERNCRED, 0, &nbp);
|
||||
error = UFS_BALLOC(vp, (off_t)(SBOFF), SBSIZE, KERNCRED, 0, &nbp);
|
||||
if (error)
|
||||
goto out;
|
||||
bawrite(nbp);
|
||||
@ -379,7 +379,9 @@ ffs_snapshot(mp, snapfile)
|
||||
bcopy(fs->fs_csp, copy_fs->fs_csp, fs->fs_cssize);
|
||||
(char *)space += fs->fs_cssize;
|
||||
loc = howmany(fs->fs_cssize, fs->fs_fsize);
|
||||
if ((len = fragnum(fs, loc) * fs->fs_fsize) > 0) {
|
||||
i = fs->fs_frag - loc % fs->fs_frag;
|
||||
len = (i == fs->fs_frag) ? 0 : i * fs->fs_fsize;
|
||||
if (len > 0) {
|
||||
if ((error = bread(ip->i_devvp,
|
||||
fsbtodb(fs, fs->fs_csaddr + loc),
|
||||
len, KERNCRED, &bp)) != 0) {
|
||||
@ -741,7 +743,7 @@ ffs_snapremove(vp)
|
||||
struct buf *ibp;
|
||||
struct fs *fs;
|
||||
ufs_daddr_t blkno, dblk;
|
||||
int error, loc, last;
|
||||
int error, numblks, loc, last;
|
||||
|
||||
ip = VTOI(vp);
|
||||
fs = ip->i_fs;
|
||||
@ -767,12 +769,16 @@ ffs_snapremove(vp)
|
||||
*/
|
||||
for (blkno = 1; blkno < NDADDR; blkno++) {
|
||||
dblk = ip->i_db[blkno];
|
||||
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP ||
|
||||
(dblk == blkstofrags(fs, blkno) &&
|
||||
ffs_snapblkfree(ip, dblk, fs->fs_bsize)))
|
||||
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP)
|
||||
ip->i_db[blkno] = 0;
|
||||
else if ((dblk == blkstofrags(fs, blkno) &&
|
||||
ffs_snapblkfree(ip, dblk, fs->fs_bsize))) {
|
||||
ip->i_blocks -= btodb(fs->fs_bsize);
|
||||
ip->i_db[blkno] = 0;
|
||||
}
|
||||
}
|
||||
for (blkno = NDADDR; blkno < fs->fs_size; blkno += NINDIR(fs)) {
|
||||
numblks = howmany(ip->i_size, fs->fs_bsize);
|
||||
for (blkno = NDADDR; blkno < numblks; blkno += NINDIR(fs)) {
|
||||
error = UFS_BALLOC(vp, lblktosize(fs, (off_t)blkno),
|
||||
fs->fs_bsize, KERNCRED, B_METAONLY, &ibp);
|
||||
if (error)
|
||||
@ -781,10 +787,13 @@ ffs_snapremove(vp)
|
||||
last = NINDIR(fs);
|
||||
for (loc = 0; loc < last; loc++) {
|
||||
dblk = ((ufs_daddr_t *)(ibp->b_data))[loc];
|
||||
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP ||
|
||||
(dblk == blkstofrags(fs, blkno) &&
|
||||
ffs_snapblkfree(ip, dblk, fs->fs_bsize)))
|
||||
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP)
|
||||
((ufs_daddr_t *)(ibp->b_data))[loc] = 0;
|
||||
else if ((dblk == blkstofrags(fs, blkno) &&
|
||||
ffs_snapblkfree(ip, dblk, fs->fs_bsize))) {
|
||||
ip->i_blocks -= btodb(fs->fs_bsize);
|
||||
((ufs_daddr_t *)(ibp->b_data))[loc] = 0;
|
||||
}
|
||||
}
|
||||
bawrite(ibp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user