1 /* $NetBSD: ffs_snapshot.c,v 1.157 2026/07/22 14:44:49 hannken Exp $ */ 2 3 /* 4 * Copyright 2000 Marshall Kirk McKusick. All Rights Reserved. 5 * 6 * Further information about snapshots can be obtained from: 7 * 8 * Marshall Kirk McKusick http://www.mckusick.com/softdep/ 9 * 1614 Oxford Street mckusick (at) mckusick.com 10 * Berkeley, CA 94709-1608 +1-510-843-9542 11 * USA 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY MARSHALL KIRK MCKUSICK ``AS IS'' AND ANY 24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL MARSHALL KIRK MCKUSICK BE LIABLE FOR 27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)ffs_snapshot.c 8.11 (McKusick) 7/23/00 36 * 37 * from FreeBSD: ffs_snapshot.c,v 1.79 2004/02/13 02:02:06 kuriyama Exp 38 */ 39 40 #include <sys/cdefs.h> 41 __KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.157 2026/07/22 14:44:49 hannken Exp $"); 42 43 #if defined(_KERNEL_OPT) 44 #include "opt_ffs.h" 45 #include "opt_quota.h" 46 #endif 47 48 #include <sys/param.h> 49 #include <sys/kernel.h> 50 #include <sys/systm.h> 51 #include <sys/conf.h> 52 #include <sys/buf.h> 53 #include <sys/proc.h> 54 #include <sys/namei.h> 55 #include <sys/sched.h> 56 #include <sys/stat.h> 57 #include <sys/malloc.h> 58 #include <sys/mount.h> 59 #include <sys/resource.h> 60 #include <sys/resourcevar.h> 61 #include <sys/vnode.h> 62 #include <sys/kauth.h> 63 #include <sys/fstrans.h> 64 #include <sys/wapbl.h> 65 66 #include <miscfs/specfs/specdev.h> 67 68 #include <ufs/ufs/quota.h> 69 #include <ufs/ufs/ufsmount.h> 70 #include <ufs/ufs/inode.h> 71 #include <ufs/ufs/ufs_extern.h> 72 #include <ufs/ufs/ufs_bswap.h> 73 #include <ufs/ufs/ufs_wapbl.h> 74 75 #include <ufs/ffs/fs.h> 76 #include <ufs/ffs/ffs_extern.h> 77 78 #include <uvm/uvm.h> 79 80 TAILQ_HEAD(inodelst, inode); /* List of active snapshots */ 81 82 struct snap_info { 83 kmutex_t si_lock; /* Lock this snapinfo */ 84 kmutex_t si_snaplock; /* Snapshot vnode common lock */ 85 lwp_t *si_owner; /* Snaplock owner */ 86 struct inodelst si_snapshots; /* List of active snapshots */ 87 daddr_t *si_snapblklist; /* Snapshot block hints list */ 88 uint32_t si_gen; /* Incremented on change */ 89 }; 90 91 typedef int (*acctfunc_t) 92 (struct vnode *, void *, int, int, struct fs *, daddr_t, int); 93 94 static int snapshot_setup(struct mount *, struct vnode *); 95 static int snapshot_copyfs(struct mount *, struct vnode *, void **); 96 static int snapshot_expunge(struct mount *, struct vnode *, 97 struct fs *, daddr_t *, daddr_t **); 98 static int snapshot_expunge_snap(struct mount *, struct vnode *, 99 struct fs *, daddr_t); 100 static int snapshot_writefs(struct mount *, struct vnode *, void *); 101 static int cgaccount(struct vnode *, int, int *); 102 static int cgaccount1(int, struct vnode *, void *, int); 103 static int expunge(struct vnode *, struct inode *, struct fs *, 104 acctfunc_t, int); 105 static int indiracct(struct vnode *, struct vnode *, int, daddr_t, 106 daddr_t, daddr_t, daddr_t, daddr_t, struct fs *, acctfunc_t, int); 107 static int fullacct(struct vnode *, void *, int, int, struct fs *, 108 daddr_t, int); 109 static int snapacct(struct vnode *, void *, int, int, struct fs *, 110 daddr_t, int); 111 static int mapacct(struct vnode *, void *, int, int, struct fs *, 112 daddr_t, int); 113 114 static int ffs_copyonwrite(void *, struct buf *, bool); 115 static int snapblkaddr(struct vnode *, daddr_t, daddr_t *); 116 static int rwfsblk(struct vnode *, int, void *, daddr_t); 117 static int syncsnap(struct vnode *); 118 static int wrsnapblk(struct vnode *, void *, daddr_t); 119 static int blocks_in_journal(struct fs *); 120 121 static inline bool is_active_snapshot(struct snap_info *, struct inode *); 122 static inline daddr_t db_get(struct inode *, int); 123 static inline void db_assign(struct inode *, int, daddr_t); 124 static inline daddr_t ib_get(struct inode *, int); 125 static inline daddr_t idb_get(struct inode *, void *, int); 126 static inline void idb_assign(struct inode *, void *, int, daddr_t); 127 128 #ifdef DEBUG 129 static int snapdebug = 0; 130 #endif 131 132 int 133 ffs_snapshot_init(struct ufsmount *ump) 134 { 135 struct snap_info *si; 136 137 si = ump->um_snapinfo = kmem_alloc(sizeof(*si), KM_SLEEP); 138 TAILQ_INIT(&si->si_snapshots); 139 mutex_init(&si->si_lock, MUTEX_DEFAULT, IPL_NONE); 140 mutex_init(&si->si_snaplock, MUTEX_DEFAULT, IPL_NONE); 141 si->si_owner = NULL; 142 si->si_gen = 0; 143 si->si_snapblklist = NULL; 144 145 return 0; 146 } 147 148 void 149 ffs_snapshot_fini(struct ufsmount *ump) 150 { 151 struct snap_info *si; 152 153 si = ump->um_snapinfo; 154 ump->um_snapinfo = NULL; 155 156 KASSERT(TAILQ_EMPTY(&si->si_snapshots)); 157 mutex_destroy(&si->si_lock); 158 mutex_destroy(&si->si_snaplock); 159 KASSERT(si->si_snapblklist == NULL); 160 kmem_free(si, sizeof(*si)); 161 } 162 163 /* 164 * Create a snapshot file and initialize it for the filesystem. 165 * Vnode is locked on entry and return. 166 */ 167 int 168 ffs_snapshot(struct mount *mp, struct vnode *vp, struct timespec *ctime) 169 { 170 bool suspended = false; 171 int error, redo = 0, snaploc; 172 void *sbbuf = NULL; 173 daddr_t *snaplist = NULL, snaplistsize = 0; 174 struct buf *bp, *nbp; 175 struct fs *copy_fs = NULL; 176 struct fs *fs = VFSTOUFS(mp)->um_fs; 177 struct inode *ip = VTOI(vp); 178 struct lwp *l = curlwp; 179 struct snap_info *si = VFSTOUFS(mp)->um_snapinfo; 180 struct timespec ts; 181 struct timeval starttime; 182 #ifdef DEBUG 183 struct timeval endtime; 184 #endif 185 struct vnode *devvp = ip->i_devvp; 186 187 /* 188 * If the vnode already is a snapshot, return. 189 */ 190 if ((ip->i_flags & SF_SNAPSHOT)) { 191 if ((ip->i_flags & SF_SNAPINVAL)) 192 return EINVAL; 193 if (ctime) { 194 ctime->tv_sec = DIP(ip, mtime); 195 ctime->tv_nsec = DIP(ip, mtimensec); 196 } 197 return 0; 198 } 199 /* 200 * Check for free snapshot slot in the superblock. 201 */ 202 for (snaploc = 0; snaploc < FSMAXSNAP; snaploc++) 203 if (fs->fs_snapinum[snaploc] == 0) 204 break; 205 if (snaploc == FSMAXSNAP) 206 return (ENOSPC); 207 /* 208 * Prepare the vnode to become a snapshot. 209 */ 210 error = snapshot_setup(mp, vp); 211 if (error) 212 goto out; 213 214 /* 215 * Copy all the cylinder group maps. Although the 216 * filesystem is still active, we hope that only a few 217 * cylinder groups will change between now and when we 218 * suspend operations. Thus, we will be able to quickly 219 * touch up the few cylinder groups that changed during 220 * the suspension period. 221 */ 222 error = cgaccount(vp, 1, NULL); 223 if (error) 224 goto out; 225 226 /* 227 * snapshot is now valid 228 */ 229 ip->i_flags &= ~SF_SNAPINVAL; 230 DIP_ASSIGN(ip, flags, ip->i_flags); 231 ip->i_flag |= IN_CHANGE | IN_UPDATE; 232 233 /* 234 * Ensure that the snapshot is completely on disk. 235 * Since we have marked it as a snapshot it is safe to 236 * unlock it as no process will be allowed to write to it. 237 */ 238 error = VOP_FSYNC(vp, l->l_cred, FSYNC_WAIT, 0, 0); 239 if (error) 240 goto out; 241 VOP_UNLOCK(vp); 242 /* 243 * All allocations are done, so we can now suspend the filesystem. 244 */ 245 error = vfs_suspend(vp->v_mount, 0); 246 if (error == 0) { 247 suspended = true; 248 vrele_flush(vp->v_mount); 249 error = VFS_SYNC(vp->v_mount, MNT_WAIT, curlwp->l_cred); 250 } 251 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 252 if (error) 253 goto out; 254 getmicrotime(&starttime); 255 /* 256 * First, copy all the cylinder group maps that have changed. 257 */ 258 error = cgaccount(vp, 2, &redo); 259 if (error) 260 goto out; 261 /* 262 * Create a copy of the superblock and its summary information. 263 */ 264 error = snapshot_copyfs(mp, vp, &sbbuf); 265 if (error) 266 goto out; 267 copy_fs = (struct fs *)((char *)sbbuf + ffs_blkoff(fs, fs->fs_sblockloc)); 268 /* 269 * Expunge unlinked files from our view. 270 */ 271 error = snapshot_expunge(mp, vp, copy_fs, &snaplistsize, &snaplist); 272 if (error) 273 goto out; 274 /* 275 * Record snapshot inode. Since this is the newest snapshot, 276 * it must be placed at the end of the list. 277 */ 278 if (ip->i_nlink > 0) 279 fs->fs_snapinum[snaploc] = ip->i_number; 280 281 mutex_enter(&si->si_lock); 282 if (is_active_snapshot(si, ip)) 283 panic("ffs_snapshot: %"PRIu64" already on list", ip->i_number); 284 TAILQ_INSERT_TAIL(&si->si_snapshots, ip, i_nextsnap); 285 if (TAILQ_FIRST(&si->si_snapshots) == ip) { 286 /* 287 * If this is the first snapshot on this filesystem, put the 288 * preliminary list in place and establish the cow handler. 289 */ 290 si->si_snapblklist = snaplist; 291 fscow_establish(mp, ffs_copyonwrite, devvp); 292 } 293 si->si_gen++; 294 mutex_exit(&si->si_lock); 295 296 vp->v_vflag |= VV_SYSTEM; 297 /* 298 * Set the mtime to the time the snapshot has been taken. 299 */ 300 TIMEVAL_TO_TIMESPEC(&starttime, &ts); 301 if (ctime) 302 *ctime = ts; 303 DIP_ASSIGN(ip, mtime, ts.tv_sec); 304 DIP_ASSIGN(ip, mtimensec, ts.tv_nsec); 305 ip->i_flag |= IN_CHANGE | IN_UPDATE; 306 /* 307 * Copy allocation information from all snapshots and then 308 * expunge them from our view. 309 */ 310 error = snapshot_expunge_snap(mp, vp, copy_fs, snaplistsize); 311 if (error) 312 goto out; 313 /* 314 * Write the superblock and its summary information to the snapshot. 315 */ 316 error = snapshot_writefs(mp, vp, sbbuf); 317 if (error) 318 goto out; 319 /* 320 * We're nearly done, ensure that the snapshot is completely on disk. 321 */ 322 error = VOP_FSYNC(vp, l->l_cred, FSYNC_WAIT, 0, 0); 323 if (error) 324 goto out; 325 /* 326 * Invalidate and free all pages on the snapshot vnode. 327 * We will read and write through the buffercache. 328 */ 329 rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); 330 error = VOP_PUTPAGES(vp, 0, 0, 331 PGO_ALLPAGES | PGO_CLEANIT | PGO_SYNCIO | PGO_FREE); 332 if (error) 333 goto out; 334 /* 335 * Invalidate short ( < fs_bsize ) buffers. We will always read 336 * full size buffers later. 337 */ 338 mutex_enter(&bufcache_lock); 339 KASSERT(LIST_FIRST(&vp->v_dirtyblkhd) == NULL); 340 for (bp = LIST_FIRST(&vp->v_cleanblkhd); bp; bp = nbp) { 341 nbp = LIST_NEXT(bp, b_vnbufs); 342 if (bp->b_bcount == fs->fs_bsize) 343 continue; 344 error = bbusy(bp, false, 0, NULL); 345 if (error != 0) { 346 if (error == EPASSTHROUGH) { 347 nbp = LIST_FIRST(&vp->v_cleanblkhd); 348 continue; 349 } 350 break; 351 } 352 brelsel(bp, BC_INVAL | BC_VFLUSH); 353 } 354 mutex_exit(&bufcache_lock); 355 356 out: 357 if (sbbuf != NULL) { 358 free(copy_fs->fs_csp, M_UFSMNT); 359 free(sbbuf, M_UFSMNT); 360 } 361 if (fs->fs_active != NULL) { 362 free(fs->fs_active, M_DEVBUF); 363 fs->fs_active = NULL; 364 } 365 366 mutex_enter(&si->si_lock); 367 if (snaplist != NULL) { 368 if (si->si_snapblklist == snaplist) 369 si->si_snapblklist = NULL; 370 free(snaplist, M_UFSMNT); 371 } 372 if (error) { 373 fs->fs_snapinum[snaploc] = 0; 374 } else { 375 /* 376 * As this is the newest list, it is the most inclusive, so 377 * should replace the previous list. 378 */ 379 si->si_snapblklist = ip->i_snapblklist; 380 } 381 si->si_gen++; 382 mutex_exit(&si->si_lock); 383 384 if (suspended) { 385 VOP_UNLOCK(vp); 386 vfs_resume(vp->v_mount); 387 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 388 #ifdef DEBUG 389 getmicrotime(&endtime); 390 timersub(&endtime, &starttime, &endtime); 391 printf("%s: suspended %lld.%03d sec, redo %d of %d\n", 392 mp->mnt_stat.f_mntonname, (long long)endtime.tv_sec, 393 endtime.tv_usec / 1000, redo, fs->fs_ncg); 394 #endif 395 } 396 if (error) { 397 if (UFS_WAPBL_BEGIN(mp) == 0) { 398 /* 399 * We depend on ffs_truncate() to call ffs_snapremove() 400 * before it may return an error. On failed 401 * ffs_truncate() we have normal file with leaked 402 * (meta-) data, but no snapshot to use. 403 */ 404 (void) ffs_truncate(vp, (off_t)0, 0, NOCRED); 405 UFS_WAPBL_END(mp); 406 } 407 } else if (ip->i_nlink > 0) 408 vref(vp); 409 return (error); 410 } 411 412 /* 413 * Prepare vnode to become a snapshot. 414 */ 415 static int 416 snapshot_setup(struct mount *mp, struct vnode *vp) 417 { 418 int error, n, len, loc, cg; 419 daddr_t blkno, numblks; 420 struct buf *ibp, *nbp; 421 struct fs *fs = VFSTOUFS(mp)->um_fs; 422 struct lwp *l = curlwp; 423 const int wbreak = blocks_in_journal(fs)/8; 424 struct inode *ip = VTOI(vp); 425 426 /* 427 * Check mount, readonly reference and owner. 428 */ 429 if (vp->v_mount != mp) 430 return EXDEV; 431 if (vp->v_writecount != 0) 432 return EBUSY; 433 error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FS_SNAPSHOT, 434 0, mp, vp, NULL); 435 if (error) 436 return EACCES; 437 438 /* 439 * Must completely truncate the file here. Allocated 440 * blocks on a snapshot mean that block has been copied 441 * on write, see ffs_copyonwrite() testing "blkno != 0" 442 */ 443 error = ufs_truncate_all(vp); 444 if (error) 445 return error; 446 447 /* Change inode to snapshot type file. */ 448 error = UFS_WAPBL_BEGIN(mp); 449 if (error) 450 return error; 451 #if defined(QUOTA) || defined(QUOTA2) 452 /* snapshot inodes are not accounted in quotas */ 453 chkiq(ip, -1, l->l_cred, 0); 454 #endif 455 ip->i_flags |= (SF_SNAPSHOT | SF_SNAPINVAL); 456 DIP_ASSIGN(ip, flags, ip->i_flags); 457 ip->i_flag |= IN_CHANGE | IN_UPDATE; 458 ffs_update(vp, NULL, NULL, UPDATE_WAIT); 459 UFS_WAPBL_END(mp); 460 461 KASSERT(ip->i_flags & SF_SNAPSHOT); 462 /* 463 * Write an empty list of preallocated blocks to the end of 464 * the snapshot to set size to at least that of the filesystem. 465 */ 466 numblks = howmany(fs->fs_size, fs->fs_frag); 467 blkno = 1; 468 blkno = ufs_rw64(blkno, UFS_FSNEEDSWAP(fs)); 469 error = vn_rdwr(UIO_WRITE, vp, 470 (void *)&blkno, sizeof(blkno), ffs_lblktosize(fs, (off_t)numblks), 471 UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, l->l_cred, NULL, NULL); 472 if (error) 473 return error; 474 /* 475 * Preallocate critical data structures so that we can copy 476 * them in without further allocation after we suspend all 477 * operations on the filesystem. We would like to just release 478 * the allocated buffers without writing them since they will 479 * be filled in below once we are ready to go, but this upsets 480 * the soft update code, so we go ahead and write the new buffers. 481 * 482 * Allocate all indirect blocks and mark all of them as not 483 * needing to be copied. 484 */ 485 error = UFS_WAPBL_BEGIN(mp); 486 if (error) 487 return error; 488 for (blkno = UFS_NDADDR, n = 0; blkno < numblks; blkno += FFS_NINDIR(fs)) { 489 error = ffs_balloc(vp, ffs_lblktosize(fs, (off_t)blkno), 490 fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); 491 if (error) 492 goto out; 493 brelse(ibp, 0); 494 if (wbreak > 0 && (++n % wbreak) == 0) { 495 UFS_WAPBL_END(mp); 496 error = UFS_WAPBL_BEGIN(mp); 497 if (error) 498 return error; 499 } 500 } 501 /* 502 * Allocate copies for the superblock and its summary information. 503 */ 504 error = ffs_balloc(vp, fs->fs_sblockloc, fs->fs_sbsize, l->l_cred, 505 0, &nbp); 506 if (error) 507 goto out; 508 bawrite(nbp); 509 blkno = ffs_fragstoblks(fs, fs->fs_csaddr); 510 len = howmany(fs->fs_cssize, fs->fs_bsize); 511 for (loc = 0; loc < len; loc++) { 512 error = ffs_balloc(vp, ffs_lblktosize(fs, (off_t)(blkno + loc)), 513 fs->fs_bsize, l->l_cred, 0, &nbp); 514 if (error) 515 goto out; 516 bawrite(nbp); 517 if (wbreak > 0 && (++n % wbreak) == 0) { 518 UFS_WAPBL_END(mp); 519 error = UFS_WAPBL_BEGIN(mp); 520 if (error) 521 return error; 522 } 523 } 524 /* 525 * Allocate all cylinder group blocks. 526 */ 527 for (cg = 0; cg < fs->fs_ncg; cg++) { 528 error = ffs_balloc(vp, ffs_lfragtosize(fs, cgtod(fs, cg)), 529 fs->fs_bsize, l->l_cred, 0, &nbp); 530 if (error) 531 goto out; 532 bawrite(nbp); 533 if (wbreak > 0 && (++n % wbreak) == 0) { 534 UFS_WAPBL_END(mp); 535 error = UFS_WAPBL_BEGIN(mp); 536 if (error) 537 return error; 538 } 539 } 540 541 out: 542 UFS_WAPBL_END(mp); 543 return error; 544 } 545 546 /* 547 * Create a copy of the superblock and its summary information. 548 * It is up to the caller to free copyfs and copy_fs->fs_csp. 549 */ 550 static int 551 snapshot_copyfs(struct mount *mp, struct vnode *vp, void **sbbuf) 552 { 553 int error, i, len, loc, size; 554 void *space; 555 int32_t *lp; 556 struct buf *bp; 557 struct fs *copyfs, *fs = VFSTOUFS(mp)->um_fs; 558 struct vnode *devvp = VTOI(vp)->i_devvp; 559 560 /* 561 * Grab a copy of the superblock and its summary information. 562 * We delay writing it until the suspension is released below. 563 */ 564 *sbbuf = malloc(fs->fs_bsize, M_UFSMNT, M_WAITOK); 565 loc = ffs_blkoff(fs, fs->fs_sblockloc); 566 if (loc > 0) 567 memset(*sbbuf, 0, loc); 568 copyfs = (struct fs *)((char *)(*sbbuf) + loc); 569 memcpy(copyfs, fs, fs->fs_sbsize); 570 size = fs->fs_bsize < SBLOCKSIZE ? fs->fs_bsize : SBLOCKSIZE; 571 if (fs->fs_sbsize < size) 572 memset((char *)(*sbbuf) + loc + fs->fs_sbsize, 0, 573 size - fs->fs_sbsize); 574 size = ffs_blkroundup(fs, fs->fs_cssize); 575 if (fs->fs_contigsumsize > 0) 576 size += fs->fs_ncg * sizeof(int32_t); 577 space = malloc(size, M_UFSMNT, M_WAITOK); 578 copyfs->fs_csp = space; 579 memcpy(copyfs->fs_csp, fs->fs_csp, fs->fs_cssize); 580 space = (char *)space + fs->fs_cssize; 581 loc = howmany(fs->fs_cssize, fs->fs_fsize); 582 i = fs->fs_frag - loc % fs->fs_frag; 583 len = (i == fs->fs_frag) ? 0 : i * fs->fs_fsize; 584 if (len > 0) { 585 if ((error = bread(devvp, FFS_FSBTODB(fs, fs->fs_csaddr + loc), 586 len, 0, &bp)) != 0) { 587 free(copyfs->fs_csp, M_UFSMNT); 588 free(*sbbuf, M_UFSMNT); 589 *sbbuf = NULL; 590 return error; 591 } 592 memcpy(space, bp->b_data, (u_int)len); 593 space = (char *)space + len; 594 brelse(bp, BC_INVAL | BC_NOCACHE); 595 } 596 if (fs->fs_contigsumsize > 0) { 597 copyfs->fs_maxcluster = lp = space; 598 for (i = 0; i < fs->fs_ncg; i++) 599 *lp++ = fs->fs_contigsumsize; 600 } 601 if (mp->mnt_wapbl) 602 copyfs->fs_flags &= ~FS_DOWAPBL; 603 return 0; 604 } 605 606 struct snapshot_expunge_ctx { 607 struct vnode *logvp; 608 struct vnode *vp; 609 struct fs *copy_fs; 610 }; 611 612 static bool 613 snapshot_expunge_selector(void *cl, struct vnode *xvp) 614 { 615 struct snapshot_expunge_ctx *c = cl; 616 struct inode *xp; 617 618 KASSERT(mutex_owned(xvp->v_interlock)); 619 620 xp = VTOI(xvp); 621 if (xvp->v_type == VNON || VTOI(xvp) == NULL || 622 (xp->i_flags & SF_SNAPSHOT)) 623 return false; 624 #ifdef DEBUG 625 if (snapdebug) 626 vprint("ffs_snapshot: busy vnode", xvp); 627 #endif 628 629 if (xvp == c->logvp) 630 return true; 631 632 if (xp->i_nlink > 0) 633 return false; 634 635 if (ffs_checkfreefile(c->copy_fs, c->vp, xp->i_number)) 636 return false; 637 638 return true; 639 } 640 641 /* 642 * We must check for active files that have been unlinked (e.g., with a zero 643 * link count). We have to expunge all trace of these files from the snapshot 644 * so that they are not reclaimed prematurely by fsck or unnecessarily dumped. 645 * Note that we skip unlinked snapshot files as they will be handled separately. 646 * Calculate the snapshot list size and create a preliminary list. 647 */ 648 static int 649 snapshot_expunge(struct mount *mp, struct vnode *vp, struct fs *copy_fs, 650 daddr_t *snaplistsize, daddr_t **snaplist) 651 { 652 int cg, error = 0, len, loc; 653 daddr_t blkno, *blkp; 654 struct fs *fs = VFSTOUFS(mp)->um_fs; 655 struct inode *xp; 656 struct vnode *logvp = NULL, *xvp; 657 struct vnode_iterator *marker; 658 struct snapshot_expunge_ctx ctx; 659 660 *snaplist = NULL; 661 /* 662 * Get the log inode if any. 663 */ 664 if ((fs->fs_flags & FS_DOWAPBL) && 665 fs->fs_journal_location == UFS_WAPBL_JOURNALLOC_IN_FILESYSTEM) { 666 error = VFS_VGET(mp, fs->fs_journallocs[UFS_WAPBL_INFS_INO], 667 LK_EXCLUSIVE, &logvp); 668 if (error) 669 goto out; 670 } 671 /* 672 * We also calculate the needed size for the snapshot list. 673 */ 674 *snaplistsize = fs->fs_ncg + howmany(fs->fs_cssize, fs->fs_bsize) + 675 FSMAXSNAP + 1 /* superblock */ + 1 /* last block */ + 1 /* size */; 676 677 vfs_vnode_iterator_init(mp, &marker); 678 ctx.logvp = logvp; 679 ctx.vp = vp; 680 ctx.copy_fs = copy_fs; 681 while ((xvp = vfs_vnode_iterator_next(marker, snapshot_expunge_selector, 682 &ctx))) 683 { 684 /* 685 * If there is a fragment, clear it here. 686 */ 687 xp = VTOI(xvp); 688 blkno = 0; 689 loc = howmany(xp->i_size, fs->fs_bsize) - 1; 690 if (loc < UFS_NDADDR) { 691 len = ffs_fragroundup(fs, ffs_blkoff(fs, xp->i_size)); 692 if (len > 0 && len < fs->fs_bsize) { 693 error = UFS_WAPBL_BEGIN(mp); 694 if (error) { 695 vrele(xvp); 696 vfs_vnode_iterator_destroy(marker); 697 goto out; 698 } 699 ffs_blkfree_snap(copy_fs, vp, db_get(xp, loc), 700 len, xp->i_number); 701 blkno = db_get(xp, loc); 702 db_assign(xp, loc, 0); 703 UFS_WAPBL_END(mp); 704 } 705 } 706 *snaplistsize += 1; 707 error = expunge(vp, xp, copy_fs, fullacct, BLK_NOCOPY); 708 if (blkno) 709 db_assign(xp, loc, blkno); 710 if (!error) { 711 error = UFS_WAPBL_BEGIN(mp); 712 if (!error) { 713 error = ffs_freefile_snap(copy_fs, vp, 714 xp->i_number, xp->i_mode); 715 UFS_WAPBL_END(mp); 716 } 717 } 718 vrele(xvp); 719 if (error) { 720 vfs_vnode_iterator_destroy(marker); 721 goto out; 722 } 723 } 724 vfs_vnode_iterator_destroy(marker); 725 726 /* 727 * Create a preliminary list of preallocated snapshot blocks. 728 */ 729 *snaplist = malloc(*snaplistsize * sizeof(daddr_t), M_UFSMNT, M_WAITOK); 730 blkp = &(*snaplist)[1]; 731 *blkp++ = ffs_lblkno(fs, fs->fs_sblockloc); 732 blkno = ffs_fragstoblks(fs, fs->fs_csaddr); 733 for (cg = 0; cg < fs->fs_ncg; cg++) { 734 if (ffs_fragstoblks(fs, cgtod(fs, cg)) > blkno) 735 break; 736 *blkp++ = ffs_fragstoblks(fs, cgtod(fs, cg)); 737 } 738 len = howmany(fs->fs_cssize, fs->fs_bsize); 739 for (loc = 0; loc < len; loc++) 740 *blkp++ = blkno + loc; 741 for (; cg < fs->fs_ncg; cg++) 742 *blkp++ = ffs_fragstoblks(fs, cgtod(fs, cg)); 743 (*snaplist)[0] = blkp - &(*snaplist)[0]; 744 745 out: 746 if (logvp != NULL) 747 vput(logvp); 748 if (error && *snaplist != NULL) { 749 free(*snaplist, M_UFSMNT); 750 *snaplist = NULL; 751 } 752 753 return error; 754 } 755 756 /* 757 * Copy allocation information from all the snapshots in this snapshot and 758 * then expunge them from its view. Also, collect the list of allocated 759 * blocks in i_snapblklist. 760 */ 761 static int 762 snapshot_expunge_snap(struct mount *mp, struct vnode *vp, 763 struct fs *copy_fs, daddr_t snaplistsize) 764 { 765 int error = 0, i; 766 daddr_t numblks, *snaplist = NULL; 767 struct fs *fs = VFSTOUFS(mp)->um_fs; 768 struct inode *ip = VTOI(vp), *xp; 769 struct lwp *l = curlwp; 770 struct snap_info *si = VFSTOUFS(mp)->um_snapinfo; 771 772 TAILQ_FOREACH(xp, &si->si_snapshots, i_nextsnap) { 773 if (xp != ip) { 774 error = expunge(vp, xp, fs, snapacct, BLK_SNAP); 775 if (error) 776 break; 777 } 778 if (xp->i_nlink != 0) 779 continue; 780 error = UFS_WAPBL_BEGIN(mp); 781 if (error) 782 break; 783 error = ffs_freefile_snap(copy_fs, vp, xp->i_number, xp->i_mode); 784 UFS_WAPBL_END(mp); 785 if (error) 786 break; 787 } 788 if (error) 789 goto out; 790 /* 791 * Allocate space for the full list of preallocated snapshot blocks. 792 */ 793 snaplist = malloc(snaplistsize * sizeof(daddr_t), M_UFSMNT, M_WAITOK); 794 ip->i_snapblklist = &snaplist[1]; 795 /* 796 * Expunge the blocks used by the snapshots from the set of 797 * blocks marked as used in the snapshot bitmaps. Also, collect 798 * the list of allocated blocks in i_snapblklist. 799 */ 800 error = expunge(vp, ip, copy_fs, mapacct, BLK_SNAP); 801 if (error) 802 goto out; 803 if (snaplistsize < ip->i_snapblklist - snaplist) 804 panic("ffs_snapshot: list too small"); 805 snaplistsize = ip->i_snapblklist - snaplist; 806 snaplist[0] = snaplistsize; 807 ip->i_snapblklist = &snaplist[0]; 808 /* 809 * Write out the list of allocated blocks to the end of the snapshot. 810 */ 811 numblks = howmany(fs->fs_size, fs->fs_frag); 812 for (i = 0; i < snaplistsize; i++) 813 snaplist[i] = ufs_rw64(snaplist[i], UFS_FSNEEDSWAP(fs)); 814 error = vn_rdwr(UIO_WRITE, vp, (void *)snaplist, 815 snaplistsize * sizeof(daddr_t), ffs_lblktosize(fs, (off_t)numblks), 816 UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT, l->l_cred, NULL, NULL); 817 for (i = 0; i < snaplistsize; i++) 818 snaplist[i] = ufs_rw64(snaplist[i], UFS_FSNEEDSWAP(fs)); 819 out: 820 if (error && snaplist != NULL) { 821 free(snaplist, M_UFSMNT); 822 ip->i_snapblklist = NULL; 823 } 824 return error; 825 } 826 827 /* 828 * Write the superblock and its summary information to the snapshot. 829 * Make sure, the first UFS_NDADDR blocks get copied to the snapshot. 830 */ 831 static int 832 snapshot_writefs(struct mount *mp, struct vnode *vp, void *sbbuf) 833 { 834 int error, len, loc; 835 void *space; 836 daddr_t blkno; 837 struct buf *bp; 838 struct fs *copyfs, *fs = VFSTOUFS(mp)->um_fs; 839 struct inode *ip = VTOI(vp); 840 struct lwp *l = curlwp; 841 842 copyfs = (struct fs *)((char *)sbbuf + ffs_blkoff(fs, fs->fs_sblockloc)); 843 844 /* 845 * Write the superblock and its summary information 846 * to the snapshot. 847 */ 848 blkno = ffs_fragstoblks(fs, fs->fs_csaddr); 849 len = howmany(fs->fs_cssize, fs->fs_bsize); 850 space = copyfs->fs_csp; 851 #ifdef FFS_EI 852 if (UFS_FSNEEDSWAP(fs)) { 853 ffs_sb_swap(copyfs, copyfs); 854 ffs_csum_swap(space, space, fs->fs_cssize); 855 } 856 #endif 857 error = UFS_WAPBL_BEGIN(mp); 858 if (error) 859 return error; 860 for (loc = 0; loc < len; loc++) { 861 error = bread(vp, blkno + loc, fs->fs_bsize, 862 B_MODIFY, &bp); 863 if (error) { 864 break; 865 } 866 memcpy(bp->b_data, space, fs->fs_bsize); 867 space = (char *)space + fs->fs_bsize; 868 bawrite(bp); 869 } 870 if (error) 871 goto out; 872 error = bread(vp, ffs_lblkno(fs, fs->fs_sblockloc), 873 fs->fs_bsize, B_MODIFY, &bp); 874 if (error) { 875 goto out; 876 } else { 877 memcpy(bp->b_data, sbbuf, fs->fs_bsize); 878 bawrite(bp); 879 } 880 /* 881 * Copy the first UFS_NDADDR blocks to the snapshot so 882 * ffs_copyonwrite() and ffs_snapblkfree() will always work on 883 * indirect blocks. 884 */ 885 for (loc = 0; loc < UFS_NDADDR; loc++) { 886 if (db_get(ip, loc) != 0) 887 continue; 888 error = ffs_balloc(vp, ffs_lblktosize(fs, (off_t)loc), 889 fs->fs_bsize, l->l_cred, 0, &bp); 890 if (error) 891 break; 892 error = rwfsblk(vp, B_READ, bp->b_data, loc); 893 if (error) { 894 brelse(bp, 0); 895 break; 896 } 897 bawrite(bp); 898 } 899 900 out: 901 UFS_WAPBL_END(mp); 902 return error; 903 } 904 905 /* 906 * Copy all cylinder group maps. 907 */ 908 static int 909 cgaccount(struct vnode *vp, int passno, int *redo) 910 { 911 int cg, error = 0; 912 struct buf *nbp; 913 struct fs *fs = VTOI(vp)->i_fs; 914 915 if (redo != NULL) 916 *redo = 0; 917 if (passno == 1) 918 fs->fs_active = malloc(howmany(fs->fs_ncg, NBBY), 919 M_DEVBUF, M_WAITOK | M_ZERO); 920 for (cg = 0; cg < fs->fs_ncg; cg++) { 921 if (passno == 2 && ACTIVECG_ISSET(fs, cg)) 922 continue; 923 924 if (redo != NULL) 925 *redo += 1; 926 error = UFS_WAPBL_BEGIN(vp->v_mount); 927 if (error) 928 return error; 929 error = ffs_balloc(vp, ffs_lfragtosize(fs, cgtod(fs, cg)), 930 fs->fs_bsize, curlwp->l_cred, 0, &nbp); 931 if (error) { 932 UFS_WAPBL_END(vp->v_mount); 933 break; 934 } 935 error = cgaccount1(cg, vp, nbp->b_data, passno); 936 bawrite(nbp); 937 UFS_WAPBL_END(vp->v_mount); 938 if (error) 939 break; 940 } 941 return error; 942 } 943 944 /* 945 * Copy a cylinder group map. All the unallocated blocks are marked 946 * BLK_NOCOPY so that the snapshot knows that it need not copy them 947 * if they are later written. If passno is one, then this is a first 948 * pass, so only setting needs to be done. If passno is 2, then this 949 * is a revision to a previous pass which must be undone as the 950 * replacement pass is done. 951 */ 952 static int 953 cgaccount1(int cg, struct vnode *vp, void *data, int passno) 954 { 955 struct buf *bp, *ibp; 956 struct inode *ip; 957 struct cg *cgp; 958 struct fs *fs; 959 struct lwp *l = curlwp; 960 daddr_t base, numblks; 961 int error, len, loc, ns __unused, indiroff; 962 963 ip = VTOI(vp); 964 fs = ip->i_fs; 965 ns = UFS_FSNEEDSWAP(fs); 966 error = bread(ip->i_devvp, FFS_FSBTODB(fs, cgtod(fs, cg)), 967 (int)fs->fs_cgsize, 0, &bp); 968 if (error) { 969 return (error); 970 } 971 cgp = (struct cg *)bp->b_data; 972 if (!cg_chkmagic(cgp, ns)) { 973 brelse(bp, 0); 974 return (EIO); 975 } 976 ACTIVECG_SET(fs, cg); 977 978 memcpy(data, bp->b_data, fs->fs_cgsize); 979 brelse(bp, 0); 980 if (fs->fs_cgsize < fs->fs_bsize) 981 memset((char *)data + fs->fs_cgsize, 0, 982 fs->fs_bsize - fs->fs_cgsize); 983 numblks = howmany(fs->fs_size, fs->fs_frag); 984 len = howmany(fs->fs_fpg, fs->fs_frag); 985 base = cgbase(fs, cg) / fs->fs_frag; 986 if (base + len >= numblks) 987 len = numblks - base - 1; 988 loc = 0; 989 if (base < UFS_NDADDR) { 990 for ( ; loc < UFS_NDADDR; loc++) { 991 if (ffs_isblock(fs, cg_blksfree(cgp, ns), loc)) 992 db_assign(ip, loc, BLK_NOCOPY); 993 else if (db_get(ip, loc) == BLK_NOCOPY) { 994 if (passno == 2) 995 db_assign(ip, loc, 0); 996 else if (passno == 1) 997 panic("ffs_snapshot: lost direct block"); 998 } 999 } 1000 } 1001 if ((error = ffs_balloc(vp, ffs_lblktosize(fs, (off_t)(base + loc)), 1002 fs->fs_bsize, l->l_cred, B_METAONLY, &ibp)) != 0) 1003 return (error); 1004 indiroff = (base + loc - UFS_NDADDR) % FFS_NINDIR(fs); 1005 for ( ; loc < len; loc++, indiroff++) { 1006 if (indiroff >= FFS_NINDIR(fs)) { 1007 bawrite(ibp); 1008 if ((error = ffs_balloc(vp, 1009 ffs_lblktosize(fs, (off_t)(base + loc)), 1010 fs->fs_bsize, l->l_cred, B_METAONLY, &ibp)) != 0) 1011 return (error); 1012 indiroff = 0; 1013 } 1014 if (ffs_isblock(fs, cg_blksfree(cgp, ns), loc)) 1015 idb_assign(ip, ibp->b_data, indiroff, BLK_NOCOPY); 1016 else if (idb_get(ip, ibp->b_data, indiroff) == BLK_NOCOPY) { 1017 if (passno == 2) 1018 idb_assign(ip, ibp->b_data, indiroff, 0); 1019 else if (passno == 1) 1020 panic("ffs_snapshot: lost indirect block"); 1021 } 1022 } 1023 bdwrite(ibp); 1024 return (0); 1025 } 1026 1027 /* 1028 * Before expunging a snapshot inode, note all the 1029 * blocks that it claims with BLK_SNAP so that fsck will 1030 * be able to account for those blocks properly and so 1031 * that this snapshot knows that it need not copy them 1032 * if the other snapshot holding them is freed. 1033 */ 1034 static int 1035 expunge(struct vnode *snapvp, struct inode *cancelip, struct fs *fs, 1036 acctfunc_t acctfunc, int expungetype) 1037 { 1038 int i, error, ns __unused; 1039 daddr_t lbn, rlbn; 1040 daddr_t len, blkno, numblks, blksperindir; 1041 struct ufs1_dinode *dip1; 1042 struct ufs2_dinode *dip2; 1043 struct lwp *l = curlwp; 1044 void *bap; 1045 struct buf *bp; 1046 struct mount *mp; 1047 1048 ns = UFS_FSNEEDSWAP(fs); 1049 mp = snapvp->v_mount; 1050 1051 error = UFS_WAPBL_BEGIN(mp); 1052 if (error) 1053 return error; 1054 /* 1055 * Prepare to expunge the inode. If its inode block has not 1056 * yet been copied, then allocate and fill the copy. 1057 */ 1058 lbn = ffs_fragstoblks(fs, ino_to_fsba(fs, cancelip->i_number)); 1059 error = snapblkaddr(snapvp, lbn, &blkno); 1060 if (error) 1061 return error; 1062 if (blkno != 0) { 1063 error = bread(snapvp, lbn, fs->fs_bsize, 1064 B_MODIFY, &bp); 1065 } else { 1066 error = ffs_balloc(snapvp, ffs_lblktosize(fs, (off_t)lbn), 1067 fs->fs_bsize, l->l_cred, 0, &bp); 1068 if (! error) 1069 error = rwfsblk(snapvp, B_READ, bp->b_data, lbn); 1070 } 1071 if (error) { 1072 UFS_WAPBL_END(mp); 1073 return error; 1074 } 1075 /* 1076 * Set a snapshot inode to be a zero length file, regular files 1077 * or unlinked snapshots to be completely unallocated. 1078 */ 1079 if (fs->fs_magic == FS_UFS1_MAGIC) { 1080 dip1 = (struct ufs1_dinode *)bp->b_data + 1081 ino_to_fsbo(fs, cancelip->i_number); 1082 if (cancelip->i_flags & SF_SNAPSHOT) { 1083 dip1->di_flags = 1084 ufs_rw32(ufs_rw32(dip1->di_flags, ns) | 1085 SF_SNAPINVAL, ns); 1086 } 1087 if (expungetype == BLK_NOCOPY || cancelip->i_nlink == 0) 1088 dip1->di_mode = 0; 1089 dip1->di_size = 0; 1090 dip1->di_blocks = 0; 1091 memset(&dip1->di_db[0], 0, (UFS_NDADDR + UFS_NIADDR) * sizeof(int32_t)); 1092 } else { 1093 dip2 = (struct ufs2_dinode *)bp->b_data + 1094 ino_to_fsbo(fs, cancelip->i_number); 1095 if (cancelip->i_flags & SF_SNAPSHOT) { 1096 dip2->di_flags = 1097 ufs_rw32(ufs_rw32(dip2->di_flags, ns) | 1098 SF_SNAPINVAL, ns); 1099 } 1100 if (expungetype == BLK_NOCOPY || cancelip->i_nlink == 0) 1101 dip2->di_mode = 0; 1102 dip2->di_size = 0; 1103 dip2->di_blocks = 0; 1104 memset(&dip2->di_db[0], 0, (UFS_NDADDR + UFS_NIADDR) * sizeof(int64_t)); 1105 } 1106 bdwrite(bp); 1107 UFS_WAPBL_END(mp); 1108 /* 1109 * Now go through and expunge all the blocks in the file 1110 * using the function requested. 1111 */ 1112 numblks = howmany(cancelip->i_size, fs->fs_bsize); 1113 if (fs->fs_magic == FS_UFS1_MAGIC) 1114 bap = &cancelip->i_ffs1_db[0]; 1115 else 1116 bap = &cancelip->i_ffs2_db[0]; 1117 error = (*acctfunc)(snapvp, bap, 0, UFS_NDADDR, fs, 0, expungetype); 1118 if (error) 1119 return (error); 1120 if (fs->fs_magic == FS_UFS1_MAGIC) 1121 bap = &cancelip->i_ffs1_ib[0]; 1122 else 1123 bap = &cancelip->i_ffs2_ib[0]; 1124 error = (*acctfunc)(snapvp, bap, 0, UFS_NIADDR, fs, -1, expungetype); 1125 if (error) 1126 return (error); 1127 blksperindir = 1; 1128 lbn = -UFS_NDADDR; 1129 len = numblks - UFS_NDADDR; 1130 rlbn = UFS_NDADDR; 1131 for (i = 0; len > 0 && i < UFS_NIADDR; i++) { 1132 error = indiracct(snapvp, ITOV(cancelip), i, 1133 ib_get(cancelip, i), lbn, rlbn, len, 1134 blksperindir, fs, acctfunc, expungetype); 1135 if (error) 1136 return (error); 1137 blksperindir *= FFS_NINDIR(fs); 1138 lbn -= blksperindir + 1; 1139 len -= blksperindir; 1140 rlbn += blksperindir; 1141 } 1142 return (0); 1143 } 1144 1145 /* 1146 * Descend an indirect block chain for vnode cancelvp accounting for all 1147 * its indirect blocks in snapvp. 1148 */ 1149 static int 1150 indiracct(struct vnode *snapvp, struct vnode *cancelvp, int level, 1151 daddr_t blkno, daddr_t lbn, daddr_t rlbn, daddr_t remblks, 1152 daddr_t blksperindir, struct fs *fs, acctfunc_t acctfunc, int expungetype) 1153 { 1154 int error, num, i; 1155 daddr_t subblksperindir; 1156 struct indir indirs[UFS_NIADDR + 2]; 1157 daddr_t last; 1158 void *bap; 1159 struct buf *bp; 1160 1161 if (blkno == 0) { 1162 if (expungetype == BLK_NOCOPY) 1163 return (0); 1164 panic("indiracct: missing indir"); 1165 } 1166 if ((error = ufs_getlbns(cancelvp, rlbn, indirs, &num)) != 0) 1167 return (error); 1168 if (lbn != indirs[num - 1 - level].in_lbn || num < 2) 1169 panic("indiracct: botched params"); 1170 /* 1171 * We have to expand bread here since it will deadlock looking 1172 * up the block number for any blocks that are not in the cache. 1173 */ 1174 error = ffs_getblk(cancelvp, lbn, FFS_FSBTODB(fs, blkno), fs->fs_bsize, 1175 false, &bp); 1176 if (error) 1177 return error; 1178 if ((bp->b_oflags & (BO_DONE | BO_DELWRI)) == 0 && (error = 1179 rwfsblk(bp->b_vp, B_READ, bp->b_data, ffs_fragstoblks(fs, blkno)))) { 1180 brelse(bp, 0); 1181 return (error); 1182 } 1183 /* 1184 * Account for the block pointers in this indirect block. 1185 */ 1186 last = howmany(remblks, blksperindir); 1187 if (last > FFS_NINDIR(fs)) 1188 last = FFS_NINDIR(fs); 1189 bap = malloc(fs->fs_bsize, M_DEVBUF, M_WAITOK | M_ZERO); 1190 memcpy((void *)bap, bp->b_data, fs->fs_bsize); 1191 brelse(bp, 0); 1192 error = (*acctfunc)(snapvp, bap, 0, last, 1193 fs, level == 0 ? rlbn : -1, expungetype); 1194 if (error || level == 0) 1195 goto out; 1196 /* 1197 * Account for the block pointers in each of the indirect blocks 1198 * in the levels below us. 1199 */ 1200 subblksperindir = blksperindir / FFS_NINDIR(fs); 1201 for (lbn++, level--, i = 0; i < last; i++) { 1202 error = indiracct(snapvp, cancelvp, level, 1203 idb_get(VTOI(snapvp), bap, i), lbn, rlbn, remblks, 1204 subblksperindir, fs, acctfunc, expungetype); 1205 if (error) 1206 goto out; 1207 rlbn += blksperindir; 1208 lbn -= blksperindir; 1209 remblks -= blksperindir; 1210 } 1211 out: 1212 free(bap, M_DEVBUF); 1213 return (error); 1214 } 1215 1216 /* 1217 * Do both snap accounting and map accounting. 1218 */ 1219 static int 1220 fullacct(struct vnode *vp, void *bap, int oldblkp, int lastblkp, 1221 struct fs *fs, daddr_t lblkno, 1222 int exptype /* BLK_SNAP or BLK_NOCOPY */) 1223 { 1224 int error; 1225 1226 if ((error = snapacct(vp, bap, oldblkp, lastblkp, fs, lblkno, exptype))) 1227 return (error); 1228 return (mapacct(vp, bap, oldblkp, lastblkp, fs, lblkno, exptype)); 1229 } 1230 1231 /* 1232 * Identify a set of blocks allocated in a snapshot inode. 1233 */ 1234 static int 1235 snapacct(struct vnode *vp, void *bap, int oldblkp, int lastblkp, 1236 struct fs *fs, daddr_t lblkno, 1237 int expungetype /* BLK_SNAP or BLK_NOCOPY */) 1238 { 1239 struct inode *ip = VTOI(vp); 1240 struct lwp *l = curlwp; 1241 struct mount *mp = vp->v_mount; 1242 daddr_t blkno; 1243 daddr_t lbn; 1244 struct buf *ibp; 1245 int error, n; 1246 const int wbreak = blocks_in_journal(VFSTOUFS(mp)->um_fs)/8; 1247 1248 error = UFS_WAPBL_BEGIN(mp); 1249 if (error) 1250 return error; 1251 for ( n = 0; oldblkp < lastblkp; oldblkp++) { 1252 blkno = idb_get(ip, bap, oldblkp); 1253 if (blkno == 0 || blkno == BLK_NOCOPY || blkno == BLK_SNAP) 1254 continue; 1255 lbn = ffs_fragstoblks(fs, blkno); 1256 if (lbn < UFS_NDADDR) { 1257 blkno = db_get(ip, lbn); 1258 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1259 } else { 1260 error = ffs_balloc(vp, ffs_lblktosize(fs, (off_t)lbn), 1261 fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); 1262 if (error) 1263 break; 1264 blkno = idb_get(ip, ibp->b_data, 1265 (lbn - UFS_NDADDR) % FFS_NINDIR(fs)); 1266 } 1267 /* 1268 * If we are expunging a snapshot vnode and we 1269 * find a block marked BLK_NOCOPY, then it is 1270 * one that has been allocated to this snapshot after 1271 * we took our current snapshot and can be ignored. 1272 */ 1273 if (expungetype == BLK_SNAP && blkno == BLK_NOCOPY) { 1274 if (lbn >= UFS_NDADDR) 1275 brelse(ibp, 0); 1276 } else { 1277 if (blkno != 0) 1278 panic("snapacct: bad block"); 1279 if (lbn < UFS_NDADDR) 1280 db_assign(ip, lbn, expungetype); 1281 else { 1282 idb_assign(ip, ibp->b_data, 1283 (lbn - UFS_NDADDR) % FFS_NINDIR(fs), expungetype); 1284 bdwrite(ibp); 1285 } 1286 } 1287 if (wbreak > 0 && (++n % wbreak) == 0) { 1288 UFS_WAPBL_END(mp); 1289 error = UFS_WAPBL_BEGIN(mp); 1290 if (error) 1291 return error; 1292 } 1293 } 1294 UFS_WAPBL_END(mp); 1295 return error; 1296 } 1297 1298 /* 1299 * Account for a set of blocks allocated in a snapshot inode. 1300 */ 1301 static int 1302 mapacct(struct vnode *vp, void *bap, int oldblkp, int lastblkp, 1303 struct fs *fs, daddr_t lblkno, int expungetype) 1304 { 1305 daddr_t blkno; 1306 struct inode *ip; 1307 struct mount *mp = vp->v_mount; 1308 ino_t inum; 1309 int acctit, error, n; 1310 const int wbreak = blocks_in_journal(VFSTOUFS(mp)->um_fs)/8; 1311 1312 error = UFS_WAPBL_BEGIN(mp); 1313 if (error) 1314 return error; 1315 ip = VTOI(vp); 1316 inum = ip->i_number; 1317 if (lblkno == -1) 1318 acctit = 0; 1319 else 1320 acctit = 1; 1321 for ( n = 0; oldblkp < lastblkp; oldblkp++, lblkno++) { 1322 blkno = idb_get(ip, bap, oldblkp); 1323 if (blkno == 0 || blkno == BLK_NOCOPY) 1324 continue; 1325 if (acctit && expungetype == BLK_SNAP && blkno != BLK_SNAP) 1326 *ip->i_snapblklist++ = lblkno; 1327 if (blkno == BLK_SNAP) 1328 blkno = ffs_blkstofrags(fs, lblkno); 1329 ffs_blkfree_snap(fs, vp, blkno, fs->fs_bsize, inum); 1330 if (wbreak > 0 && (++n % wbreak) == 0) { 1331 UFS_WAPBL_END(mp); 1332 error = UFS_WAPBL_BEGIN(mp); 1333 if (error) 1334 return error; 1335 } 1336 } 1337 UFS_WAPBL_END(mp); 1338 return (0); 1339 } 1340 1341 /* 1342 * Number of blocks that fit into the journal or zero if not logging. 1343 */ 1344 static int 1345 blocks_in_journal(struct fs *fs) 1346 { 1347 off_t bpj; 1348 1349 if ((fs->fs_flags & FS_DOWAPBL) == 0) 1350 return 0; 1351 bpj = 1; 1352 if (fs->fs_journal_version == UFS_WAPBL_VERSION) { 1353 switch (fs->fs_journal_location) { 1354 case UFS_WAPBL_JOURNALLOC_END_PARTITION: 1355 bpj = (off_t)fs->fs_journallocs[UFS_WAPBL_EPART_BLKSZ]* 1356 fs->fs_journallocs[UFS_WAPBL_EPART_COUNT]; 1357 break; 1358 case UFS_WAPBL_JOURNALLOC_IN_FILESYSTEM: 1359 bpj = (off_t)fs->fs_journallocs[UFS_WAPBL_INFS_BLKSZ]* 1360 fs->fs_journallocs[UFS_WAPBL_INFS_COUNT]; 1361 break; 1362 } 1363 } 1364 bpj /= fs->fs_bsize; 1365 return (bpj > 0 ? bpj : 1); 1366 } 1367 1368 /* 1369 * Decrement extra reference on snapshot when last name is removed. 1370 * It will not be freed until the last open reference goes away. 1371 */ 1372 void 1373 ffs_snapgone(struct vnode *vp) 1374 { 1375 struct inode *xp, *ip = VTOI(vp); 1376 struct mount *mp = spec_node_getmountedfs(ip->i_devvp); 1377 struct fs *fs; 1378 struct snap_info *si; 1379 int snaploc; 1380 1381 si = VFSTOUFS(mp)->um_snapinfo; 1382 1383 /* 1384 * Find snapshot in incore list. 1385 */ 1386 mutex_enter(&si->si_lock); 1387 TAILQ_FOREACH(xp, &si->si_snapshots, i_nextsnap) 1388 if (xp == ip) 1389 break; 1390 mutex_exit(&si->si_lock); 1391 if (xp != NULL) 1392 vrele(ITOV(ip)); 1393 #ifdef DEBUG 1394 else if (snapdebug) 1395 printf("ffs_snapgone: lost snapshot vnode %llu\n", 1396 (unsigned long long)ip->i_number); 1397 #endif 1398 /* 1399 * Delete snapshot inode from superblock. Keep list dense. 1400 */ 1401 mutex_enter(&si->si_lock); 1402 fs = ip->i_fs; 1403 for (snaploc = 0; snaploc < FSMAXSNAP; snaploc++) 1404 if (fs->fs_snapinum[snaploc] == ip->i_number) 1405 break; 1406 if (snaploc < FSMAXSNAP) { 1407 for (snaploc++; snaploc < FSMAXSNAP; snaploc++) { 1408 if (fs->fs_snapinum[snaploc] == 0) 1409 break; 1410 fs->fs_snapinum[snaploc - 1] = fs->fs_snapinum[snaploc]; 1411 } 1412 fs->fs_snapinum[snaploc - 1] = 0; 1413 } 1414 si->si_gen++; 1415 mutex_exit(&si->si_lock); 1416 } 1417 1418 /* 1419 * Prepare a snapshot file for being removed. 1420 */ 1421 void 1422 ffs_snapremove(struct vnode *vp) 1423 { 1424 struct inode *ip = VTOI(vp), *xp; 1425 struct vnode *devvp = ip->i_devvp; 1426 struct fs *fs = ip->i_fs; 1427 struct mount *mp = spec_node_getmountedfs(devvp); 1428 struct buf *ibp; 1429 struct snap_info *si; 1430 struct lwp *l = curlwp; 1431 daddr_t numblks, blkno, dblk; 1432 int error, loc, last; 1433 1434 si = VFSTOUFS(mp)->um_snapinfo; 1435 /* 1436 * If active, delete from incore list (this snapshot may 1437 * already have been in the process of being deleted, so 1438 * would not have been active). 1439 * 1440 * Clear copy-on-write flag if last snapshot. 1441 */ 1442 mutex_enter(&si->si_snaplock); 1443 mutex_enter(&si->si_lock); 1444 if (is_active_snapshot(si, ip)) { 1445 TAILQ_REMOVE(&si->si_snapshots, ip, i_nextsnap); 1446 if (TAILQ_FIRST(&si->si_snapshots) != 0) { 1447 /* Roll back the list of preallocated blocks. */ 1448 xp = TAILQ_LAST(&si->si_snapshots, inodelst); 1449 si->si_snapblklist = xp->i_snapblklist; 1450 si->si_gen++; 1451 mutex_exit(&si->si_lock); 1452 mutex_exit(&si->si_snaplock); 1453 } else { 1454 si->si_snapblklist = 0; 1455 si->si_gen++; 1456 mutex_exit(&si->si_lock); 1457 mutex_exit(&si->si_snaplock); 1458 fscow_disestablish(mp, ffs_copyonwrite, devvp); 1459 } 1460 if (ip->i_snapblklist != NULL) { 1461 free(ip->i_snapblklist, M_UFSMNT); 1462 ip->i_snapblklist = NULL; 1463 } 1464 } else { 1465 mutex_exit(&si->si_lock); 1466 mutex_exit(&si->si_snaplock); 1467 } 1468 /* 1469 * Clear all BLK_NOCOPY fields. Pass any block claims to other 1470 * snapshots that want them (see ffs_snapblkfree below). 1471 */ 1472 for (blkno = 1; blkno < UFS_NDADDR; blkno++) { 1473 dblk = db_get(ip, blkno); 1474 if (dblk == BLK_NOCOPY || dblk == BLK_SNAP) 1475 db_assign(ip, blkno, 0); 1476 else if ((dblk == ffs_blkstofrags(fs, blkno) && 1477 ffs_snapblkfree(fs, ip->i_devvp, dblk, fs->fs_bsize, 1478 ip->i_number))) { 1479 DIP_ADD(ip, blocks, -btodb(fs->fs_bsize)); 1480 db_assign(ip, blkno, 0); 1481 } 1482 } 1483 numblks = howmany(ip->i_size, fs->fs_bsize); 1484 for (blkno = UFS_NDADDR; blkno < numblks; blkno += FFS_NINDIR(fs)) { 1485 error = ffs_balloc(vp, ffs_lblktosize(fs, (off_t)blkno), 1486 fs->fs_bsize, l->l_cred, B_METAONLY, &ibp); 1487 if (error) 1488 continue; 1489 if (fs->fs_size - blkno > FFS_NINDIR(fs)) 1490 last = FFS_NINDIR(fs); 1491 else 1492 last = fs->fs_size - blkno; 1493 for (loc = 0; loc < last; loc++) { 1494 dblk = idb_get(ip, ibp->b_data, loc); 1495 if (dblk == BLK_NOCOPY || dblk == BLK_SNAP) 1496 idb_assign(ip, ibp->b_data, loc, 0); 1497 else if (dblk == ffs_blkstofrags(fs, blkno) && 1498 ffs_snapblkfree(fs, ip->i_devvp, dblk, 1499 fs->fs_bsize, ip->i_number)) { 1500 DIP_ADD(ip, blocks, -btodb(fs->fs_bsize)); 1501 idb_assign(ip, ibp->b_data, loc, 0); 1502 } 1503 } 1504 bawrite(ibp); 1505 UFS_WAPBL_END(mp); 1506 error = UFS_WAPBL_BEGIN(mp); 1507 KASSERT(error == 0); 1508 } 1509 /* 1510 * Clear snapshot flag and drop reference. 1511 */ 1512 ip->i_flags &= ~(SF_SNAPSHOT | SF_SNAPINVAL); 1513 DIP_ASSIGN(ip, flags, ip->i_flags); 1514 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1515 #if defined(QUOTA) || defined(QUOTA2) 1516 chkdq(ip, DIP(ip, blocks), l->l_cred, FORCE); 1517 chkiq(ip, 1, l->l_cred, FORCE); 1518 #endif 1519 } 1520 1521 /* 1522 * Notification that a block is being freed. Return zero if the free 1523 * should be allowed to proceed. Return non-zero if the snapshot file 1524 * wants to claim the block. The block will be claimed if it is an 1525 * uncopied part of one of the snapshots. It will be freed if it is 1526 * either a BLK_NOCOPY or has already been copied in all of the snapshots. 1527 * If a fragment is being freed, then all snapshots that care about 1528 * it must make a copy since a snapshot file can only claim full sized 1529 * blocks. Note that if more than one snapshot file maps the block, 1530 * we can pick one at random to claim it. Since none of the snapshots 1531 * can change, we are assurred that they will all see the same unmodified 1532 * image. When deleting a snapshot file (see ffs_snapremove above), we 1533 * must push any of these claimed blocks to one of the other snapshots 1534 * that maps it. These claimed blocks are easily identified as they will 1535 * have a block number equal to their logical block number within the 1536 * snapshot. A copied block can never have this property because they 1537 * must always have been allocated from a BLK_NOCOPY location. 1538 */ 1539 int 1540 ffs_snapblkfree(struct fs *fs, struct vnode *devvp, daddr_t bno, 1541 long size, ino_t inum) 1542 { 1543 struct mount *mp = spec_node_getmountedfs(devvp); 1544 struct buf *ibp; 1545 struct inode *ip; 1546 struct vnode *vp = NULL; 1547 struct snap_info *si; 1548 void *saved_data = NULL; 1549 daddr_t lbn; 1550 daddr_t blkno; 1551 uint32_t gen; 1552 int indiroff = 0, error = 0, claimedblk = 0; 1553 1554 si = VFSTOUFS(mp)->um_snapinfo; 1555 lbn = ffs_fragstoblks(fs, bno); 1556 mutex_enter(&si->si_snaplock); 1557 mutex_enter(&si->si_lock); 1558 si->si_owner = curlwp; 1559 1560 retry: 1561 gen = si->si_gen; 1562 TAILQ_FOREACH(ip, &si->si_snapshots, i_nextsnap) { 1563 vp = ITOV(ip); 1564 /* 1565 * Lookup block being written. 1566 */ 1567 if (lbn < UFS_NDADDR) { 1568 blkno = db_get(ip, lbn); 1569 } else { 1570 mutex_exit(&si->si_lock); 1571 error = ffs_balloc(vp, ffs_lblktosize(fs, (off_t)lbn), 1572 fs->fs_bsize, FSCRED, B_METAONLY, &ibp); 1573 if (error) { 1574 mutex_enter(&si->si_lock); 1575 break; 1576 } 1577 indiroff = (lbn - UFS_NDADDR) % FFS_NINDIR(fs); 1578 blkno = idb_get(ip, ibp->b_data, indiroff); 1579 mutex_enter(&si->si_lock); 1580 if (gen != si->si_gen) { 1581 brelse(ibp, 0); 1582 goto retry; 1583 } 1584 } 1585 /* 1586 * Check to see if block needs to be copied. 1587 */ 1588 if (blkno == 0) { 1589 /* 1590 * A block that we map is being freed. If it has not 1591 * been claimed yet, we will claim or copy it (below). 1592 */ 1593 claimedblk = 1; 1594 } else if (blkno == BLK_SNAP) { 1595 /* 1596 * No previous snapshot claimed the block, 1597 * so it will be freed and become a BLK_NOCOPY 1598 * (don't care) for us. 1599 */ 1600 if (claimedblk) 1601 panic("snapblkfree: inconsistent block type"); 1602 if (lbn < UFS_NDADDR) { 1603 db_assign(ip, lbn, BLK_NOCOPY); 1604 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1605 } else { 1606 idb_assign(ip, ibp->b_data, indiroff, 1607 BLK_NOCOPY); 1608 mutex_exit(&si->si_lock); 1609 if (ip->i_nlink > 0) 1610 bwrite(ibp); 1611 else 1612 bdwrite(ibp); 1613 mutex_enter(&si->si_lock); 1614 if (gen != si->si_gen) 1615 goto retry; 1616 } 1617 continue; 1618 } else /* BLK_NOCOPY or default */ { 1619 /* 1620 * If the snapshot has already copied the block 1621 * (default), or does not care about the block, 1622 * it is not needed. 1623 */ 1624 if (lbn >= UFS_NDADDR) 1625 brelse(ibp, 0); 1626 continue; 1627 } 1628 /* 1629 * If this is a full size block, we will just grab it 1630 * and assign it to the snapshot inode. Otherwise we 1631 * will proceed to copy it. See explanation for this 1632 * routine as to why only a single snapshot needs to 1633 * claim this block. 1634 */ 1635 if (size == fs->fs_bsize) { 1636 #ifdef DEBUG 1637 if (snapdebug) 1638 printf("%s %llu lbn %" PRId64 1639 "from inum %llu\n", 1640 "Grabonremove: snapino", 1641 (unsigned long long)ip->i_number, 1642 lbn, (unsigned long long)inum); 1643 #endif 1644 mutex_exit(&si->si_lock); 1645 if (lbn < UFS_NDADDR) { 1646 db_assign(ip, lbn, bno); 1647 } else { 1648 idb_assign(ip, ibp->b_data, indiroff, bno); 1649 if (ip->i_nlink > 0) 1650 bwrite(ibp); 1651 else 1652 bdwrite(ibp); 1653 } 1654 DIP_ADD(ip, blocks, btodb(size)); 1655 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1656 if (ip->i_nlink > 0 && mp->mnt_wapbl) 1657 error = syncsnap(vp); 1658 else 1659 error = 0; 1660 mutex_enter(&si->si_lock); 1661 si->si_owner = NULL; 1662 mutex_exit(&si->si_lock); 1663 mutex_exit(&si->si_snaplock); 1664 return (error == 0); 1665 } 1666 if (lbn >= UFS_NDADDR) 1667 brelse(ibp, 0); 1668 #ifdef DEBUG 1669 if (snapdebug) 1670 printf("%s%llu lbn %" PRId64 " %s %llu size %ld\n", 1671 "Copyonremove: snapino ", 1672 (unsigned long long)ip->i_number, 1673 lbn, "for inum", (unsigned long long)inum, size); 1674 #endif 1675 /* 1676 * If we have already read the old block contents, then 1677 * simply copy them to the new block. Note that we need 1678 * to synchronously write snapshots that have not been 1679 * unlinked, and hence will be visible after a crash, 1680 * to ensure their integrity. 1681 */ 1682 mutex_exit(&si->si_lock); 1683 if (saved_data == NULL) { 1684 saved_data = malloc(fs->fs_bsize, M_UFSMNT, M_WAITOK); 1685 error = rwfsblk(vp, B_READ, saved_data, lbn); 1686 if (error) { 1687 free(saved_data, M_UFSMNT); 1688 saved_data = NULL; 1689 mutex_enter(&si->si_lock); 1690 break; 1691 } 1692 } 1693 error = wrsnapblk(vp, saved_data, lbn); 1694 if (error == 0 && ip->i_nlink > 0 && mp->mnt_wapbl) 1695 error = syncsnap(vp); 1696 mutex_enter(&si->si_lock); 1697 if (error) 1698 break; 1699 if (gen != si->si_gen) 1700 goto retry; 1701 } 1702 si->si_owner = NULL; 1703 mutex_exit(&si->si_lock); 1704 mutex_exit(&si->si_snaplock); 1705 if (saved_data) 1706 free(saved_data, M_UFSMNT); 1707 /* 1708 * If we have been unable to allocate a block in which to do 1709 * the copy, then return non-zero so that the fragment will 1710 * not be freed. Although space will be lost, the snapshot 1711 * will stay consistent. 1712 */ 1713 return (error); 1714 } 1715 1716 /* 1717 * Associate snapshot files when mounting. 1718 */ 1719 void 1720 ffs_snapshot_mount(struct mount *mp) 1721 { 1722 struct vnode *devvp = VFSTOUFS(mp)->um_devvp; 1723 struct fs *fs = VFSTOUFS(mp)->um_fs; 1724 struct lwp *l = curlwp; 1725 struct vnode *vp; 1726 struct inode *ip, *xp; 1727 struct snap_info *si; 1728 daddr_t snaplistsize, *snapblklist; 1729 int i, error, ns __unused, snaploc, loc; 1730 1731 /* 1732 * No persistent snapshots on apple ufs file systems. 1733 */ 1734 if (UFS_MPISAPPLEUFS(VFSTOUFS(mp))) 1735 return; 1736 1737 si = VFSTOUFS(mp)->um_snapinfo; 1738 ns = UFS_FSNEEDSWAP(fs); 1739 /* 1740 * XXX The following needs to be set before ffs_truncate or 1741 * VOP_READ can be called. 1742 */ 1743 mp->mnt_stat.f_iosize = fs->fs_bsize; 1744 /* 1745 * Process each snapshot listed in the superblock. 1746 */ 1747 vp = NULL; 1748 mutex_enter(&si->si_lock); 1749 for (snaploc = 0; snaploc < FSMAXSNAP; snaploc++) { 1750 if (fs->fs_snapinum[snaploc] == 0) 1751 break; 1752 if ((error = VFS_VGET(mp, fs->fs_snapinum[snaploc], 1753 LK_EXCLUSIVE, &vp)) != 0) { 1754 printf("ffs_snapshot_mount: vget failed %d\n", error); 1755 continue; 1756 } 1757 ip = VTOI(vp); 1758 if ((ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL)) != 1759 SF_SNAPSHOT) { 1760 printf("ffs_snapshot_mount: non-snapshot inode %d\n", 1761 fs->fs_snapinum[snaploc]); 1762 vput(vp); 1763 vp = NULL; 1764 for (loc = snaploc + 1; loc < FSMAXSNAP; loc++) { 1765 if (fs->fs_snapinum[loc] == 0) 1766 break; 1767 fs->fs_snapinum[loc - 1] = fs->fs_snapinum[loc]; 1768 } 1769 fs->fs_snapinum[loc - 1] = 0; 1770 snaploc--; 1771 continue; 1772 } 1773 1774 /* 1775 * Read the block hints list. Use an empty list on 1776 * read errors. 1777 */ 1778 error = vn_rdwr(UIO_READ, vp, 1779 (void *)&snaplistsize, sizeof(snaplistsize), 1780 ffs_lblktosize(fs, howmany(fs->fs_size, fs->fs_frag)), 1781 UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT|IO_ALTSEMANTICS, 1782 l->l_cred, NULL, NULL); 1783 if (error) { 1784 printf("ffs_snapshot_mount: read_1 failed %d\n", error); 1785 snaplistsize = 1; 1786 } else 1787 snaplistsize = ufs_rw64(snaplistsize, ns); 1788 snapblklist = malloc( 1789 snaplistsize * sizeof(daddr_t), M_UFSMNT, M_WAITOK); 1790 if (error) 1791 snapblklist[0] = 1; 1792 else { 1793 error = vn_rdwr(UIO_READ, vp, (void *)snapblklist, 1794 snaplistsize * sizeof(daddr_t), 1795 ffs_lblktosize(fs, howmany(fs->fs_size, fs->fs_frag)), 1796 UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT|IO_ALTSEMANTICS, 1797 l->l_cred, NULL, NULL); 1798 for (i = 0; i < snaplistsize; i++) 1799 snapblklist[i] = ufs_rw64(snapblklist[i], ns); 1800 if (error) { 1801 printf("ffs_snapshot_mount: read_2 failed %d\n", 1802 error); 1803 snapblklist[0] = 1; 1804 } 1805 } 1806 ip->i_snapblklist = &snapblklist[0]; 1807 1808 /* 1809 * Link it onto the active snapshot list. 1810 */ 1811 if (is_active_snapshot(si, ip)) 1812 panic("ffs_snapshot_mount: %"PRIu64" already on list", 1813 ip->i_number); 1814 else 1815 TAILQ_INSERT_TAIL(&si->si_snapshots, ip, i_nextsnap); 1816 vp->v_vflag |= VV_SYSTEM; 1817 VOP_UNLOCK(vp); 1818 } 1819 /* 1820 * No usable snapshots found. 1821 */ 1822 if (vp == NULL) { 1823 mutex_exit(&si->si_lock); 1824 return; 1825 } 1826 /* 1827 * Attach the block hints list. We always want to 1828 * use the list from the newest snapshot. 1829 */ 1830 xp = TAILQ_LAST(&si->si_snapshots, inodelst); 1831 si->si_snapblklist = xp->i_snapblklist; 1832 fscow_establish(mp, ffs_copyonwrite, devvp); 1833 si->si_gen++; 1834 mutex_exit(&si->si_lock); 1835 } 1836 1837 /* 1838 * Disassociate snapshot files when unmounting. 1839 */ 1840 void 1841 ffs_snapshot_unmount(struct mount *mp) 1842 { 1843 struct vnode *devvp = VFSTOUFS(mp)->um_devvp; 1844 struct inode *xp; 1845 struct vnode *vp = NULL; 1846 struct snap_info *si; 1847 1848 si = VFSTOUFS(mp)->um_snapinfo; 1849 mutex_enter(&si->si_lock); 1850 while ((xp = TAILQ_FIRST(&si->si_snapshots)) != 0) { 1851 vp = ITOV(xp); 1852 TAILQ_REMOVE(&si->si_snapshots, xp, i_nextsnap); 1853 if (xp->i_snapblklist == si->si_snapblklist) 1854 si->si_snapblklist = NULL; 1855 free(xp->i_snapblklist, M_UFSMNT); 1856 if (xp->i_nlink > 0) { 1857 si->si_gen++; 1858 mutex_exit(&si->si_lock); 1859 vrele(vp); 1860 mutex_enter(&si->si_lock); 1861 } 1862 } 1863 si->si_gen++; 1864 mutex_exit(&si->si_lock); 1865 if (vp) 1866 fscow_disestablish(mp, ffs_copyonwrite, devvp); 1867 } 1868 1869 /* 1870 * Check for need to copy block that is about to be written, 1871 * copying the block if necessary. 1872 */ 1873 static int 1874 ffs_copyonwrite(void *v, struct buf *bp, bool data_valid) 1875 { 1876 struct fs *fs; 1877 struct inode *ip; 1878 struct vnode *devvp = v, *vp = NULL; 1879 struct mount *mp = spec_node_getmountedfs(devvp); 1880 struct snap_info *si; 1881 void *saved_data = NULL; 1882 daddr_t lbn, blkno, *snapblklist; 1883 uint32_t gen; 1884 int lower, upper, mid, snapshot_locked = 0, error = 0; 1885 1886 /* 1887 * Check for valid snapshots. 1888 */ 1889 si = VFSTOUFS(mp)->um_snapinfo; 1890 mutex_enter(&si->si_lock); 1891 ip = TAILQ_FIRST(&si->si_snapshots); 1892 if (ip == NULL) { 1893 mutex_exit(&si->si_lock); 1894 return 0; 1895 } 1896 /* 1897 * First check to see if it is after the file system, 1898 * in the journal or in the preallocated list. 1899 * By doing these checks we avoid several potential deadlocks. 1900 */ 1901 fs = ip->i_fs; 1902 lbn = ffs_fragstoblks(fs, FFS_DBTOFSB(fs, bp->b_blkno)); 1903 if (bp->b_blkno >= FFS_FSBTODB(fs, fs->fs_size)) { 1904 mutex_exit(&si->si_lock); 1905 return 0; 1906 } 1907 if ((fs->fs_flags & FS_DOWAPBL) && 1908 fs->fs_journal_location == UFS_WAPBL_JOURNALLOC_IN_FILESYSTEM) { 1909 off_t blk_off, log_start, log_end; 1910 1911 log_start = (off_t)fs->fs_journallocs[UFS_WAPBL_INFS_ADDR] * 1912 fs->fs_journallocs[UFS_WAPBL_INFS_BLKSZ]; 1913 log_end = log_start + fs->fs_journallocs[UFS_WAPBL_INFS_COUNT] * 1914 fs->fs_journallocs[UFS_WAPBL_INFS_BLKSZ]; 1915 blk_off = dbtob(bp->b_blkno); 1916 if (blk_off >= log_start && blk_off < log_end) { 1917 mutex_exit(&si->si_lock); 1918 return 0; 1919 } 1920 } 1921 snapblklist = si->si_snapblklist; 1922 upper = (snapblklist != NULL ? snapblklist[0] - 1 : 0); 1923 lower = 1; 1924 while (lower <= upper) { 1925 mid = (lower + upper) / 2; 1926 if (snapblklist[mid] == lbn) 1927 break; 1928 if (snapblklist[mid] < lbn) 1929 lower = mid + 1; 1930 else 1931 upper = mid - 1; 1932 } 1933 if (lower <= upper) { 1934 mutex_exit(&si->si_lock); 1935 return 0; 1936 } 1937 /* 1938 * Not in the precomputed list, so check the snapshots. 1939 */ 1940 if (si->si_owner != curlwp) { 1941 if (!mutex_tryenter(&si->si_snaplock)) { 1942 mutex_exit(&si->si_lock); 1943 mutex_enter(&si->si_snaplock); 1944 mutex_enter(&si->si_lock); 1945 } 1946 si->si_owner = curlwp; 1947 snapshot_locked = 1; 1948 } 1949 if (data_valid && bp->b_bcount == fs->fs_bsize) 1950 saved_data = bp->b_data; 1951 retry: 1952 gen = si->si_gen; 1953 TAILQ_FOREACH(ip, &si->si_snapshots, i_nextsnap) { 1954 vp = ITOV(ip); 1955 /* 1956 * We ensure that everything of our own that needs to be 1957 * copied will be done at the time that ffs_snapshot is 1958 * called. Thus we can skip the check here which can 1959 * deadlock in doing the lookup in ffs_balloc. 1960 */ 1961 if (bp->b_vp == vp) 1962 continue; 1963 /* 1964 * Check to see if block needs to be copied. 1965 */ 1966 if (lbn < UFS_NDADDR) { 1967 blkno = db_get(ip, lbn); 1968 } else { 1969 mutex_exit(&si->si_lock); 1970 blkno = 0; /* XXX: GCC */ 1971 if ((error = snapblkaddr(vp, lbn, &blkno)) != 0) { 1972 mutex_enter(&si->si_lock); 1973 break; 1974 } 1975 mutex_enter(&si->si_lock); 1976 if (gen != si->si_gen) 1977 goto retry; 1978 } 1979 KASSERTMSG((blkno != BLK_SNAP || bp->b_lblkno < 0), 1980 "ffs_copyonwrite: bad copy block: blkno %jd, lblkno %jd", 1981 (intmax_t)blkno, (intmax_t)bp->b_lblkno); 1982 if (blkno != 0) 1983 continue; 1984 1985 if (uvm_lwp_is_pagedaemon(curlwp)) { 1986 error = ENOMEM; 1987 break; 1988 } 1989 /* Only one level of recursion allowed. */ 1990 KASSERT(snapshot_locked); 1991 /* 1992 * Allocate the block into which to do the copy. Since 1993 * multiple processes may all try to copy the same block, 1994 * we have to recheck our need to do a copy if we sleep 1995 * waiting for the lock. 1996 * 1997 * Because all snapshots on a filesystem share a single 1998 * lock, we ensure that we will never be in competition 1999 * with another process to allocate a block. 2000 */ 2001 #ifdef DEBUG 2002 if (snapdebug) { 2003 printf("Copyonwrite: snapino %llu lbn %" PRId64 " for ", 2004 (unsigned long long)ip->i_number, lbn); 2005 if (bp->b_vp == devvp) 2006 printf("fs metadata"); 2007 else 2008 printf("inum %llu", (unsigned long long) 2009 VTOI(bp->b_vp)->i_number); 2010 printf(" lblkno %" PRId64 "\n", bp->b_lblkno); 2011 } 2012 #endif 2013 /* 2014 * If we have already read the old block contents, then 2015 * simply copy them to the new block. Note that we need 2016 * to synchronously write snapshots that have not been 2017 * unlinked, and hence will be visible after a crash, 2018 * to ensure their integrity. 2019 */ 2020 mutex_exit(&si->si_lock); 2021 if (saved_data == NULL) { 2022 saved_data = malloc(fs->fs_bsize, M_UFSMNT, M_WAITOK); 2023 error = rwfsblk(vp, B_READ, saved_data, lbn); 2024 if (error) { 2025 free(saved_data, M_UFSMNT); 2026 saved_data = NULL; 2027 mutex_enter(&si->si_lock); 2028 break; 2029 } 2030 } 2031 error = wrsnapblk(vp, saved_data, lbn); 2032 if (error == 0 && ip->i_nlink > 0 && mp->mnt_wapbl) 2033 error = syncsnap(vp); 2034 mutex_enter(&si->si_lock); 2035 if (error) 2036 break; 2037 if (gen != si->si_gen) 2038 goto retry; 2039 } 2040 /* 2041 * Note that we need to synchronously write snapshots that 2042 * have not been unlinked, and hence will be visible after 2043 * a crash, to ensure their integrity. 2044 */ 2045 if (snapshot_locked) { 2046 si->si_owner = NULL; 2047 mutex_exit(&si->si_lock); 2048 mutex_exit(&si->si_snaplock); 2049 } else 2050 mutex_exit(&si->si_lock); 2051 if (saved_data && saved_data != bp->b_data) 2052 free(saved_data, M_UFSMNT); 2053 return error; 2054 } 2055 2056 /* 2057 * Read from a snapshot. 2058 */ 2059 int 2060 ffs_snapshot_read(struct vnode *vp, struct uio *uio, int ioflag) 2061 { 2062 struct inode *ip = VTOI(vp); 2063 struct fs *fs = ip->i_fs; 2064 struct snap_info *si = VFSTOUFS(vp->v_mount)->um_snapinfo; 2065 struct buf *bp; 2066 daddr_t lbn, nextlbn; 2067 off_t fsbytes, bytesinfile; 2068 long size, xfersize, blkoffset; 2069 int error; 2070 2071 mutex_enter(&si->si_snaplock); 2072 2073 if (ioflag & IO_ALTSEMANTICS) 2074 fsbytes = ip->i_size; 2075 else 2076 fsbytes = ffs_lfragtosize(fs, fs->fs_size); 2077 for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) { 2078 bytesinfile = fsbytes - uio->uio_offset; 2079 if (bytesinfile <= 0) 2080 break; 2081 lbn = ffs_lblkno(fs, uio->uio_offset); 2082 nextlbn = lbn + 1; 2083 size = fs->fs_bsize; 2084 blkoffset = ffs_blkoff(fs, uio->uio_offset); 2085 xfersize = MIN(MIN(fs->fs_bsize - blkoffset, uio->uio_resid), 2086 bytesinfile); 2087 2088 if (ffs_lblktosize(fs, nextlbn + 1) >= fsbytes) { 2089 if (ffs_lblktosize(fs, lbn) + size > fsbytes) 2090 size = ffs_fragroundup(fs, 2091 fsbytes - ffs_lblktosize(fs, lbn)); 2092 error = bread(vp, lbn, size, 0, &bp); 2093 } else { 2094 int nextsize = fs->fs_bsize; 2095 error = breadn(vp, lbn, 2096 size, &nextlbn, &nextsize, 1, 0, &bp); 2097 } 2098 if (error) 2099 break; 2100 2101 /* 2102 * We should only get non-zero b_resid when an I/O error 2103 * has occurred, which should cause us to break above. 2104 * However, if the short read did not cause an error, 2105 * then we want to ensure that we do not uiomove bad 2106 * or uninitialized data. 2107 */ 2108 size -= bp->b_resid; 2109 if (size < blkoffset + xfersize) { 2110 xfersize = size - blkoffset; 2111 if (xfersize <= 0) 2112 break; 2113 } 2114 error = uiomove((char *)bp->b_data + blkoffset, xfersize, uio); 2115 if (error) 2116 break; 2117 brelse(bp, BC_AGE); 2118 } 2119 if (bp != NULL) 2120 brelse(bp, BC_AGE); 2121 2122 mutex_exit(&si->si_snaplock); 2123 return error; 2124 } 2125 2126 /* 2127 * Lookup a snapshots data block address. 2128 * Simpler than UFS_BALLOC() as we know all metadata is already allocated 2129 * and safe even for the pagedaemon where we cannot bread(). 2130 */ 2131 static int 2132 snapblkaddr(struct vnode *vp, daddr_t lbn, daddr_t *res) 2133 { 2134 struct indir indirs[UFS_NIADDR + 2]; 2135 struct inode *ip = VTOI(vp); 2136 struct fs *fs = ip->i_fs; 2137 struct buf *bp; 2138 int error, num; 2139 2140 KASSERT(lbn >= 0); 2141 2142 if (lbn < UFS_NDADDR) { 2143 *res = db_get(ip, lbn); 2144 return 0; 2145 } 2146 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0) 2147 return error; 2148 if (uvm_lwp_is_pagedaemon(curlwp)) { 2149 mutex_enter(&bufcache_lock); 2150 bp = incore(vp, indirs[num-1].in_lbn); 2151 if (bp && (bp->b_oflags & (BO_DONE | BO_DELWRI))) { 2152 *res = idb_get(ip, bp->b_data, indirs[num-1].in_off); 2153 error = 0; 2154 } else 2155 error = ENOMEM; 2156 mutex_exit(&bufcache_lock); 2157 return error; 2158 } 2159 error = bread(vp, indirs[num-1].in_lbn, fs->fs_bsize, 0, &bp); 2160 if (error == 0) { 2161 *res = idb_get(ip, bp->b_data, indirs[num-1].in_off); 2162 brelse(bp, 0); 2163 } 2164 2165 return error; 2166 } 2167 2168 /* 2169 * Read or write the specified block of the filesystem vp resides on 2170 * from or to the disk bypassing the buffer cache. 2171 */ 2172 static int 2173 rwfsblk(struct vnode *vp, int flags, void *data, daddr_t lbn) 2174 { 2175 int error; 2176 struct inode *ip = VTOI(vp); 2177 struct fs *fs = ip->i_fs; 2178 struct buf *nbp; 2179 2180 nbp = getiobuf(NULL, true); 2181 nbp->b_flags = flags; 2182 nbp->b_bcount = nbp->b_bufsize = fs->fs_bsize; 2183 nbp->b_error = 0; 2184 nbp->b_data = data; 2185 nbp->b_blkno = nbp->b_rawblkno = FFS_FSBTODB(fs, ffs_blkstofrags(fs, lbn)); 2186 nbp->b_proc = NULL; 2187 nbp->b_dev = ip->i_devvp->v_rdev; 2188 SET(nbp->b_cflags, BC_BUSY); /* mark buffer busy */ 2189 2190 bdev_strategy(nbp); 2191 2192 error = biowait(nbp); 2193 2194 putiobuf(nbp); 2195 2196 return error; 2197 } 2198 2199 /* 2200 * Write all dirty buffers to disk and invalidate them. 2201 */ 2202 static int 2203 syncsnap(struct vnode *vp) 2204 { 2205 int error; 2206 buf_t *bp; 2207 struct fs *fs = VTOI(vp)->i_fs; 2208 2209 mutex_enter(&bufcache_lock); 2210 while ((bp = LIST_FIRST(&vp->v_dirtyblkhd))) { 2211 error = bbusy(bp, false, 0, NULL); 2212 if (error == EPASSTHROUGH) 2213 continue; 2214 else if (error != 0) { 2215 mutex_exit(&bufcache_lock); 2216 return error; 2217 } 2218 KASSERT(bp->b_bcount == fs->fs_bsize); 2219 mutex_exit(&bufcache_lock); 2220 error = rwfsblk(vp, B_WRITE, bp->b_data, 2221 ffs_fragstoblks(fs, FFS_DBTOFSB(fs, bp->b_blkno))); 2222 brelse(bp, BC_INVAL | BC_VFLUSH); 2223 if (error) 2224 return error; 2225 mutex_enter(&bufcache_lock); 2226 } 2227 mutex_exit(&bufcache_lock); 2228 2229 return 0; 2230 } 2231 2232 /* 2233 * Write the specified block to a snapshot. 2234 */ 2235 static int 2236 wrsnapblk(struct vnode *vp, void *data, daddr_t lbn) 2237 { 2238 struct inode *ip = VTOI(vp); 2239 struct fs *fs = ip->i_fs; 2240 struct buf *bp; 2241 int error; 2242 2243 error = ffs_balloc(vp, ffs_lblktosize(fs, (off_t)lbn), fs->fs_bsize, 2244 FSCRED, (ip->i_nlink > 0 ? B_SYNC : 0), &bp); 2245 if (error) 2246 return error; 2247 memcpy(bp->b_data, data, fs->fs_bsize); 2248 if (ip->i_nlink > 0) 2249 error = bwrite(bp); 2250 else 2251 bawrite(bp); 2252 2253 return error; 2254 } 2255 2256 /* 2257 * Check if this inode is present on the active snapshot list. 2258 * Must be called with snapinfo locked. 2259 */ 2260 static inline bool 2261 is_active_snapshot(struct snap_info *si, struct inode *ip) 2262 { 2263 struct inode *xp; 2264 2265 KASSERT(mutex_owned(&si->si_lock)); 2266 2267 TAILQ_FOREACH(xp, &si->si_snapshots, i_nextsnap) 2268 if (xp == ip) 2269 return true; 2270 return false; 2271 } 2272 2273 /* 2274 * Get/Put direct block from inode or buffer containing disk addresses. Take 2275 * care for fs type (UFS1/UFS2) and byte swapping. These functions should go 2276 * into a global include. 2277 */ 2278 static inline daddr_t 2279 db_get(struct inode *ip, int loc) 2280 { 2281 if (ip->i_ump->um_fstype == UFS1) 2282 return ufs_rw32(ip->i_ffs1_db[loc], UFS_IPNEEDSWAP(ip)); 2283 else 2284 return ufs_rw64(ip->i_ffs2_db[loc], UFS_IPNEEDSWAP(ip)); 2285 } 2286 2287 static inline void 2288 db_assign(struct inode *ip, int loc, daddr_t val) 2289 { 2290 if (ip->i_ump->um_fstype == UFS1) 2291 ip->i_ffs1_db[loc] = ufs_rw32(val, UFS_IPNEEDSWAP(ip)); 2292 else 2293 ip->i_ffs2_db[loc] = ufs_rw64(val, UFS_IPNEEDSWAP(ip)); 2294 } 2295 2296 __unused static inline daddr_t 2297 ib_get(struct inode *ip, int loc) 2298 { 2299 if (ip->i_ump->um_fstype == UFS1) 2300 return ufs_rw32(ip->i_ffs1_ib[loc], UFS_IPNEEDSWAP(ip)); 2301 else 2302 return ufs_rw64(ip->i_ffs2_ib[loc], UFS_IPNEEDSWAP(ip)); 2303 } 2304 2305 static inline daddr_t 2306 idb_get(struct inode *ip, void *bf, int loc) 2307 { 2308 if (ip->i_ump->um_fstype == UFS1) 2309 return ufs_rw32(((int32_t *)(bf))[loc], UFS_IPNEEDSWAP(ip)); 2310 else 2311 return ufs_rw64(((int64_t *)(bf))[loc], UFS_IPNEEDSWAP(ip)); 2312 } 2313 2314 static inline void 2315 idb_assign(struct inode *ip, void *bf, int loc, daddr_t val) 2316 { 2317 if (ip->i_ump->um_fstype == UFS1) 2318 ((int32_t *)(bf))[loc] = ufs_rw32(val, UFS_IPNEEDSWAP(ip)); 2319 else 2320 ((int64_t *)(bf))[loc] = ufs_rw64(val, UFS_IPNEEDSWAP(ip)); 2321 } 2322