ffs_softdep.c (76354) | ffs_softdep.c (76357) |
---|---|
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 | 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 $ | 39 * $FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 76357 2001-05-08 07:42:20Z 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> | 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/stat.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) | 61#include <sys/syslog.h> 62#include <sys/vnode.h> 63#include <sys/conf.h> 64#include <ufs/ufs/dir.h> 65#include <ufs/ufs/extattr.h> 66#include <ufs/ufs/quota.h> 67#include <ufs/ufs/inode.h> 68#include <ufs/ufs/ufsmount.h> --- 1652 unchanged lines hidden (view full) --- 1721 struct allocdirect *adp; 1722 struct vnode *vp; 1723 struct buf *bp; 1724 struct fs *fs; 1725 int i, delay, error; 1726 1727 fs = ip->i_fs; 1728 if (length != 0) |
1728 panic("softde_setup_freeblocks: non-zero length"); | 1729 panic("softdep_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 /* | 1730 MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks), 1731 M_FREEBLKS, M_SOFTDEP_FLAGS|M_ZERO); 1732 freeblks->fb_list.wk_type = D_FREEBLKS; 1733 freeblks->fb_uid = ip->i_uid; 1734 freeblks->fb_previousinum = ip->i_number; 1735 freeblks->fb_devvp = ip->i_devvp; 1736 freeblks->fb_mnt = ITOV(ip)->v_mount; 1737 freeblks->fb_oldsize = ip->i_size; --- 5 unchanged lines hidden (view full) --- 1743 } 1744 for (i = 0; i < NIADDR; i++) { 1745 freeblks->fb_iblks[i] = ip->i_ib[i]; 1746 ip->i_ib[i] = 0; 1747 } 1748 ip->i_blocks = 0; 1749 ip->i_size = 0; 1750 /* |
1751 * If the file was removed, then the space being freed was 1752 * accounted for then (see softdep_filereleased()). If the 1753 * file is merely being truncated, then we account for it now. 1754 */ 1755 if ((ip->i_flag & IN_SPACECOUNTED) == 0) 1756 fs->fs_pendingblocks += freeblks->fb_chkcnt; 1757 /* |
|
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; | 1758 * Push the zero'ed inode to to its disk buffer so that we are free 1759 * to delete its dependencies below. Once the dependencies are gone 1760 * the buffer can be safely released. 1761 */ 1762 if ((error = bread(ip->i_devvp, 1763 fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 1764 (int)fs->fs_bsize, NOCRED, &bp)) != 0) 1765 softdep_error("softdep_setup_freeblocks", error); --- 223 unchanged lines hidden (view full) --- 1989 MALLOC(freefile, struct freefile *, sizeof(struct freefile), 1990 M_FREEFILE, M_SOFTDEP_FLAGS); 1991 freefile->fx_list.wk_type = D_FREEFILE; 1992 freefile->fx_list.wk_state = 0; 1993 freefile->fx_mode = mode; 1994 freefile->fx_oldinum = ino; 1995 freefile->fx_devvp = ip->i_devvp; 1996 freefile->fx_mnt = ITOV(ip)->v_mount; |
1997 if ((ip->i_flag & IN_SPACECOUNTED) == 0) 1998 ip->i_fs->fs_pendinginodes += 1; |
|
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); | 1999 2000 /* 2001 * If the inodedep does not exist, then the zero'ed inode has 2002 * been written to disk. If the allocated inode has never been 2003 * written to disk, then the on-disk inode is zero'ed. In either 2004 * case we can free the file immediately. 2005 */ 2006 ACQUIRE_LOCK(&lk); --- 116 unchanged lines hidden (view full) --- 2123 */ 2124 for (level = (NIADDR - 1); level >= 0; level--) { 2125 if ((bn = freeblks->fb_iblks[level]) == 0) 2126 continue; 2127 if ((error = indir_trunc(&tip, fsbtodb(fs, bn), level, 2128 baselbns[level], &blocksreleased)) == 0) 2129 allerror = error; 2130 ffs_blkfree(&tip, bn, fs->fs_bsize); |
2131 fs->fs_pendingblocks -= nblocks; |
|
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); | 2132 blocksreleased += nblocks; 2133 } 2134 /* 2135 * All direct blocks or frags. 2136 */ 2137 for (i = (NDADDR - 1); i >= 0; i--) { 2138 if ((bn = freeblks->fb_dblks[i]) == 0) 2139 continue; 2140 bsize = blksize(fs, &tip, i); 2141 ffs_blkfree(&tip, bn, bsize); |
2142 fs->fs_pendingblocks -= btodb(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); | 2143 blocksreleased += btodb(bsize); 2144 } 2145 /* 2146 * If we still have not finished background cleanup, then check 2147 * to see if the block count needs to be adjusted. 2148 */ 2149 if (freeblks->fb_chkcnt != blocksreleased && 2150 (fs->fs_flags & FS_UNCLEAN) != 0 && (flags & LK_NOWAIT) == 0 && --- 85 unchanged lines hidden (view full) --- 2236 if ((nb = bap[i]) == 0) 2237 continue; 2238 if (level != 0) { 2239 if ((error = indir_trunc(ip, fsbtodb(fs, nb), 2240 level - 1, lbn + (i * lbnadd), countp)) != 0) 2241 allerror = error; 2242 } 2243 ffs_blkfree(ip, nb, fs->fs_bsize); |
2244 fs->fs_pendingblocks -= nblocks; |
|
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/* | 2245 *countp += nblocks; 2246 } 2247 bp->b_flags |= B_INVAL | B_NOCACHE; 2248 brelse(bp); 2249 return (allerror); 2250} 2251 2252/* --- 535 unchanged lines hidden (view full) --- 2788 FREE_LOCK(&lk); 2789 panic("softdep_change_linkcnt: bad delta"); 2790 } 2791 inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink; 2792 FREE_LOCK(&lk); 2793} 2794 2795/* |
2796 * Called when the effective link count and the reference count 2797 * on an inode drops to zero. At this point there are no names 2798 * referencing the file in the filesystem and no active file 2799 * references. The space associated with the file will be freed 2800 * as soon as the necessary soft dependencies are cleared. 2801 */ 2802void 2803softdep_releasefile(ip) 2804 struct inode *ip; /* inode with the zero effective link count */ 2805{ 2806 struct inodedep *inodedep; 2807 2808 if (ip->i_effnlink > 0) 2809 panic("softdep_filerelease: file still referenced"); 2810 /* 2811 * We may be called several times as the real reference count 2812 * drops to zero. We only want to account for the space once. 2813 */ 2814 if (ip->i_flag & IN_SPACECOUNTED) 2815 return; 2816 /* 2817 * We have to deactivate a snapshot otherwise copyonwrites may 2818 * add blocks and the cleanup may remove blocks after we have 2819 * tried to account for them. 2820 */ 2821 if ((ip->i_flags & SF_SNAPSHOT) != 0) 2822 ffs_snapremove(ITOV(ip)); 2823 /* 2824 * If we are tracking an nlinkdelta, we have to also remember 2825 * whether we accounted for the freed space yet. 2826 */ 2827 ACQUIRE_LOCK(&lk); 2828 if ((inodedep_lookup(ip->i_fs, ip->i_number, 0, &inodedep))) 2829 inodedep->id_state |= SPACECOUNTED; 2830 FREE_LOCK(&lk); 2831 ip->i_fs->fs_pendingblocks += ip->i_blocks; 2832 ip->i_fs->fs_pendinginodes += 1; 2833 ip->i_flag |= IN_SPACECOUNTED; 2834} 2835 2836/* |
|
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; | 2837 * This workitem decrements the inode's link count. 2838 * If the link count reaches zero, the file is removed. 2839 */ 2840static void 2841handle_workitem_remove(dirrem) 2842 struct dirrem *dirrem; 2843{ 2844 struct proc *p = CURPROC; /* XXX */ --- 109 unchanged lines hidden (view full) --- 2954 error = inodedep_lookup(fs, freefile->fx_oldinum, 0, &idp); 2955 FREE_LOCK(&lk); 2956 if (error) 2957 panic("handle_workitem_freefile: inodedep survived"); 2958#endif 2959 tip.i_devvp = freefile->fx_devvp; 2960 tip.i_dev = freefile->fx_devvp->v_rdev; 2961 tip.i_fs = fs; |
2962 fs->fs_pendinginodes -= 1; |
|
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; | 2963 if ((error = ffs_freefile(&tip, freefile->fx_oldinum, freefile->fx_mode)) != 0) 2964 softdep_error("handle_workitem_freefile", error); 2965 WORKITEM_FREE(freefile, D_FREEFILE); 2966} 2967 2968/* 2969 * Disk writes. 2970 * --- 858 unchanged lines hidden (view full) --- 3829 */ 3830 ip->i_effnlink = ip->i_nlink; 3831 ACQUIRE_LOCK(&lk); 3832 if (inodedep_lookup(ip->i_fs, ip->i_number, 0, &inodedep) == 0) { 3833 FREE_LOCK(&lk); 3834 return; 3835 } 3836 ip->i_effnlink -= inodedep->id_nlinkdelta; |
3837 if (inodedep->id_state & SPACECOUNTED) 3838 ip->i_flag |= IN_SPACECOUNTED; |
|
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 --- | 3839 FREE_LOCK(&lk); 3840} 3841 3842/* 3843 * This routine is called just before the "in-core" inode 3844 * information is to be copied to the in-memory inode block. 3845 * Recall that an inode block contains several inodes. If 3846 * the force flag is set, then the dependencies will be --- 1169 unchanged lines hidden --- |