Lines Matching +full:ip +full:- +full:block
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
10 * Berkeley, CA 94709-1608 +1-510-843-9542
112 ffs_snapgone(struct inode *ip)
208 struct inode *ip, *xp;
223 fs = ump->um_fs;
229 if ((mp->mnt_flag & MNT_GJOURNAL) != 0) {
231 "using gjournal", fs->fs_fsmnt);
235 flag = mp->mnt_flag;
245 if (fs->fs_snapinum[snaploc] == 0)
262 if (nd.ni_dvp->v_mount != mp)
305 vnode_create_vobject(nd.ni_vp, fs->fs_size, td);
306 vp->v_vflag |= VV_SYSTEM;
307 ip = VTOI(vp);
308 devvp = ITODEVVP(ip);
310 * Calculate the size of the filesystem then allocate the block
311 * immediately following the last block of the filesystem that
315 numblks = howmany(fs->fs_size, fs->fs_frag);
317 fs->fs_bsize, KERNCRED, BA_CLRBUF, &bp);
321 ip->i_size = lblktosize(fs, (off_t)(numblks + 1));
322 vnode_pager_setsize(vp, ip->i_size);
323 DIP_SET(ip, i_size, ip->i_size);
324 UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE);
338 fs->fs_bsize, td->td_ucred, BA_METAONLY, &ibp);
346 error = UFS_BALLOC(vp, fs->fs_sblockloc, fs->fs_sbsize, KERNCRED,
351 blkno = fragstoblks(fs, fs->fs_csaddr);
352 len = howmany(fs->fs_cssize, fs->fs_bsize);
355 fs->fs_bsize, KERNCRED, 0, &nbp);
363 for (cg = 0; cg < fs->fs_ncg; cg++) {
365 fs->fs_bsize, KERNCRED, 0, &nbp);
377 * Change inode to snapshot type file. Before setting its block
382 ip->i_flags |= SF_SNAPSHOT;
383 DIP_SET(ip, i_flags, ip->i_flags);
384 UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
393 len = roundup2(howmany(fs->fs_ncg, NBBY), sizeof(uint64_t));
396 fs->fs_active = space;
398 for (cg = 0; cg < fs->fs_ncg; cg++) {
400 fs->fs_bsize, KERNCRED, 0, &nbp);
423 if (td->td_proc->p_nice > 0) {
426 p = td->td_proc;
428 saved_nice = p->p_nice;
437 if ((error = vfs_write_suspend(vp->v_mount, 0)) != 0) {
442 if (mp->mnt_kern_flag & MNTK_SUSPENDED)
447 if (ip->i_effnlink == 0) {
459 for (cg = 0; cg < fs->fs_ncg; cg++) {
466 fs->fs_bsize, KERNCRED, 0, &nbp);
478 copy_fs = malloc((uint64_t)fs->fs_bsize, M_UFSMNT, M_WAITOK);
479 bcopy(fs, copy_fs, fs->fs_sbsize);
480 copy_fs->fs_si = malloc(sizeof(struct fs_summary_info), M_UFSMNT,
482 if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0)
483 copy_fs->fs_clean = 1;
484 size = fs->fs_bsize < SBLOCKSIZE ? fs->fs_bsize : SBLOCKSIZE;
485 if (fs->fs_sbsize < size)
486 bzero(&((char *)copy_fs)[fs->fs_sbsize],
487 size - fs->fs_sbsize);
488 size = blkroundup(fs, fs->fs_cssize);
489 if (fs->fs_contigsumsize > 0)
490 size += fs->fs_ncg * sizeof(int32_t);
492 copy_fs->fs_csp = space;
493 bcopy(fs->fs_csp, copy_fs->fs_csp, fs->fs_cssize);
494 space = (char *)space + fs->fs_cssize;
495 loc = howmany(fs->fs_cssize, fs->fs_fsize);
496 i = fs->fs_frag - loc % fs->fs_frag;
497 len = (i == fs->fs_frag) ? 0 : i * fs->fs_fsize;
499 if ((error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + loc),
504 bcopy(bp->b_data, space, (uint64_t)len);
506 bp->b_flags |= B_INVAL | B_NOCACHE;
509 if (fs->fs_contigsumsize > 0) {
510 copy_fs->fs_maxcluster = lp = space;
511 for (i = 0; i < fs->fs_ncg; i++)
512 *lp++ = fs->fs_contigsumsize;
526 * - one for each cylinder group map
527 * - one for each block used by superblock summary table
528 * - one for each snapshot inode block
529 * - one for the superblock
530 * - one for the snapshot list
531 * The direct block entries in the snapshot are always
536 * expanded by one because of an update of an inode block for
539 * Because the direct block pointers are always copied, they
543 snaplistsize = fs->fs_ncg + howmany(fs->fs_cssize, fs->fs_bsize) +
546 mp->mnt_kern_flag &= ~MNTK_SUSPENDED;
550 if ((xvp->v_usecount == 0 &&
551 (xvp->v_iflag & (VI_OWEINACT | VI_DOINGINACT)) == 0) ||
552 xvp->v_type == VNON ||
572 if (xvp->v_usecount == 0 &&
573 (xvp->v_iflag & (VI_OWEINACT | VI_DOINGINACT)) == 0) {
584 if (VOP_GETATTR(xvp, &vat, td->td_ucred) == 0 &&
591 if (ffs_checkfreefile(copy_fs, vp, xp->i_number)) {
600 loc = howmany(xp->i_size, fs->fs_bsize) - 1;
602 len = fragroundup(fs, blkoff(fs, xp->i_size));
603 if (len != 0 && len < fs->fs_bsize) {
605 DIP(xp, i_db[loc]), len, xp->i_number,
606 xvp->v_type, NULL, SINGLETON_KEY);
621 error = ffs_freefile(ump, copy_fs, vp, xp->i_number,
622 xp->i_mode, NULL);
633 if (fs->fs_flags & FS_SUJ) {
652 * update the non-integrity-critical time fields and
653 * allocated-block count.
656 if (DIP(ip, i_db[blockno]) != 0)
659 fs->fs_bsize, KERNCRED, BA_CLRBUF, &bp);
675 vp->v_vnlock = &sn->sn_lock;
676 lockmgr(&vp->v_lock, LK_RELEASE, NULL);
677 xp = TAILQ_FIRST(&sn->sn_head);
688 *blkp++ = lblkno(fs, fs->fs_sblockloc);
689 blkno = fragstoblks(fs, fs->fs_csaddr);
690 for (cg = 0; cg < fs->fs_ncg; cg++) {
695 len = howmany(fs->fs_cssize, fs->fs_bsize);
698 for (; cg < fs->fs_ncg; cg++)
700 snapblklist[0] = blkp - snapblklist;
702 if (sn->sn_blklist != NULL)
703 panic("ffs_snapshot: non-empty list");
704 sn->sn_blklist = snapblklist;
705 sn->sn_listsize = blkp - snapblklist;
713 fs->fs_snapinum[snaploc] = ip->i_number;
714 if (ip->i_nextsnap.tqe_prev != 0)
716 (uintmax_t)ip->i_number);
717 TAILQ_INSERT_TAIL(&sn->sn_head, ip, i_nextsnap);
718 devvp->v_vflag |= VV_COPYONWRITE;
723 free(copy_fs->fs_csp, M_UFSMNT);
724 free(copy_fs->fs_si, M_UFSMNT);
733 vfs_write_resume(vp->v_mount, VR_START_WRITE | VR_NO_SUSPCLR);
739 vp->v_mount->mnt_stat.f_mntonname, (long)endtime.tv_sec,
740 endtime.tv_nsec / 1000000, redo, fs->fs_ncg);
749 TAILQ_FOREACH(xp, &sn->sn_head, i_nextsnap) {
750 if (xp == ip)
758 if (error == 0 && xp->i_effnlink == 0) {
762 xp->i_number,
763 xp->i_mode, NULL);
766 fs->fs_snapinum[snaploc] = 0;
775 ip->i_snapblklist = &snapblklist[1];
781 if (I_IS_UFS1(ip))
782 error = expunge_ufs1(vp, ip, copy_fs, mapacct_ufs1,
785 error = expunge_ufs2(vp, ip, copy_fs, mapacct_ufs2,
788 fs->fs_snapinum[snaploc] = 0;
792 if (snaplistsize < ip->i_snapblklist - snapblklist)
794 snaplistsize = ip->i_snapblklist - snapblklist;
796 ip->i_snapblklist = 0;
809 if ((error = VOP_WRITE(vp, &auio, IO_UNIT, td->td_ucred)) != 0) {
810 fs->fs_snapinum[snaploc] = 0;
818 blkno = fragstoblks(fs, fs->fs_csaddr);
819 len = howmany(fs->fs_cssize, fs->fs_bsize);
820 space = copy_fs->fs_csp;
822 error = bread(vp, blkno + loc, fs->fs_bsize, KERNCRED, &nbp);
824 fs->fs_snapinum[snaploc] = 0;
828 bcopy(space, nbp->b_data, fs->fs_bsize);
829 space = (char *)space + fs->fs_bsize;
832 error = bread(vp, lblkno(fs, fs->fs_sblockloc), fs->fs_bsize,
837 loc = blkoff(fs, fs->fs_sblockloc);
838 copy_fs->fs_fmod = 0;
839 bpfs = (struct fs *)&nbp->b_data[loc];
840 bcopy((caddr_t)copy_fs, (caddr_t)bpfs, (uint64_t)fs->fs_sbsize);
842 bpfs->fs_ckhash = ffs_calc_sbhash(bpfs);
850 space = sn->sn_blklist;
851 sn->sn_blklist = snapblklist;
852 sn->sn_listsize = snaplistsize;
857 free(copy_fs->fs_csp, M_UFSMNT);
858 free(copy_fs->fs_si, M_UFSMNT);
865 p = td->td_proc;
867 sched_nice(td->td_proc, saved_nice);
868 PROC_UNLOCK(td->td_proc);
871 if (fs->fs_active != 0) {
872 free(fs->fs_active, M_DEVBUF);
873 fs->fs_active = 0;
877 mp->mnt_flag = (mp->mnt_flag & MNT_QUOTA) | (flag & ~MNT_QUOTA);
923 struct inode *ip;
929 ip = VTOI(vp);
930 fs = ITOFS(ip);
931 if ((error = ffs_getcg(fs, ITODEVVP(ip), cg, 0, &bp, &cgp)) != 0)
933 UFS_LOCK(ITOUMP(ip));
941 fs->fs_cs(fs, cg) = cgp->cg_cs;
942 UFS_UNLOCK(ITOUMP(ip));
943 bcopy(bp->b_data, nbp->b_data, fs->fs_cgsize);
944 if (fs->fs_cgsize < fs->fs_bsize)
945 bzero(&nbp->b_data[fs->fs_cgsize],
946 fs->fs_bsize - fs->fs_cgsize);
947 cgp = (struct cg *)nbp->b_data;
950 nbp->b_flags |= B_VALIDSUSPWRT;
951 numblks = howmany(fs->fs_size, fs->fs_frag);
952 len = howmany(fs->fs_fpg, fs->fs_frag);
953 base = cgbase(fs, cg) / fs->fs_frag;
955 len = numblks - base - 1;
960 DIP_SET(ip, i_db[loc], BLK_NOCOPY);
961 else if (passno == 2 && DIP(ip, i_db[loc])== BLK_NOCOPY)
962 DIP_SET(ip, i_db[loc], 0);
963 else if (passno == 1 && DIP(ip, i_db[loc])== BLK_NOCOPY)
964 panic("ffs_snapshot: lost direct block");
968 fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
972 indiroff = (base + loc - UFS_NDADDR) % NINDIR(fs);
976 ibp->b_flags |= B_VALIDSUSPWRT;
980 fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
986 if (I_IS_UFS1(ip)) {
988 ((ufs1_daddr_t *)(ibp->b_data))[indiroff] =
990 else if (passno == 2 && ((ufs1_daddr_t *)(ibp->b_data))
992 ((ufs1_daddr_t *)(ibp->b_data))[indiroff] = 0;
993 else if (passno == 1 && ((ufs1_daddr_t *)(ibp->b_data))
995 panic("ffs_snapshot: lost indirect block");
999 ((ufs2_daddr_t *)(ibp->b_data))[indiroff] = BLK_NOCOPY;
1001 ((ufs2_daddr_t *)(ibp->b_data)) [indiroff] == BLK_NOCOPY)
1002 ((ufs2_daddr_t *)(ibp->b_data))[indiroff] = 0;
1004 ((ufs2_daddr_t *)(ibp->b_data)) [indiroff] == BLK_NOCOPY)
1005 panic("ffs_snapshot: lost indirect block");
1008 ibp->b_flags |= B_VALIDSUSPWRT;
1013 * BX_CYLGRP b_xflags because the allocation of the block for the
1014 * the cylinder group map will always be a full size block (fs_bsize)
1019 if ((fs->fs_metackhash & CK_CYLGRP) != 0) {
1020 ((struct cg *)nbp->b_data)->cg_ckhash = 0;
1021 ((struct cg *)nbp->b_data)->cg_ckhash =
1022 calculate_crc32c(~0L, nbp->b_data, fs->fs_cgsize);
1052 * Prepare to expunge the inode. If its inode block has not
1055 lbn = fragstoblks(fs, ino_to_fsba(fs, cancelip->i_number));
1058 blkno = VTOI(snapvp)->i_din1->di_db[lbn];
1062 td->td_pflags |= TDP_COWINPROGRESS;
1064 fs->fs_bsize, KERNCRED, BA_METAONLY, &bp);
1065 td->td_pflags &= ~TDP_COWINPROGRESS;
1068 indiroff = (lbn - UFS_NDADDR) % NINDIR(fs);
1069 blkno = ((ufs1_daddr_t *)(bp->b_data))[indiroff];
1073 if ((error = bread(snapvp, lbn, fs->fs_bsize, KERNCRED, &bp)))
1077 fs->fs_bsize, KERNCRED, 0, &bp);
1087 dip = (struct ufs1_dinode *)bp->b_data +
1088 ino_to_fsbo(fs, cancelip->i_number);
1089 if (clearmode || cancelip->i_effnlink == 0)
1090 dip->di_mode = 0;
1091 dip->di_size = 0;
1092 dip->di_blocks = 0;
1093 dip->di_flags &= ~SF_SNAPSHOT;
1094 bzero(dip->di_db, UFS_NDADDR * sizeof(ufs1_daddr_t));
1095 bzero(dip->di_ib, UFS_NIADDR * sizeof(ufs1_daddr_t));
1101 numblks = howmany(cancelip->i_size, fs->fs_bsize);
1102 if ((error = (*acctfunc)(snapvp, &cancelip->i_din1->di_db[0],
1103 &cancelip->i_din1->di_db[UFS_NDADDR], fs, 0, expungetype)))
1105 if ((error = (*acctfunc)(snapvp, &cancelip->i_din1->di_ib[0],
1106 &cancelip->i_din1->di_ib[UFS_NIADDR], fs, -1, expungetype)))
1109 lbn = -UFS_NDADDR;
1110 len = numblks - UFS_NDADDR;
1114 cancelip->i_din1->di_ib[i], lbn, rlbn, len,
1119 lbn -= blksperindir + 1;
1120 len -= blksperindir;
1127 * Descend an indirect block chain for vnode cancelvp accounting for all
1157 if (lbn != indirs[num - 1 - level].in_lbn || num < 2)
1161 * up the block number for any blocks that are not in the cache.
1163 bp = getblk(cancelvp, lbn, fs->fs_bsize, 0, 0, 0);
1164 bp->b_blkno = fsbtodb(fs, blkno);
1165 if ((bp->b_flags & (B_DONE | B_DELWRI)) == 0 &&
1171 * Account for the block pointers in this indirect block.
1176 bap = malloc(fs->fs_bsize, M_DEVBUF, M_WAITOK);
1177 bcopy(bp->b_data, (caddr_t)bap, fs->fs_bsize);
1180 level == 0 ? rlbn : -1, expungetype);
1184 * Account for the block pointers in each of the indirect blocks
1188 for (lbn++, level--, i = 0; i < last; i++) {
1194 lbn -= blksperindir;
1195 remblks -= blksperindir;
1231 struct inode *ip = VTOI(vp);
1243 blkp = &ip->i_din1->di_db[lbn];
1244 UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
1247 fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
1250 blkp = &((ufs1_daddr_t *)(ibp->b_data))
1251 [(lbn - UFS_NDADDR) % NINDIR(fs)];
1255 * find a block marked BLK_NOCOPY, then it is
1264 panic("snapacct_ufs1: bad block");
1285 struct inode *ip;
1289 ip = VTOI(vp);
1290 inum = ip->i_number;
1291 if (lblkno == -1)
1300 *ip->i_snapblklist++ = lblkno;
1303 ffs_blkfree(ITOUMP(ip), fs, vp, blkno, fs->fs_bsize, inum,
1304 vp->v_type, NULL, SINGLETON_KEY);
1334 * Prepare to expunge the inode. If its inode block has not
1337 lbn = fragstoblks(fs, ino_to_fsba(fs, cancelip->i_number));
1340 blkno = VTOI(snapvp)->i_din2->di_db[lbn];
1344 td->td_pflags |= TDP_COWINPROGRESS;
1346 fs->fs_bsize, KERNCRED, BA_METAONLY, &bp);
1347 td->td_pflags &= ~TDP_COWINPROGRESS;
1350 indiroff = (lbn - UFS_NDADDR) % NINDIR(fs);
1351 blkno = ((ufs2_daddr_t *)(bp->b_data))[indiroff];
1355 if ((error = bread(snapvp, lbn, fs->fs_bsize, KERNCRED, &bp)))
1359 fs->fs_bsize, KERNCRED, 0, &bp);
1369 dip = (struct ufs2_dinode *)bp->b_data +
1370 ino_to_fsbo(fs, cancelip->i_number);
1371 dip->di_size = 0;
1372 dip->di_blocks = 0;
1373 dip->di_flags &= ~SF_SNAPSHOT;
1374 bzero(dip->di_db, UFS_NDADDR * sizeof(ufs2_daddr_t));
1375 bzero(dip->di_ib, UFS_NIADDR * sizeof(ufs2_daddr_t));
1376 if (clearmode || cancelip->i_effnlink == 0)
1377 dip->di_mode = 0;
1385 numblks = howmany(cancelip->i_size, fs->fs_bsize);
1386 if ((error = (*acctfunc)(snapvp, &cancelip->i_din2->di_db[0],
1387 &cancelip->i_din2->di_db[UFS_NDADDR], fs, 0, expungetype)))
1389 if ((error = (*acctfunc)(snapvp, &cancelip->i_din2->di_ib[0],
1390 &cancelip->i_din2->di_ib[UFS_NIADDR], fs, -1, expungetype)))
1393 lbn = -UFS_NDADDR;
1394 len = numblks - UFS_NDADDR;
1398 cancelip->i_din2->di_ib[i], lbn, rlbn, len,
1403 lbn -= blksperindir + 1;
1404 len -= blksperindir;
1411 * Descend an indirect block chain for vnode cancelvp accounting for all
1441 if (lbn != indirs[num - 1 - level].in_lbn || num < 2)
1445 * up the block number for any blocks that are not in the cache.
1447 bp = getblk(cancelvp, lbn, fs->fs_bsize, 0, 0, 0);
1448 bp->b_blkno = fsbtodb(fs, blkno);
1449 if ((bp->b_flags & B_CACHE) == 0 &&
1455 * Account for the block pointers in this indirect block.
1460 bap = malloc(fs->fs_bsize, M_DEVBUF, M_WAITOK);
1461 bcopy(bp->b_data, (caddr_t)bap, fs->fs_bsize);
1464 level == 0 ? rlbn : -1, expungetype);
1468 * Account for the block pointers in each of the indirect blocks
1472 for (lbn++, level--, i = 0; i < last; i++) {
1478 lbn -= blksperindir;
1479 remblks -= blksperindir;
1515 struct inode *ip = VTOI(vp);
1527 blkp = &ip->i_din2->di_db[lbn];
1528 UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
1531 fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
1534 blkp = &((ufs2_daddr_t *)(ibp->b_data))
1535 [(lbn - UFS_NDADDR) % NINDIR(fs)];
1539 * find a block marked BLK_NOCOPY, then it is
1548 panic("snapacct_ufs2: bad block");
1569 struct inode *ip;
1573 ip = VTOI(vp);
1574 inum = ip->i_number;
1575 if (lblkno == -1)
1585 *ip->i_snapblklist++ = lblkno;
1588 ffs_blkfree(ITOUMP(ip), fs, vp, blkno, fs->fs_bsize, inum,
1589 vp->v_type, NULL, SINGLETON_KEY);
1599 ffs_snapgone(struct inode *ip)
1611 sn = ITODEVVP(ip)->v_rdev->si_snapdata;
1613 TAILQ_FOREACH(xp, &sn->sn_head, i_nextsnap)
1614 if (xp == ip)
1617 vrele(ITOV(ip));
1621 (uintmax_t)ip->i_number);
1626 ump = ITOUMP(ip);
1627 fs = ump->um_fs;
1630 if (fs->fs_snapinum[snaploc] == ip->i_number)
1634 if (fs->fs_snapinum[snaploc] == 0)
1636 fs->fs_snapinum[snaploc - 1] = fs->fs_snapinum[snaploc];
1638 fs->fs_snapinum[snaploc - 1] = 0;
1649 struct inode *ip;
1657 ip = VTOI(vp);
1658 fs = ITOFS(ip);
1659 devvp = ITODEVVP(ip);
1665 * Clear copy-on-write flag if last snapshot.
1668 if (ip->i_nextsnap.tqe_prev != 0) {
1669 sn = devvp->v_rdev->si_snapdata;
1670 TAILQ_REMOVE(&sn->sn_head, ip, i_nextsnap);
1671 ip->i_nextsnap.tqe_prev = 0;
1677 * Clear all BLK_NOCOPY fields. Pass any block claims to other
1681 dblk = DIP(ip, i_db[blkno]);
1685 DIP_SET(ip, i_db[blkno], 0);
1687 ffs_snapblkfree(fs, ITODEVVP(ip), dblk, fs->fs_bsize,
1688 ip->i_number, vp->v_type, NULL))) {
1689 DIP_SET(ip, i_blocks, DIP(ip, i_blocks) -
1690 btodb(fs->fs_bsize));
1691 DIP_SET(ip, i_db[blkno], 0);
1694 numblks = howmany(ip->i_size, fs->fs_bsize);
1697 fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
1700 if (fs->fs_size - blkno > NINDIR(fs))
1703 last = fs->fs_size - blkno;
1705 if (I_IS_UFS1(ip)) {
1706 dblk = ((ufs1_daddr_t *)(ibp->b_data))[loc];
1710 ((ufs1_daddr_t *)(ibp->b_data))[loc]= 0;
1712 ffs_snapblkfree(fs, ITODEVVP(ip), dblk,
1713 fs->fs_bsize, ip->i_number, vp->v_type,
1715 ip->i_din1->di_blocks -=
1716 btodb(fs->fs_bsize);
1717 ((ufs1_daddr_t *)(ibp->b_data))[loc]= 0;
1721 dblk = ((ufs2_daddr_t *)(ibp->b_data))[loc];
1725 ((ufs2_daddr_t *)(ibp->b_data))[loc] = 0;
1727 ffs_snapblkfree(fs, ITODEVVP(ip), dblk,
1728 fs->fs_bsize, ip->i_number, vp->v_type, NULL))) {
1729 ip->i_din2->di_blocks -= btodb(fs->fs_bsize);
1730 ((ufs2_daddr_t *)(ibp->b_data))[loc] = 0;
1738 ip->i_flags &= ~SF_SNAPSHOT;
1739 DIP_SET(ip, i_flags, ip->i_flags);
1740 UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
1750 * Reenable disk quotas for ex-snapshot file.
1752 if (!getinoquota(ip))
1753 (void) chkdq(ip, DIP(ip, i_blocks), KERNCRED, FORCE);
1758 * Notification that a block is being freed. Return zero if the free
1759 * should be allowed to proceed. Return non-zero if the snapshot file
1760 * wants to claim the block. The block will be claimed if it is an
1765 * blocks. Note that if more than one snapshot file maps the block,
1771 * have a block number equal to their logical block number within the
1772 * snapshot. A copied block can never have this property because they
1786 struct inode *ip;
1796 sn = devvp->v_rdev->si_snapdata;
1806 if (lockmgr(&sn->sn_lock, LK_INTERLOCK | LK_EXCLUSIVE | LK_SLEEPFAIL,
1810 TAILQ_FOREACH(ip, &sn->sn_head, i_nextsnap) {
1811 vp = ITOV(ip);
1815 * Lookup block being written.
1818 blkno = DIP(ip, i_db[lbn]);
1820 td->td_pflags |= TDP_COWINPROGRESS;
1822 fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
1823 td->td_pflags &= ~TDP_COWINPROGRESS;
1826 indiroff = (lbn - UFS_NDADDR) % NINDIR(fs);
1827 if (I_IS_UFS1(ip))
1828 blkno=((ufs1_daddr_t *)(ibp->b_data))[indiroff];
1830 blkno=((ufs2_daddr_t *)(ibp->b_data))[indiroff];
1833 * Check to see if block needs to be copied.
1837 * A block that we map is being freed. If it has not
1843 * No previous snapshot claimed the block,
1848 panic("snapblkfree: inconsistent block type");
1850 DIP_SET(ip, i_db[lbn], BLK_NOCOPY);
1851 UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
1852 } else if (I_IS_UFS1(ip)) {
1853 ((ufs1_daddr_t *)(ibp->b_data))[indiroff] =
1857 ((ufs2_daddr_t *)(ibp->b_data))[indiroff] =
1864 * If the snapshot has already copied the block
1865 * (default), or does not care about the block,
1873 * If this is a full size block, we will just grab it
1877 * claim this block.
1879 if (size == fs->fs_bsize) {
1884 (uintmax_t)ip->i_number,
1893 softdep_inode_append(ip,
1894 curthread->td_ucred, wkhd);
1899 DIP_SET(ip, i_db[lbn], bno);
1900 } else if (I_IS_UFS1(ip)) {
1901 ((ufs1_daddr_t *)(ibp->b_data))[indiroff] = bno;
1904 ((ufs2_daddr_t *)(ibp->b_data))[indiroff] = bno;
1907 DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + btodb(size));
1908 UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE);
1909 lockmgr(vp->v_vnlock, LK_RELEASE, NULL);
1915 * Allocate the block into which to do the copy. Note that this
1919 td->td_pflags |= TDP_COWINPROGRESS;
1921 fs->fs_bsize, KERNCRED, 0, &cbp);
1922 td->td_pflags &= ~TDP_COWINPROGRESS;
1928 "Copyonremove: snapino ", (uintmax_t)ip->i_number,
1930 (intmax_t)cbp->b_blkno);
1933 * If we have already read the old block contents, then
1934 * simply copy them to the new block. Note that we need
1939 * dopersistence sysctl-setable flag to decide on the
1943 bcopy(savedcbp->b_data, cbp->b_data, fs->fs_bsize);
1946 ip->i_effnlink > 0)
1951 * Otherwise, read the old block contents into the buffer.
1954 bzero(cbp->b_data, fs->fs_bsize);
1957 ip->i_effnlink > 0)
1968 * use the dopersistence sysctl-setable flag to decide on
1972 vp = savedcbp->b_vp;
1975 VTOI(vp)->i_effnlink > 0)
1979 * If we have been unable to allocate a block in which to do
1980 * the copy, then return non-zero so that the fragment will
1986 lockmgr(&sn->sn_lock, LK_RELEASE, NULL);
1997 struct vnode *devvp = ump->um_devvp;
1998 struct fs *fs = ump->um_fs;
2003 struct inode *ip;
2015 mp->mnt_stat.f_iosize = fs->fs_bsize;
2023 if (fs->fs_snapinum[snaploc] == 0)
2025 if ((error = ffs_vget(mp, fs->fs_snapinum[snaploc],
2030 ip = VTOI(vp);
2031 if (vp->v_type != VREG) {
2032 reason = "non-file snapshot";
2033 } else if (!IS_SNAPSHOT(ip)) {
2034 reason = "non-snapshot";
2035 } else if (ip->i_size ==
2036 lblktosize(fs, howmany(fs->fs_size, fs->fs_frag))) {
2045 reason, fs->fs_snapinum[snaploc]);
2049 if (fs->fs_snapinum[loc] == 0)
2051 fs->fs_snapinum[loc - 1] = fs->fs_snapinum[loc];
2053 fs->fs_snapinum[loc - 1] = 0;
2054 snaploc--;
2066 vp->v_vnlock = &sn->sn_lock;
2067 lockmgr(&vp->v_lock, LK_RELEASE, NULL);
2072 if (ip->i_nextsnap.tqe_prev != 0)
2074 (uintmax_t)ip->i_number);
2076 TAILQ_INSERT_TAIL(&sn->sn_head, ip, i_nextsnap);
2077 vp->v_vflag |= VV_SYSTEM;
2089 * Allocate the space for the block hints list. We always want to
2098 lblktosize(fs, howmany(fs->fs_size, fs->fs_frag));
2103 if ((error = VOP_READ(vp, &auio, IO_UNIT, td->td_ucred)) != 0) {
2114 auio.uio_offset -= sizeof(snaplistsize);
2115 if ((error = VOP_READ(vp, &auio, IO_UNIT, td->td_ucred)) != 0) {
2123 sn->sn_listsize = snaplistsize;
2124 sn->sn_blklist = (daddr_t *)snapblklist;
2125 devvp->v_vflag |= VV_COPYONWRITE;
2135 struct vnode *devvp = VFSTOUFS(mp)->um_devvp;
2141 sn = devvp->v_rdev->si_snapdata;
2142 while (sn != NULL && (xp = TAILQ_FIRST(&sn->sn_head)) != NULL) {
2144 TAILQ_REMOVE(&sn->sn_head, xp, i_nextsnap);
2145 xp->i_nextsnap.tqe_prev = 0;
2146 lockmgr(&sn->sn_lock, LK_INTERLOCK | LK_EXCLUSIVE,
2150 lockmgr(&vp->v_lock, LK_RELEASE, NULL);
2151 if (xp->i_effnlink > 0) {
2156 sn = devvp->v_rdev->si_snapdata;
2163 * Check the buffer block to be belong to device buffer that shall be
2176 KASSERT(devvp->v_type == VCHR, ("Not a device %p", devvp));
2177 sn = devvp->v_rdev->si_snapdata;
2178 if (sn == NULL || TAILQ_FIRST(&sn->sn_head) == NULL)
2180 fs = ITOFS(TAILQ_FIRST(&sn->sn_head));
2181 lbn = fragstoblks(fs, dbtofsb(fs, bp->b_blkno));
2182 snapblklist = sn->sn_blklist;
2183 upper = sn->sn_listsize - 1;
2192 upper = mid - 1;
2207 if (bo->bo_dirty.bv_cnt <= dirtybufthresh)
2211 vp = bp->b_vp;
2220 if (bo->bo_dirty.bv_cnt > dirtybufthresh + 10 && !bp_bdskip) {
2228 TAILQ_FOREACH(nbp, &bo->bo_dirty.bv_hd, b_bobufs) {
2229 if ((nbp->b_vflags & BV_BKGRDINPROG) ||
2255 if (nbp->b_flags & B_CLUSTEROK) {
2270 * Check for need to copy block that is about to be written,
2271 * copying the block if necessary.
2280 struct inode *ip;
2287 if (devvp != bp->b_vp && IS_SNAPSHOT(VTOI(bp->b_vp)))
2289 if (td->td_pflags & TDP_COWINPROGRESS)
2296 sn = devvp->v_rdev->si_snapdata;
2298 TAILQ_EMPTY(&sn->sn_head)) {
2302 ip = TAILQ_FIRST(&sn->sn_head);
2303 fs = ITOFS(ip);
2304 lbn = fragstoblks(fs, dbtofsb(fs, bp->b_blkno));
2309 snapblklist = sn->sn_blklist;
2310 upper = sn->sn_listsize - 1;
2319 upper = mid - 1;
2326 prev_norunningbuf = td->td_pflags & TDP_NORUNNINGBUF;
2332 saved_runningbufspace = bp->b_runningbufspace;
2338 while (lockmgr(&sn->sn_lock, LK_INTERLOCK | LK_EXCLUSIVE | LK_SLEEPFAIL,
2341 sn = devvp->v_rdev->si_snapdata;
2343 TAILQ_EMPTY(&sn->sn_head)) {
2352 TAILQ_FOREACH(ip, &sn->sn_head, i_nextsnap) {
2353 vp = ITOV(ip);
2362 if (bp->b_vp == vp)
2365 * Check to see if block needs to be copied. We do not have
2371 blkno = DIP(ip, i_db[lbn]);
2373 td->td_pflags |= TDP_COWINPROGRESS | TDP_NORUNNINGBUF;
2375 fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
2376 td->td_pflags &= ~TDP_COWINPROGRESS;
2379 indiroff = (lbn - UFS_NDADDR) % NINDIR(fs);
2380 if (I_IS_UFS1(ip))
2381 blkno=((ufs1_daddr_t *)(ibp->b_data))[indiroff];
2383 blkno=((ufs2_daddr_t *)(ibp->b_data))[indiroff];
2387 if (blkno == BLK_SNAP && bp->b_lblkno >= 0)
2388 panic("ffs_copyonwrite: bad copy block");
2393 * Allocate the block into which to do the copy. Since
2394 * multiple processes may all try to copy the same block,
2400 * with another process to allocate a block.
2402 td->td_pflags |= TDP_COWINPROGRESS | TDP_NORUNNINGBUF;
2404 fs->fs_bsize, KERNCRED, 0, &cbp);
2405 td->td_pflags &= ~TDP_COWINPROGRESS;
2411 (uintmax_t)ip->i_number, (intmax_t)lbn);
2412 if (bp->b_vp == devvp)
2416 (uintmax_t)VTOI(bp->b_vp)->i_number);
2418 (intmax_t)bp->b_lblkno, (intmax_t)cbp->b_blkno);
2422 * If we have already read the old block contents, then
2423 * simply copy them to the new block. Note that we need
2428 * dopersistence sysctl-setable flag to decide on the
2432 bcopy(savedcbp->b_data, cbp->b_data, fs->fs_bsize);
2434 if ((devvp == bp->b_vp || bp->b_vp->v_type == VDIR ||
2435 dopersistence) && ip->i_effnlink > 0)
2442 * Otherwise, read the old block contents into the buffer.
2445 bzero(cbp->b_data, fs->fs_bsize);
2447 if ((devvp == bp->b_vp || bp->b_vp->v_type == VDIR ||
2448 dopersistence) && ip->i_effnlink > 0)
2461 * use the dopersistence sysctl-setable flag to decide on
2465 vp = savedcbp->b_vp;
2467 if ((devvp == bp->b_vp || bp->b_vp->v_type == VDIR ||
2468 dopersistence) && VTOI(vp)->i_effnlink > 0)
2473 lockmgr(vp->v_vnlock, LK_RELEASE, NULL);
2474 td->td_pflags = (td->td_pflags & ~TDP_NORUNNINGBUF) |
2476 if (launched_async_io && (td->td_pflags & TDP_NORUNNINGBUF) == 0)
2496 struct inode *ip;
2498 devvp = VFSTOUFS(mp)->um_devvp;
2499 if ((devvp->v_vflag & VV_COPYONWRITE) == 0)
2503 sn = devvp->v_rdev->si_snapdata;
2508 if (lockmgr(&sn->sn_lock,
2513 TAILQ_FOREACH(ip, &sn->sn_head, i_nextsnap) {
2514 vp = ITOV(ip);
2517 lockmgr(&sn->sn_lock, LK_RELEASE, NULL);
2521 * Read the specified block into the given buffer.
2522 * Much of this boiler-plate comes from bwrite().
2529 struct inode *ip;
2532 ip = VTOI(vp);
2533 fs = ITOFS(ip);
2535 bp->b_iocmd = BIO_READ;
2536 bp->b_iooffset = dbtob(fsbtodb(fs, blkstofrags(fs, lbn)));
2537 bp->b_iodone = bdone;
2538 g_vfs_strategy(&ITODEVVP(ip)->v_bufobj, bp);
2540 return (bp->b_error);
2554 struct inode *ip;
2565 if (vp->v_type == VNON ||
2566 ((VTOI(vp)->i_flag & IN_LAZYACCESS) == 0 &&
2567 ((vp->v_iflag & VI_OWEINACT) == 0 || vp->v_usecount > 0))) {
2581 ip = VTOI(vp);
2582 if ((ip->i_flag & IN_LAZYACCESS) != 0) {
2583 ip->i_flag &= ~IN_LAZYACCESS;
2584 UFS_INODE_SET_FLAG(ip, IN_MODIFIED);
2588 if (error == ERELOOKUP && vp->v_usecount == 0) {
2621 TAILQ_INIT(&sn->sn_head);
2622 lockinit(&sn->sn_lock, PVFS, "snaplk", VLKTIMEOUT,
2648 sn = devvp->v_rdev->si_snapdata;
2650 if (sn == NULL || TAILQ_FIRST(&sn->sn_head) != NULL ||
2651 (devvp->v_vflag & VV_COPYONWRITE) == 0)
2654 devvp->v_rdev->si_snapdata = NULL;
2655 devvp->v_vflag &= ~VV_COPYONWRITE;
2656 lockmgr(&sn->sn_lock, LK_DRAIN|LK_INTERLOCK, VI_MTX(devvp));
2657 snapblklist = sn->sn_blklist;
2658 sn->sn_blklist = NULL;
2659 sn->sn_listsize = 0;
2660 lockmgr(&sn->sn_lock, LK_RELEASE, NULL);
2687 for (i = 0; i <= sn->sn_lock.lk_recurse; i++) {
2688 if (lockmgr(&vp->v_lock, LK_EXCLUSIVE | LK_NOWAIT |
2692 lockmgr(&vp->v_lock, LK_EXCLUSIVE | LK_INTERLOCK,
2697 KASSERT(vp->v_vnlock == &sn->sn_lock,
2699 vp->v_vnlock = &vp->v_lock;
2700 while (sn->sn_lock.lk_recurse > 0)
2701 lockmgr(&sn->sn_lock, LK_RELEASE, NULL);
2702 lockmgr(&sn->sn_lock, LK_RELEASE, NULL);
2720 sn = devvp->v_rdev->si_snapdata;
2724 * filesystem and we use our pre-allocated
2728 error = lockmgr(&nsn->sn_lock, LK_EXCLUSIVE |
2732 sn = devvp->v_rdev->si_snapdata = nsn;
2742 error = lockmgr(&sn->sn_lock, LK_INTERLOCK |