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 --- |