1/*
2 * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
3 *
4 * The soft updates code is derived from the appendix of a University
5 * of Michigan technical report (Gregory R. Ganger and Yale N. Patt,
6 * "Soft Updates: A Solution to the Metadata Update Problem in File
7 * Systems", CSE-TR-254-95, August 1995).
8 *
--- 22 unchanged lines hidden (view full) ---
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * from: @(#)ffs_softdep.c 9.59 (McKusick) 6/21/00
39 * $FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 76354 2001-05-08 07:13:00Z mckusick $
40 */
41
42/*
43 * For now we want the safety net that the DIAGNOSTIC and DEBUG flags provide.
44 */
45#ifndef DIAGNOSTIC
46#define DIAGNOSTIC
47#endif
--- 4 unchanged lines hidden (view full) ---
52#include <sys/param.h>
53#include <sys/kernel.h>
54#include <sys/systm.h>
55#include <sys/bio.h>
56#include <sys/buf.h>
57#include <sys/malloc.h>
58#include <sys/mount.h>
59#include <sys/proc.h>
60#include <sys/syslog.h>
61#include <sys/vnode.h>
62#include <sys/conf.h>
63#include <ufs/ufs/dir.h>
64#include <ufs/ufs/extattr.h>
65#include <ufs/ufs/quota.h>
66#include <ufs/ufs/inode.h>
67#include <ufs/ufs/ufsmount.h>
--- 1652 unchanged lines hidden (view full) ---
1720 struct allocdirect *adp;
1721 struct vnode *vp;
1722 struct buf *bp;
1723 struct fs *fs;
1724 int i, delay, error;
1725
1726 fs = ip->i_fs;
1727 if (length != 0)
1728 panic("softde_setup_freeblocks: non-zero length");
1729 MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks),
1730 M_FREEBLKS, M_SOFTDEP_FLAGS|M_ZERO);
1731 freeblks->fb_list.wk_type = D_FREEBLKS;
1732 freeblks->fb_uid = ip->i_uid;
1733 freeblks->fb_previousinum = ip->i_number;
1734 freeblks->fb_devvp = ip->i_devvp;
1735 freeblks->fb_mnt = ITOV(ip)->v_mount;
1736 freeblks->fb_oldsize = ip->i_size;
--- 5 unchanged lines hidden (view full) ---
1742 }
1743 for (i = 0; i < NIADDR; i++) {
1744 freeblks->fb_iblks[i] = ip->i_ib[i];
1745 ip->i_ib[i] = 0;
1746 }
1747 ip->i_blocks = 0;
1748 ip->i_size = 0;
1749 /*
1750 * Push the zero'ed inode to to its disk buffer so that we are free
1751 * to delete its dependencies below. Once the dependencies are gone
1752 * the buffer can be safely released.
1753 */
1754 if ((error = bread(ip->i_devvp,
1755 fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
1756 (int)fs->fs_bsize, NOCRED, &bp)) != 0)
1757 softdep_error("softdep_setup_freeblocks", error);
--- 223 unchanged lines hidden (view full) ---
1981 MALLOC(freefile, struct freefile *, sizeof(struct freefile),
1982 M_FREEFILE, M_SOFTDEP_FLAGS);
1983 freefile->fx_list.wk_type = D_FREEFILE;
1984 freefile->fx_list.wk_state = 0;
1985 freefile->fx_mode = mode;
1986 freefile->fx_oldinum = ino;
1987 freefile->fx_devvp = ip->i_devvp;
1988 freefile->fx_mnt = ITOV(ip)->v_mount;
1989
1990 /*
1991 * If the inodedep does not exist, then the zero'ed inode has
1992 * been written to disk. If the allocated inode has never been
1993 * written to disk, then the on-disk inode is zero'ed. In either
1994 * case we can free the file immediately.
1995 */
1996 ACQUIRE_LOCK(&lk);
--- 116 unchanged lines hidden (view full) ---
2113 */
2114 for (level = (NIADDR - 1); level >= 0; level--) {
2115 if ((bn = freeblks->fb_iblks[level]) == 0)
2116 continue;
2117 if ((error = indir_trunc(&tip, fsbtodb(fs, bn), level,
2118 baselbns[level], &blocksreleased)) == 0)
2119 allerror = error;
2120 ffs_blkfree(&tip, bn, fs->fs_bsize);
2121 blocksreleased += nblocks;
2122 }
2123 /*
2124 * All direct blocks or frags.
2125 */
2126 for (i = (NDADDR - 1); i >= 0; i--) {
2127 if ((bn = freeblks->fb_dblks[i]) == 0)
2128 continue;
2129 bsize = blksize(fs, &tip, i);
2130 ffs_blkfree(&tip, bn, bsize);
2131 blocksreleased += btodb(bsize);
2132 }
2133 /*
2134 * If we still have not finished background cleanup, then check
2135 * to see if the block count needs to be adjusted.
2136 */
2137 if (freeblks->fb_chkcnt != blocksreleased &&
2138 (fs->fs_flags & FS_UNCLEAN) != 0 && (flags & LK_NOWAIT) == 0 &&
--- 85 unchanged lines hidden (view full) ---
2224 if ((nb = bap[i]) == 0)
2225 continue;
2226 if (level != 0) {
2227 if ((error = indir_trunc(ip, fsbtodb(fs, nb),
2228 level - 1, lbn + (i * lbnadd), countp)) != 0)
2229 allerror = error;
2230 }
2231 ffs_blkfree(ip, nb, fs->fs_bsize);
2232 *countp += nblocks;
2233 }
2234 bp->b_flags |= B_INVAL | B_NOCACHE;
2235 brelse(bp);
2236 return (allerror);
2237}
2238
2239/*
--- 535 unchanged lines hidden (view full) ---
2775 FREE_LOCK(&lk);
2776 panic("softdep_change_linkcnt: bad delta");
2777 }
2778 inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
2779 FREE_LOCK(&lk);
2780}
2781
2782/*
2783 * This workitem decrements the inode's link count.
2784 * If the link count reaches zero, the file is removed.
2785 */
2786static void
2787handle_workitem_remove(dirrem)
2788 struct dirrem *dirrem;
2789{
2790 struct proc *p = CURPROC; /* XXX */
--- 109 unchanged lines hidden (view full) ---
2900 error = inodedep_lookup(fs, freefile->fx_oldinum, 0, &idp);
2901 FREE_LOCK(&lk);
2902 if (error)
2903 panic("handle_workitem_freefile: inodedep survived");
2904#endif
2905 tip.i_devvp = freefile->fx_devvp;
2906 tip.i_dev = freefile->fx_devvp->v_rdev;
2907 tip.i_fs = fs;
2908 if ((error = ffs_freefile(&tip, freefile->fx_oldinum, freefile->fx_mode)) != 0)
2909 softdep_error("handle_workitem_freefile", error);
2910 WORKITEM_FREE(freefile, D_FREEFILE);
2911}
2912
2913/*
2914 * Disk writes.
2915 *
--- 858 unchanged lines hidden (view full) ---
3774 */
3775 ip->i_effnlink = ip->i_nlink;
3776 ACQUIRE_LOCK(&lk);
3777 if (inodedep_lookup(ip->i_fs, ip->i_number, 0, &inodedep) == 0) {
3778 FREE_LOCK(&lk);
3779 return;
3780 }
3781 ip->i_effnlink -= inodedep->id_nlinkdelta;
3782 FREE_LOCK(&lk);
3783}
3784
3785/*
3786 * This routine is called just before the "in-core" inode
3787 * information is to be copied to the in-memory inode block.
3788 * Recall that an inode block contains several inodes. If
3789 * the force flag is set, then the dependencies will be
--- 1169 unchanged lines hidden ---
2 * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
3 *
4 * The soft updates code is derived from the appendix of a University
5 * of Michigan technical report (Gregory R. Ganger and Yale N. Patt,
6 * "Soft Updates: A Solution to the Metadata Update Problem in File
7 * Systems", CSE-TR-254-95, August 1995).
8 *
--- 22 unchanged lines hidden (view full) ---
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * from: @(#)ffs_softdep.c 9.59 (McKusick) 6/21/00
39 * $FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 76354 2001-05-08 07:13:00Z mckusick $
40 */
41
42/*
43 * For now we want the safety net that the DIAGNOSTIC and DEBUG flags provide.
44 */
45#ifndef DIAGNOSTIC
46#define DIAGNOSTIC
47#endif
--- 4 unchanged lines hidden (view full) ---
52#include <sys/param.h>
53#include <sys/kernel.h>
54#include <sys/systm.h>
55#include <sys/bio.h>
56#include <sys/buf.h>
57#include <sys/malloc.h>
58#include <sys/mount.h>
59#include <sys/proc.h>
60#include <sys/syslog.h>
61#include <sys/vnode.h>
62#include <sys/conf.h>
63#include <ufs/ufs/dir.h>
64#include <ufs/ufs/extattr.h>
65#include <ufs/ufs/quota.h>
66#include <ufs/ufs/inode.h>
67#include <ufs/ufs/ufsmount.h>
--- 1652 unchanged lines hidden (view full) ---
1720 struct allocdirect *adp;
1721 struct vnode *vp;
1722 struct buf *bp;
1723 struct fs *fs;
1724 int i, delay, error;
1725
1726 fs = ip->i_fs;
1727 if (length != 0)
1728 panic("softde_setup_freeblocks: non-zero length");
1729 MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks),
1730 M_FREEBLKS, M_SOFTDEP_FLAGS|M_ZERO);
1731 freeblks->fb_list.wk_type = D_FREEBLKS;
1732 freeblks->fb_uid = ip->i_uid;
1733 freeblks->fb_previousinum = ip->i_number;
1734 freeblks->fb_devvp = ip->i_devvp;
1735 freeblks->fb_mnt = ITOV(ip)->v_mount;
1736 freeblks->fb_oldsize = ip->i_size;
--- 5 unchanged lines hidden (view full) ---
1742 }
1743 for (i = 0; i < NIADDR; i++) {
1744 freeblks->fb_iblks[i] = ip->i_ib[i];
1745 ip->i_ib[i] = 0;
1746 }
1747 ip->i_blocks = 0;
1748 ip->i_size = 0;
1749 /*
1750 * Push the zero'ed inode to to its disk buffer so that we are free
1751 * to delete its dependencies below. Once the dependencies are gone
1752 * the buffer can be safely released.
1753 */
1754 if ((error = bread(ip->i_devvp,
1755 fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
1756 (int)fs->fs_bsize, NOCRED, &bp)) != 0)
1757 softdep_error("softdep_setup_freeblocks", error);
--- 223 unchanged lines hidden (view full) ---
1981 MALLOC(freefile, struct freefile *, sizeof(struct freefile),
1982 M_FREEFILE, M_SOFTDEP_FLAGS);
1983 freefile->fx_list.wk_type = D_FREEFILE;
1984 freefile->fx_list.wk_state = 0;
1985 freefile->fx_mode = mode;
1986 freefile->fx_oldinum = ino;
1987 freefile->fx_devvp = ip->i_devvp;
1988 freefile->fx_mnt = ITOV(ip)->v_mount;
1989
1990 /*
1991 * If the inodedep does not exist, then the zero'ed inode has
1992 * been written to disk. If the allocated inode has never been
1993 * written to disk, then the on-disk inode is zero'ed. In either
1994 * case we can free the file immediately.
1995 */
1996 ACQUIRE_LOCK(&lk);
--- 116 unchanged lines hidden (view full) ---
2113 */
2114 for (level = (NIADDR - 1); level >= 0; level--) {
2115 if ((bn = freeblks->fb_iblks[level]) == 0)
2116 continue;
2117 if ((error = indir_trunc(&tip, fsbtodb(fs, bn), level,
2118 baselbns[level], &blocksreleased)) == 0)
2119 allerror = error;
2120 ffs_blkfree(&tip, bn, fs->fs_bsize);
2121 blocksreleased += nblocks;
2122 }
2123 /*
2124 * All direct blocks or frags.
2125 */
2126 for (i = (NDADDR - 1); i >= 0; i--) {
2127 if ((bn = freeblks->fb_dblks[i]) == 0)
2128 continue;
2129 bsize = blksize(fs, &tip, i);
2130 ffs_blkfree(&tip, bn, bsize);
2131 blocksreleased += btodb(bsize);
2132 }
2133 /*
2134 * If we still have not finished background cleanup, then check
2135 * to see if the block count needs to be adjusted.
2136 */
2137 if (freeblks->fb_chkcnt != blocksreleased &&
2138 (fs->fs_flags & FS_UNCLEAN) != 0 && (flags & LK_NOWAIT) == 0 &&
--- 85 unchanged lines hidden (view full) ---
2224 if ((nb = bap[i]) == 0)
2225 continue;
2226 if (level != 0) {
2227 if ((error = indir_trunc(ip, fsbtodb(fs, nb),
2228 level - 1, lbn + (i * lbnadd), countp)) != 0)
2229 allerror = error;
2230 }
2231 ffs_blkfree(ip, nb, fs->fs_bsize);
2232 *countp += nblocks;
2233 }
2234 bp->b_flags |= B_INVAL | B_NOCACHE;
2235 brelse(bp);
2236 return (allerror);
2237}
2238
2239/*
--- 535 unchanged lines hidden (view full) ---
2775 FREE_LOCK(&lk);
2776 panic("softdep_change_linkcnt: bad delta");
2777 }
2778 inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
2779 FREE_LOCK(&lk);
2780}
2781
2782/*
2783 * This workitem decrements the inode's link count.
2784 * If the link count reaches zero, the file is removed.
2785 */
2786static void
2787handle_workitem_remove(dirrem)
2788 struct dirrem *dirrem;
2789{
2790 struct proc *p = CURPROC; /* XXX */
--- 109 unchanged lines hidden (view full) ---
2900 error = inodedep_lookup(fs, freefile->fx_oldinum, 0, &idp);
2901 FREE_LOCK(&lk);
2902 if (error)
2903 panic("handle_workitem_freefile: inodedep survived");
2904#endif
2905 tip.i_devvp = freefile->fx_devvp;
2906 tip.i_dev = freefile->fx_devvp->v_rdev;
2907 tip.i_fs = fs;
2908 if ((error = ffs_freefile(&tip, freefile->fx_oldinum, freefile->fx_mode)) != 0)
2909 softdep_error("handle_workitem_freefile", error);
2910 WORKITEM_FREE(freefile, D_FREEFILE);
2911}
2912
2913/*
2914 * Disk writes.
2915 *
--- 858 unchanged lines hidden (view full) ---
3774 */
3775 ip->i_effnlink = ip->i_nlink;
3776 ACQUIRE_LOCK(&lk);
3777 if (inodedep_lookup(ip->i_fs, ip->i_number, 0, &inodedep) == 0) {
3778 FREE_LOCK(&lk);
3779 return;
3780 }
3781 ip->i_effnlink -= inodedep->id_nlinkdelta;
3782 FREE_LOCK(&lk);
3783}
3784
3785/*
3786 * This routine is called just before the "in-core" inode
3787 * information is to be copied to the in-memory inode block.
3788 * Recall that an inode block contains several inodes. If
3789 * the force flag is set, then the dependencies will be
--- 1169 unchanged lines hidden ---