version 1.15, 2005/05/22 08:35:28 |
version 1.16, 2005/05/25 11:07:13 |
Line 150 ffs_snapshot(mp, vp, ctime) |
|
Line 150 ffs_snapshot(mp, vp, ctime) |
|
long redo = 0; |
long redo = 0; |
int32_t *lp; |
int32_t *lp; |
void *space; |
void *space; |
caddr_t cgbuf; |
caddr_t sbbuf = NULL; |
struct ufsmount *ump = VFSTOUFS(mp); |
struct ufsmount *ump = VFSTOUFS(mp); |
struct fs *copy_fs = NULL, *fs = ump->um_fs; |
struct fs *copy_fs = NULL, *fs = ump->um_fs; |
struct proc *p = curproc; |
struct proc *p = curproc; |
Line 200 ffs_snapshot(mp, vp, ctime) |
|
Line 200 ffs_snapshot(mp, vp, ctime) |
|
ip = VTOI(vp); |
ip = VTOI(vp); |
devvp = ip->i_devvp; |
devvp = ip->i_devvp; |
/* |
/* |
* Allocate and copy the last block contents so as to be able |
* Write an empty list of preallocated blocks to the end of |
* to set size to that of the filesystem. |
* the snapshot to set size to at least that of the filesystem. |
*/ |
*/ |
numblks = howmany(fs->fs_size, fs->fs_frag); |
numblks = howmany(fs->fs_size, fs->fs_frag); |
cgbuf = malloc(fs->fs_bsize, M_UFSMNT, M_WAITOK); |
blkno = 1; |
if ((error = readfsblk(vp, cgbuf, numblks - 1)) != 0) |
blkno = ufs_rw64(blkno, ns); |
goto out; |
|
error = vn_rdwr(UIO_WRITE, vp, |
error = vn_rdwr(UIO_WRITE, vp, |
cgbuf, fs->fs_bsize, lblktosize(fs, (off_t)(numblks - 1)), |
(caddr_t)&blkno, sizeof(blkno), lblktosize(fs, (off_t)numblks), |
UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, p->p_ucred, NULL, NULL); |
UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, p->p_ucred, NULL, NULL); |
if (error) |
if (error) |
goto out; |
goto out; |
Line 248 ffs_snapshot(mp, vp, ctime) |
|
Line 247 ffs_snapshot(mp, vp, ctime) |
|
bawrite(nbp); |
bawrite(nbp); |
} |
} |
/* |
/* |
* Allocate all cylinder group blocks. |
|
*/ |
|
for (cg = 0; cg < fs->fs_ncg; cg++) { |
|
error = VOP_BALLOC(vp, lfragtosize(fs, cgtod(fs, cg)), |
|
fs->fs_bsize, KERNCRED, 0, &nbp); |
|
if (error) |
|
goto out; |
|
bawrite(nbp); |
|
} |
|
/* |
|
* Copy all the cylinder group maps. Although the |
* Copy all the cylinder group maps. Although the |
* filesystem is still active, we hope that only a few |
* filesystem is still active, we hope that only a few |
* cylinder groups will change between now and when we |
* cylinder groups will change between now and when we |
Line 302 ffs_snapshot(mp, vp, ctime) |
|
Line 291 ffs_snapshot(mp, vp, ctime) |
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
microtime(&starttime); |
microtime(&starttime); |
/* |
/* |
* The last block saved before may have changed so update it now. |
|
*/ |
|
if ((error = readfsblk(vp, cgbuf, numblks - 1)) != 0) |
|
goto out1; |
|
if ((error = writevnblk(vp, cgbuf, numblks - 1)) != 0) |
|
goto out1; |
|
/* |
|
* First, copy all the cylinder group maps that have changed. |
* First, copy all the cylinder group maps that have changed. |
*/ |
*/ |
for (cg = 0; cg < fs->fs_ncg; cg++) { |
for (cg = 0; cg < fs->fs_ncg; cg++) { |
Line 327 ffs_snapshot(mp, vp, ctime) |
|
Line 309 ffs_snapshot(mp, vp, ctime) |
|
* Grab a copy of the superblock and its summary information. |
* Grab a copy of the superblock and its summary information. |
* We delay writing it until the suspension is released below. |
* We delay writing it until the suspension is released below. |
*/ |
*/ |
|
sbbuf = malloc(fs->fs_bsize, M_UFSMNT, M_WAITOK); |
loc = blkoff(fs, fs->fs_sblockloc); |
loc = blkoff(fs, fs->fs_sblockloc); |
if (loc > 0) |
if (loc > 0) |
bzero(&cgbuf[0], loc); |
bzero(&sbbuf[0], loc); |
copy_fs = (struct fs *)(cgbuf + loc); |
copy_fs = (struct fs *)(sbbuf + loc); |
bcopy(fs, copy_fs, fs->fs_sbsize); |
bcopy(fs, copy_fs, fs->fs_sbsize); |
size = fs->fs_bsize < SBLOCKSIZE ? fs->fs_bsize : SBLOCKSIZE; |
size = fs->fs_bsize < SBLOCKSIZE ? fs->fs_bsize : SBLOCKSIZE; |
if (fs->fs_sbsize < size) |
if (fs->fs_sbsize < size) |
bzero(&cgbuf[loc + fs->fs_sbsize], size - fs->fs_sbsize); |
bzero(&sbbuf[loc + fs->fs_sbsize], size - fs->fs_sbsize); |
size = blkroundup(fs, fs->fs_cssize); |
size = blkroundup(fs, fs->fs_cssize); |
if (fs->fs_contigsumsize > 0) |
if (fs->fs_contigsumsize > 0) |
size += fs->fs_ncg * sizeof(int32_t); |
size += fs->fs_ncg * sizeof(int32_t); |
|
|
*/ |
*/ |
for (i = 0; i < snaplistsize; i++) |
for (i = 0; i < snaplistsize; i++) |
snapblklist[i] = ufs_rw64(snapblklist[i], ns); |
snapblklist[i] = ufs_rw64(snapblklist[i], ns); |
error = vn_rdwr(UIO_WRITE, vp, |
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)snapblklist, |
(caddr_t)snapblklist, snaplistsize*sizeof(ufs2_daddr_t), ip->i_size, |
snaplistsize*sizeof(ufs2_daddr_t), lblktosize(fs, (off_t)numblks), |
UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, p->p_ucred, NULL, NULL); |
UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, p->p_ucred, NULL, NULL); |
for (i = 0; i < snaplistsize; i++) |
for (i = 0; i < snaplistsize; i++) |
snapblklist[i] = ufs_rw64(snapblklist[i], ns); |
snapblklist[i] = ufs_rw64(snapblklist[i], ns); |
|
|
brelse(nbp); |
brelse(nbp); |
fs->fs_snapinum[snaploc] = 0; |
fs->fs_snapinum[snaploc] = 0; |
} |
} |
bcopy(cgbuf, nbp->b_data, fs->fs_bsize); |
bcopy(sbbuf, nbp->b_data, fs->fs_bsize); |
bawrite(nbp); |
bawrite(nbp); |
} |
} |
out: |
out: |
|
|
simple_unlock(&global_v_numoutput_slock); |
simple_unlock(&global_v_numoutput_slock); |
splx(s); |
splx(s); |
} |
} |
if (cgbuf) |
if (sbbuf) |
free(cgbuf, M_UFSMNT); |
free(sbbuf, M_UFSMNT); |
if (fs->fs_active != 0) { |
if (fs->fs_active != 0) { |
FREE(fs->fs_active, M_DEVBUF); |
FREE(fs->fs_active, M_DEVBUF); |
fs->fs_active = 0; |
fs->fs_active = 0; |