Deleted Added
full compact
ffs_softdep.c (172836) ffs_softdep.c (173464)
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 *

--- 25 unchanged lines hidden (view full) ---

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 */
40
41#include <sys/cdefs.h>
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 *

--- 25 unchanged lines hidden (view full) ---

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 */
40
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 172836 2007-10-20 23:23:23Z julian $");
42__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_softdep.c 173464 2007-11-08 17:21:51Z obrien $");
43
44/*
43
44/*
45 * For now we want the safety net that the DIAGNOSTIC and DEBUG flags provide.
45 * For now we want the safety net that the INVARIANTS and DEBUG flags provide.
46 */
46 */
47#ifndef DIAGNOSTIC
48#define DIAGNOSTIC
49#endif
50#ifndef DEBUG
51#define DEBUG
52#endif
53
54#include <sys/param.h>
55#include <sys/kernel.h>
56#include <sys/systm.h>
57#include <sys/bio.h>

--- 2719 unchanged lines hidden (view full) ---

2777 (flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp) == 0) {
2778 ip = VTOI(vp);
2779 DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + \
2780 freeblks->fb_chkcnt - blocksreleased);
2781 ip->i_flag |= IN_CHANGE;
2782 vput(vp);
2783 }
2784
47#ifndef DEBUG
48#define DEBUG
49#endif
50
51#include <sys/param.h>
52#include <sys/kernel.h>
53#include <sys/systm.h>
54#include <sys/bio.h>

--- 2719 unchanged lines hidden (view full) ---

2774 (flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp) == 0) {
2775 ip = VTOI(vp);
2776 DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + \
2777 freeblks->fb_chkcnt - blocksreleased);
2778 ip->i_flag |= IN_CHANGE;
2779 vput(vp);
2780 }
2781
2785#ifdef DIAGNOSTIC
2782#ifdef INVARIANTS
2786 if (freeblks->fb_chkcnt != blocksreleased &&
2787 ((fs->fs_flags & FS_UNCLEAN) == 0 || (flags & LK_NOWAIT) != 0))
2788 printf("handle_workitem_freeblocks: block count\n");
2789 if (allerror)
2790 softdep_error("handle_workitem_freeblks", allerror);
2783 if (freeblks->fb_chkcnt != blocksreleased &&
2784 ((fs->fs_flags & FS_UNCLEAN) == 0 || (flags & LK_NOWAIT) != 0))
2785 printf("handle_workitem_freeblocks: block count\n");
2786 if (allerror)
2787 softdep_error("handle_workitem_freeblks", allerror);
2791#endif /* DIAGNOSTIC */
2788#endif /* INVARIANTS */
2792
2793 ACQUIRE_LOCK(&lk);
2794 WORKITEM_FREE(freeblks, D_FREEBLKS);
2795 FREE_LOCK(&lk);
2796}
2797
2798/*
2799 * Release blocks associated with the inode ip and stored in the indirect

--- 1110 unchanged lines hidden (view full) ---

3910 inodedep->id_savedextsize = 0;
3911 if (TAILQ_EMPTY(&inodedep->id_inoupdt))
3912 return;
3913 /*
3914 * Set the dependencies to busy.
3915 */
3916 for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
3917 adp = TAILQ_NEXT(adp, ad_next)) {
2789
2790 ACQUIRE_LOCK(&lk);
2791 WORKITEM_FREE(freeblks, D_FREEBLKS);
2792 FREE_LOCK(&lk);
2793}
2794
2795/*
2796 * Release blocks associated with the inode ip and stored in the indirect

--- 1110 unchanged lines hidden (view full) ---

3907 inodedep->id_savedextsize = 0;
3908 if (TAILQ_EMPTY(&inodedep->id_inoupdt))
3909 return;
3910 /*
3911 * Set the dependencies to busy.
3912 */
3913 for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
3914 adp = TAILQ_NEXT(adp, ad_next)) {
3918#ifdef DIAGNOSTIC
3915#ifdef INVARIANTS
3919 if (deplist != 0 && prevlbn >= adp->ad_lbn)
3920 panic("softdep_write_inodeblock: lbn order");
3921 prevlbn = adp->ad_lbn;
3922 if (adp->ad_lbn < NDADDR &&
3923 dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
3924 panic("%s: direct pointer #%jd mismatch %d != %jd",
3925 "softdep_write_inodeblock",
3926 (intmax_t)adp->ad_lbn,

--- 5 unchanged lines hidden (view full) ---

3932 "softdep_write_inodeblock",
3933 (intmax_t)adp->ad_lbn - NDADDR,
3934 dp->di_ib[adp->ad_lbn - NDADDR],
3935 (intmax_t)adp->ad_newblkno);
3936 deplist |= 1 << adp->ad_lbn;
3937 if ((adp->ad_state & ATTACHED) == 0)
3938 panic("softdep_write_inodeblock: Unknown state 0x%x",
3939 adp->ad_state);
3916 if (deplist != 0 && prevlbn >= adp->ad_lbn)
3917 panic("softdep_write_inodeblock: lbn order");
3918 prevlbn = adp->ad_lbn;
3919 if (adp->ad_lbn < NDADDR &&
3920 dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
3921 panic("%s: direct pointer #%jd mismatch %d != %jd",
3922 "softdep_write_inodeblock",
3923 (intmax_t)adp->ad_lbn,

--- 5 unchanged lines hidden (view full) ---

3929 "softdep_write_inodeblock",
3930 (intmax_t)adp->ad_lbn - NDADDR,
3931 dp->di_ib[adp->ad_lbn - NDADDR],
3932 (intmax_t)adp->ad_newblkno);
3933 deplist |= 1 << adp->ad_lbn;
3934 if ((adp->ad_state & ATTACHED) == 0)
3935 panic("softdep_write_inodeblock: Unknown state 0x%x",
3936 adp->ad_state);
3940#endif /* DIAGNOSTIC */
3937#endif /* INVARIANTS */
3941 adp->ad_state &= ~ATTACHED;
3942 adp->ad_state |= UNDONE;
3943 }
3944 /*
3945 * The on-disk inode cannot claim to be any larger than the last
3946 * fragment that has been written. Otherwise, the on-disk inode
3947 * might have fragments that were not the last block in the file
3948 * which would corrupt the filesystem.
3949 */
3950 for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
3951 lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
3952 if (adp->ad_lbn >= NDADDR)
3953 break;
3954 dp->di_db[adp->ad_lbn] = adp->ad_oldblkno;
3955 /* keep going until hitting a rollback to a frag */
3956 if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
3957 continue;
3958 dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
3959 for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
3938 adp->ad_state &= ~ATTACHED;
3939 adp->ad_state |= UNDONE;
3940 }
3941 /*
3942 * The on-disk inode cannot claim to be any larger than the last
3943 * fragment that has been written. Otherwise, the on-disk inode
3944 * might have fragments that were not the last block in the file
3945 * which would corrupt the filesystem.
3946 */
3947 for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
3948 lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
3949 if (adp->ad_lbn >= NDADDR)
3950 break;
3951 dp->di_db[adp->ad_lbn] = adp->ad_oldblkno;
3952 /* keep going until hitting a rollback to a frag */
3953 if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
3954 continue;
3955 dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
3956 for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
3960#ifdef DIAGNOSTIC
3957#ifdef INVARIANTS
3961 if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
3962 panic("softdep_write_inodeblock: lost dep1");
3958 if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
3959 panic("softdep_write_inodeblock: lost dep1");
3963#endif /* DIAGNOSTIC */
3960#endif /* INVARIANTS */
3964 dp->di_db[i] = 0;
3965 }
3966 for (i = 0; i < NIADDR; i++) {
3961 dp->di_db[i] = 0;
3962 }
3963 for (i = 0; i < NIADDR; i++) {
3967#ifdef DIAGNOSTIC
3964#ifdef INVARIANTS
3968 if (dp->di_ib[i] != 0 &&
3969 (deplist & ((1 << NDADDR) << i)) == 0)
3970 panic("softdep_write_inodeblock: lost dep2");
3965 if (dp->di_ib[i] != 0 &&
3966 (deplist & ((1 << NDADDR) << i)) == 0)
3967 panic("softdep_write_inodeblock: lost dep2");
3971#endif /* DIAGNOSTIC */
3968#endif /* INVARIANTS */
3972 dp->di_ib[i] = 0;
3973 }
3974 return;
3975 }
3976 /*
3977 * If we have zero'ed out the last allocated block of the file,
3978 * roll back the size to the last currently allocated block.
3979 * We know that this last allocated block is a full-sized as

--- 74 unchanged lines hidden (view full) ---

4054 if (TAILQ_EMPTY(&inodedep->id_inoupdt) &&
4055 TAILQ_EMPTY(&inodedep->id_extupdt))
4056 return;
4057 /*
4058 * Set the ext data dependencies to busy.
4059 */
4060 for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_extupdt); adp;
4061 adp = TAILQ_NEXT(adp, ad_next)) {
3969 dp->di_ib[i] = 0;
3970 }
3971 return;
3972 }
3973 /*
3974 * If we have zero'ed out the last allocated block of the file,
3975 * roll back the size to the last currently allocated block.
3976 * We know that this last allocated block is a full-sized as

--- 74 unchanged lines hidden (view full) ---

4051 if (TAILQ_EMPTY(&inodedep->id_inoupdt) &&
4052 TAILQ_EMPTY(&inodedep->id_extupdt))
4053 return;
4054 /*
4055 * Set the ext data dependencies to busy.
4056 */
4057 for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_extupdt); adp;
4058 adp = TAILQ_NEXT(adp, ad_next)) {
4062#ifdef DIAGNOSTIC
4059#ifdef INVARIANTS
4063 if (deplist != 0 && prevlbn >= adp->ad_lbn)
4064 panic("softdep_write_inodeblock: lbn order");
4065 prevlbn = adp->ad_lbn;
4066 if (dp->di_extb[adp->ad_lbn] != adp->ad_newblkno)
4067 panic("%s: direct pointer #%jd mismatch %jd != %jd",
4068 "softdep_write_inodeblock",
4069 (intmax_t)adp->ad_lbn,
4070 (intmax_t)dp->di_extb[adp->ad_lbn],
4071 (intmax_t)adp->ad_newblkno);
4072 deplist |= 1 << adp->ad_lbn;
4073 if ((adp->ad_state & ATTACHED) == 0)
4074 panic("softdep_write_inodeblock: Unknown state 0x%x",
4075 adp->ad_state);
4060 if (deplist != 0 && prevlbn >= adp->ad_lbn)
4061 panic("softdep_write_inodeblock: lbn order");
4062 prevlbn = adp->ad_lbn;
4063 if (dp->di_extb[adp->ad_lbn] != adp->ad_newblkno)
4064 panic("%s: direct pointer #%jd mismatch %jd != %jd",
4065 "softdep_write_inodeblock",
4066 (intmax_t)adp->ad_lbn,
4067 (intmax_t)dp->di_extb[adp->ad_lbn],
4068 (intmax_t)adp->ad_newblkno);
4069 deplist |= 1 << adp->ad_lbn;
4070 if ((adp->ad_state & ATTACHED) == 0)
4071 panic("softdep_write_inodeblock: Unknown state 0x%x",
4072 adp->ad_state);
4076#endif /* DIAGNOSTIC */
4073#endif /* INVARIANTS */
4077 adp->ad_state &= ~ATTACHED;
4078 adp->ad_state |= UNDONE;
4079 }
4080 /*
4081 * The on-disk inode cannot claim to be any larger than the last
4082 * fragment that has been written. Otherwise, the on-disk inode
4083 * might have fragments that were not the last block in the ext
4084 * data which would corrupt the filesystem.
4085 */
4086 for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_extupdt); adp;
4087 lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
4088 dp->di_extb[adp->ad_lbn] = adp->ad_oldblkno;
4089 /* keep going until hitting a rollback to a frag */
4090 if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
4091 continue;
4092 dp->di_extsize = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
4093 for (i = adp->ad_lbn + 1; i < NXADDR; i++) {
4074 adp->ad_state &= ~ATTACHED;
4075 adp->ad_state |= UNDONE;
4076 }
4077 /*
4078 * The on-disk inode cannot claim to be any larger than the last
4079 * fragment that has been written. Otherwise, the on-disk inode
4080 * might have fragments that were not the last block in the ext
4081 * data which would corrupt the filesystem.
4082 */
4083 for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_extupdt); adp;
4084 lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
4085 dp->di_extb[adp->ad_lbn] = adp->ad_oldblkno;
4086 /* keep going until hitting a rollback to a frag */
4087 if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
4088 continue;
4089 dp->di_extsize = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
4090 for (i = adp->ad_lbn + 1; i < NXADDR; i++) {
4094#ifdef DIAGNOSTIC
4091#ifdef INVARIANTS
4095 if (dp->di_extb[i] != 0 && (deplist & (1 << i)) == 0)
4096 panic("softdep_write_inodeblock: lost dep1");
4092 if (dp->di_extb[i] != 0 && (deplist & (1 << i)) == 0)
4093 panic("softdep_write_inodeblock: lost dep1");
4097#endif /* DIAGNOSTIC */
4094#endif /* INVARIANTS */
4098 dp->di_extb[i] = 0;
4099 }
4100 lastadp = NULL;
4101 break;
4102 }
4103 /*
4104 * If we have zero'ed out the last allocated block of the ext
4105 * data, roll back the size to the last currently allocated block.

--- 7 unchanged lines hidden (view full) ---

4113 break;
4114 dp->di_extsize = (i + 1) * fs->fs_bsize;
4115 }
4116 /*
4117 * Set the file data dependencies to busy.
4118 */
4119 for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
4120 adp = TAILQ_NEXT(adp, ad_next)) {
4095 dp->di_extb[i] = 0;
4096 }
4097 lastadp = NULL;
4098 break;
4099 }
4100 /*
4101 * If we have zero'ed out the last allocated block of the ext
4102 * data, roll back the size to the last currently allocated block.

--- 7 unchanged lines hidden (view full) ---

4110 break;
4111 dp->di_extsize = (i + 1) * fs->fs_bsize;
4112 }
4113 /*
4114 * Set the file data dependencies to busy.
4115 */
4116 for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
4117 adp = TAILQ_NEXT(adp, ad_next)) {
4121#ifdef DIAGNOSTIC
4118#ifdef INVARIANTS
4122 if (deplist != 0 && prevlbn >= adp->ad_lbn)
4123 panic("softdep_write_inodeblock: lbn order");
4124 prevlbn = adp->ad_lbn;
4125 if (adp->ad_lbn < NDADDR &&
4126 dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
4127 panic("%s: direct pointer #%jd mismatch %jd != %jd",
4128 "softdep_write_inodeblock",
4129 (intmax_t)adp->ad_lbn,

--- 5 unchanged lines hidden (view full) ---

4135 "softdep_write_inodeblock:",
4136 (intmax_t)adp->ad_lbn - NDADDR,
4137 (intmax_t)dp->di_ib[adp->ad_lbn - NDADDR],
4138 (intmax_t)adp->ad_newblkno);
4139 deplist |= 1 << adp->ad_lbn;
4140 if ((adp->ad_state & ATTACHED) == 0)
4141 panic("softdep_write_inodeblock: Unknown state 0x%x",
4142 adp->ad_state);
4119 if (deplist != 0 && prevlbn >= adp->ad_lbn)
4120 panic("softdep_write_inodeblock: lbn order");
4121 prevlbn = adp->ad_lbn;
4122 if (adp->ad_lbn < NDADDR &&
4123 dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
4124 panic("%s: direct pointer #%jd mismatch %jd != %jd",
4125 "softdep_write_inodeblock",
4126 (intmax_t)adp->ad_lbn,

--- 5 unchanged lines hidden (view full) ---

4132 "softdep_write_inodeblock:",
4133 (intmax_t)adp->ad_lbn - NDADDR,
4134 (intmax_t)dp->di_ib[adp->ad_lbn - NDADDR],
4135 (intmax_t)adp->ad_newblkno);
4136 deplist |= 1 << adp->ad_lbn;
4137 if ((adp->ad_state & ATTACHED) == 0)
4138 panic("softdep_write_inodeblock: Unknown state 0x%x",
4139 adp->ad_state);
4143#endif /* DIAGNOSTIC */
4140#endif /* INVARIANTS */
4144 adp->ad_state &= ~ATTACHED;
4145 adp->ad_state |= UNDONE;
4146 }
4147 /*
4148 * The on-disk inode cannot claim to be any larger than the last
4149 * fragment that has been written. Otherwise, the on-disk inode
4150 * might have fragments that were not the last block in the file
4151 * which would corrupt the filesystem.
4152 */
4153 for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
4154 lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
4155 if (adp->ad_lbn >= NDADDR)
4156 break;
4157 dp->di_db[adp->ad_lbn] = adp->ad_oldblkno;
4158 /* keep going until hitting a rollback to a frag */
4159 if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
4160 continue;
4161 dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
4162 for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
4141 adp->ad_state &= ~ATTACHED;
4142 adp->ad_state |= UNDONE;
4143 }
4144 /*
4145 * The on-disk inode cannot claim to be any larger than the last
4146 * fragment that has been written. Otherwise, the on-disk inode
4147 * might have fragments that were not the last block in the file
4148 * which would corrupt the filesystem.
4149 */
4150 for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
4151 lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) {
4152 if (adp->ad_lbn >= NDADDR)
4153 break;
4154 dp->di_db[adp->ad_lbn] = adp->ad_oldblkno;
4155 /* keep going until hitting a rollback to a frag */
4156 if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize)
4157 continue;
4158 dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
4159 for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
4163#ifdef DIAGNOSTIC
4160#ifdef INVARIANTS
4164 if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
4165 panic("softdep_write_inodeblock: lost dep2");
4161 if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
4162 panic("softdep_write_inodeblock: lost dep2");
4166#endif /* DIAGNOSTIC */
4163#endif /* INVARIANTS */
4167 dp->di_db[i] = 0;
4168 }
4169 for (i = 0; i < NIADDR; i++) {
4164 dp->di_db[i] = 0;
4165 }
4166 for (i = 0; i < NIADDR; i++) {
4170#ifdef DIAGNOSTIC
4167#ifdef INVARIANTS
4171 if (dp->di_ib[i] != 0 &&
4172 (deplist & ((1 << NDADDR) << i)) == 0)
4173 panic("softdep_write_inodeblock: lost dep3");
4168 if (dp->di_ib[i] != 0 &&
4169 (deplist & ((1 << NDADDR) << i)) == 0)
4170 panic("softdep_write_inodeblock: lost dep3");
4174#endif /* DIAGNOSTIC */
4171#endif /* INVARIANTS */
4175 dp->di_ib[i] = 0;
4176 }
4177 return;
4178 }
4179 /*
4180 * If we have zero'ed out the last allocated block of the file,
4181 * roll back the size to the last currently allocated block.
4182 * We know that this last allocated block is a full-sized as

--- 2117 unchanged lines hidden ---
4172 dp->di_ib[i] = 0;
4173 }
4174 return;
4175 }
4176 /*
4177 * If we have zero'ed out the last allocated block of the file,
4178 * roll back the size to the last currently allocated block.
4179 * We know that this last allocated block is a full-sized as

--- 2117 unchanged lines hidden ---