From c0bb168505f499bb5c3d47fa22b926ee24ff883d Mon Sep 17 00:00:00 2001 From: Bill Joy Date: Fri, 3 Oct 1980 18:45:34 -0800 Subject: [PATCH] file system update orderings SCCS-vsn: sys/ufs/ffs/ffs_inode.c 3.5 SCCS-vsn: sys/ufs/ffs/ufs_inode.c 3.5 SCCS-vsn: sys/ufs/lfs/lfs_inode.c 3.5 SCCS-vsn: sys/ufs/ufs/ufs_inode.c 3.5 SCCS-vsn: sys/kern/subr_xxx.c 3.3 SCCS-vsn: sys/kern/vfs_syscalls.c 3.5 SCCS-vsn: sys/ufs/ffs/ffs_vnops.c 3.5 SCCS-vsn: sys/ufs/ffs/ufs_vnops.c 3.5 SCCS-vsn: sys/ufs/lfs/lfs_vnops.c 3.5 SCCS-vsn: sys/ufs/ufs/ufs_vnops.c 3.5 --- usr/src/sys/kern/subr_xxx.c | 30 +++++++++++++++++++---- usr/src/sys/kern/vfs_syscalls.c | 4 +-- usr/src/sys/ufs/ffs/ffs_inode.c | 43 +++++++++++++++++++++++++++++---- usr/src/sys/ufs/ffs/ffs_vnops.c | 4 +-- usr/src/sys/ufs/ffs/ufs_inode.c | 43 +++++++++++++++++++++++++++++---- usr/src/sys/ufs/ffs/ufs_vnops.c | 4 +-- usr/src/sys/ufs/lfs/lfs_inode.c | 43 +++++++++++++++++++++++++++++---- usr/src/sys/ufs/lfs/lfs_vnops.c | 4 +-- usr/src/sys/ufs/ufs/ufs_inode.c | 43 +++++++++++++++++++++++++++++---- usr/src/sys/ufs/ufs/ufs_vnops.c | 4 +-- 10 files changed, 187 insertions(+), 35 deletions(-) diff --git a/usr/src/sys/kern/subr_xxx.c b/usr/src/sys/kern/subr_xxx.c index f5fad4c25e..2cb6dc8caa 100644 --- a/usr/src/sys/kern/subr_xxx.c +++ b/usr/src/sys/kern/subr_xxx.c @@ -1,4 +1,4 @@ -/* subr_xxx.c 3.2 %G% */ +/* subr_xxx.c 3.3 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -45,7 +45,15 @@ daddr_t bn; if(rwflg==B_READ || (bp = alloc(dev))==NULL) return((daddr_t)-1); nb = dbtofsb(bp->b_blkno); - bdwrite(bp); + if ((ip->i_mode&IFMT) == IFDIR) + /* + * Write directory blocks synchronously + * so they never appear with garbage in + * them on the disk. + */ + bwrite(bp); + else + bdwrite(bp); ip->i_un.i_addr[i] = nb; ip->i_flag |= IUPD|ICHG; } @@ -76,14 +84,18 @@ daddr_t bn; } /* - * fetch the address from the inode + * fetch the first indirect block */ nb = ip->i_un.i_addr[NADDR-j]; if(nb == 0) { if(rwflg==B_READ || (bp = alloc(dev))==NULL) return((daddr_t)-1); nb = dbtofsb(bp->b_blkno); - bdwrite(bp); + /* + * Write synchronously so that indirect blocks + * never point at garbage. + */ + bwrite(bp); ip->i_un.i_addr[NADDR-j] = nb; ip->i_flag |= IUPD|ICHG; } @@ -107,7 +119,15 @@ daddr_t bn; return((daddr_t)-1); } nb = dbtofsb(nbp->b_blkno); - bdwrite(nbp); + if (j < 3 || (ip->i_mode&IFMT) == IFDIR) + /* + * Write synchronously so indirect blocks + * never point at garbage and blocks + * in directories never contain garbage. + */ + bwrite(nbp); + else + bdwrite(nbp); bap[i] = nb; bdwrite(bp); } else diff --git a/usr/src/sys/kern/vfs_syscalls.c b/usr/src/sys/kern/vfs_syscalls.c index 9a12bc608e..ee5d28b19a 100644 --- a/usr/src/sys/kern/vfs_syscalls.c +++ b/usr/src/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* vfs_syscalls.c 3.4 %G% */ +/* vfs_syscalls.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -65,7 +65,7 @@ off_t pipeadj; register struct buf *bp; struct stat ds; - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); /* * first copy from inode table */ diff --git a/usr/src/sys/ufs/ffs/ffs_inode.c b/usr/src/sys/ufs/ffs/ffs_inode.c index 03cb6fd884..c894ccbdda 100644 --- a/usr/src/sys/ufs/ffs/ffs_inode.c +++ b/usr/src/sys/ufs/ffs/ffs_inode.c @@ -1,4 +1,4 @@ -/* ffs_inode.c 3.4 %G% */ +/* ffs_inode.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -178,7 +178,7 @@ register struct inode *ip; ip->i_flag |= IUPD|ICHG; ifree(ip->i_dev, ip->i_number); } - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); prele(ip); i = INOHASH(ip->i_dev, ip->i_number); x = ip - inode; @@ -208,10 +208,13 @@ done: * an inode structure. * If any is on, update the inode * with the current time. + * If waitfor is given, then must insure + * i/o order so wait for write to complete. */ -iupdat(ip, ta, tm) +iupdat(ip, ta, tm, waitfor) register struct inode *ip; time_t *ta, *tm; +int waitfor; { register struct buf *bp; struct dinode *dp; @@ -250,7 +253,10 @@ time_t *ta, *tm; if(ip->i_flag&ICHG) dp->di_ctime = time; ip->i_flag &= ~(IUPD|IACC|ICHG); - bdwrite(bp); + if (waitfor) + bwrite(bp); + else + bdwrite(bp); } } @@ -269,12 +275,30 @@ register struct inode *ip; register i; dev_t dev; daddr_t bn; + struct inode itmp; if (ip->i_vfdcnt) panic("itrunc"); i = ip->i_mode & IFMT; if (i!=IFREG && i!=IFDIR) return; + + /* + * Clean inode on disk before freeing blocks + * to insure no duplicates if system crashes. + */ + itmp = *ip; + itmp.i_size = 0; + for (i = 0; i < NADDR; i++) + itmp.i_un.i_addr[i] = 0; + itmp.i_flag |= ICHG|IUPD; + iupdat(&itmp, &time, &time, 1); + ip->i_flag &= ~(IUPD|IACC|ICHG); + + /* + * Now return blocks to free list... if machine + * crashes, they will be harmless MISSING blocks. + */ dev = ip->i_dev; for(i=NADDR-1; i>=0; i--) { bn = ip->i_un.i_addr[i]; @@ -300,7 +324,10 @@ register struct inode *ip; } } ip->i_size = 0; - ip->i_flag |= ICHG|IUPD; + /* + * Inode was written and flags updated above. + * No need to modify flags here. + */ } tloop(dev, bn, f1, f2) @@ -357,6 +384,12 @@ maknode(mode) ip->i_nlink = 1; ip->i_uid = u.u_uid; ip->i_gid = u.u_gid; + + /* + * Make sure inode goes to disk before directory entry. + */ + iupdat(ip, &time, &time, 1); + wdir(ip); return(ip); } diff --git a/usr/src/sys/ufs/ffs/ffs_vnops.c b/usr/src/sys/ufs/ffs/ffs_vnops.c index 8778a5fa28..b26cd2e1f0 100644 --- a/usr/src/sys/ufs/ffs/ffs_vnops.c +++ b/usr/src/sys/ufs/ffs/ffs_vnops.c @@ -1,4 +1,4 @@ -/* ffs_vnops.c 3.4 %G% */ +/* ffs_vnops.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -65,7 +65,7 @@ off_t pipeadj; register struct buf *bp; struct stat ds; - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); /* * first copy from inode table */ diff --git a/usr/src/sys/ufs/ffs/ufs_inode.c b/usr/src/sys/ufs/ffs/ufs_inode.c index 6a36b69010..4065756e9a 100644 --- a/usr/src/sys/ufs/ffs/ufs_inode.c +++ b/usr/src/sys/ufs/ffs/ufs_inode.c @@ -1,4 +1,4 @@ -/* ufs_inode.c 3.4 %G% */ +/* ufs_inode.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -178,7 +178,7 @@ register struct inode *ip; ip->i_flag |= IUPD|ICHG; ifree(ip->i_dev, ip->i_number); } - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); prele(ip); i = INOHASH(ip->i_dev, ip->i_number); x = ip - inode; @@ -208,10 +208,13 @@ done: * an inode structure. * If any is on, update the inode * with the current time. + * If waitfor is given, then must insure + * i/o order so wait for write to complete. */ -iupdat(ip, ta, tm) +iupdat(ip, ta, tm, waitfor) register struct inode *ip; time_t *ta, *tm; +int waitfor; { register struct buf *bp; struct dinode *dp; @@ -250,7 +253,10 @@ time_t *ta, *tm; if(ip->i_flag&ICHG) dp->di_ctime = time; ip->i_flag &= ~(IUPD|IACC|ICHG); - bdwrite(bp); + if (waitfor) + bwrite(bp); + else + bdwrite(bp); } } @@ -269,12 +275,30 @@ register struct inode *ip; register i; dev_t dev; daddr_t bn; + struct inode itmp; if (ip->i_vfdcnt) panic("itrunc"); i = ip->i_mode & IFMT; if (i!=IFREG && i!=IFDIR) return; + + /* + * Clean inode on disk before freeing blocks + * to insure no duplicates if system crashes. + */ + itmp = *ip; + itmp.i_size = 0; + for (i = 0; i < NADDR; i++) + itmp.i_un.i_addr[i] = 0; + itmp.i_flag |= ICHG|IUPD; + iupdat(&itmp, &time, &time, 1); + ip->i_flag &= ~(IUPD|IACC|ICHG); + + /* + * Now return blocks to free list... if machine + * crashes, they will be harmless MISSING blocks. + */ dev = ip->i_dev; for(i=NADDR-1; i>=0; i--) { bn = ip->i_un.i_addr[i]; @@ -300,7 +324,10 @@ register struct inode *ip; } } ip->i_size = 0; - ip->i_flag |= ICHG|IUPD; + /* + * Inode was written and flags updated above. + * No need to modify flags here. + */ } tloop(dev, bn, f1, f2) @@ -357,6 +384,12 @@ maknode(mode) ip->i_nlink = 1; ip->i_uid = u.u_uid; ip->i_gid = u.u_gid; + + /* + * Make sure inode goes to disk before directory entry. + */ + iupdat(ip, &time, &time, 1); + wdir(ip); return(ip); } diff --git a/usr/src/sys/ufs/ffs/ufs_vnops.c b/usr/src/sys/ufs/ffs/ufs_vnops.c index fb00bab450..bcd3b7fc91 100644 --- a/usr/src/sys/ufs/ffs/ufs_vnops.c +++ b/usr/src/sys/ufs/ffs/ufs_vnops.c @@ -1,4 +1,4 @@ -/* ufs_vnops.c 3.4 %G% */ +/* ufs_vnops.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -65,7 +65,7 @@ off_t pipeadj; register struct buf *bp; struct stat ds; - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); /* * first copy from inode table */ diff --git a/usr/src/sys/ufs/lfs/lfs_inode.c b/usr/src/sys/ufs/lfs/lfs_inode.c index 9d47643bce..231e7bb5fd 100644 --- a/usr/src/sys/ufs/lfs/lfs_inode.c +++ b/usr/src/sys/ufs/lfs/lfs_inode.c @@ -1,4 +1,4 @@ -/* lfs_inode.c 3.4 %G% */ +/* lfs_inode.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -178,7 +178,7 @@ register struct inode *ip; ip->i_flag |= IUPD|ICHG; ifree(ip->i_dev, ip->i_number); } - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); prele(ip); i = INOHASH(ip->i_dev, ip->i_number); x = ip - inode; @@ -208,10 +208,13 @@ done: * an inode structure. * If any is on, update the inode * with the current time. + * If waitfor is given, then must insure + * i/o order so wait for write to complete. */ -iupdat(ip, ta, tm) +iupdat(ip, ta, tm, waitfor) register struct inode *ip; time_t *ta, *tm; +int waitfor; { register struct buf *bp; struct dinode *dp; @@ -250,7 +253,10 @@ time_t *ta, *tm; if(ip->i_flag&ICHG) dp->di_ctime = time; ip->i_flag &= ~(IUPD|IACC|ICHG); - bdwrite(bp); + if (waitfor) + bwrite(bp); + else + bdwrite(bp); } } @@ -269,12 +275,30 @@ register struct inode *ip; register i; dev_t dev; daddr_t bn; + struct inode itmp; if (ip->i_vfdcnt) panic("itrunc"); i = ip->i_mode & IFMT; if (i!=IFREG && i!=IFDIR) return; + + /* + * Clean inode on disk before freeing blocks + * to insure no duplicates if system crashes. + */ + itmp = *ip; + itmp.i_size = 0; + for (i = 0; i < NADDR; i++) + itmp.i_un.i_addr[i] = 0; + itmp.i_flag |= ICHG|IUPD; + iupdat(&itmp, &time, &time, 1); + ip->i_flag &= ~(IUPD|IACC|ICHG); + + /* + * Now return blocks to free list... if machine + * crashes, they will be harmless MISSING blocks. + */ dev = ip->i_dev; for(i=NADDR-1; i>=0; i--) { bn = ip->i_un.i_addr[i]; @@ -300,7 +324,10 @@ register struct inode *ip; } } ip->i_size = 0; - ip->i_flag |= ICHG|IUPD; + /* + * Inode was written and flags updated above. + * No need to modify flags here. + */ } tloop(dev, bn, f1, f2) @@ -357,6 +384,12 @@ maknode(mode) ip->i_nlink = 1; ip->i_uid = u.u_uid; ip->i_gid = u.u_gid; + + /* + * Make sure inode goes to disk before directory entry. + */ + iupdat(ip, &time, &time, 1); + wdir(ip); return(ip); } diff --git a/usr/src/sys/ufs/lfs/lfs_vnops.c b/usr/src/sys/ufs/lfs/lfs_vnops.c index 74edcdc2cf..478637a1fc 100644 --- a/usr/src/sys/ufs/lfs/lfs_vnops.c +++ b/usr/src/sys/ufs/lfs/lfs_vnops.c @@ -1,4 +1,4 @@ -/* lfs_vnops.c 3.4 %G% */ +/* lfs_vnops.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -65,7 +65,7 @@ off_t pipeadj; register struct buf *bp; struct stat ds; - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); /* * first copy from inode table */ diff --git a/usr/src/sys/ufs/ufs/ufs_inode.c b/usr/src/sys/ufs/ufs/ufs_inode.c index 6a36b69010..4065756e9a 100644 --- a/usr/src/sys/ufs/ufs/ufs_inode.c +++ b/usr/src/sys/ufs/ufs/ufs_inode.c @@ -1,4 +1,4 @@ -/* ufs_inode.c 3.4 %G% */ +/* ufs_inode.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -178,7 +178,7 @@ register struct inode *ip; ip->i_flag |= IUPD|ICHG; ifree(ip->i_dev, ip->i_number); } - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); prele(ip); i = INOHASH(ip->i_dev, ip->i_number); x = ip - inode; @@ -208,10 +208,13 @@ done: * an inode structure. * If any is on, update the inode * with the current time. + * If waitfor is given, then must insure + * i/o order so wait for write to complete. */ -iupdat(ip, ta, tm) +iupdat(ip, ta, tm, waitfor) register struct inode *ip; time_t *ta, *tm; +int waitfor; { register struct buf *bp; struct dinode *dp; @@ -250,7 +253,10 @@ time_t *ta, *tm; if(ip->i_flag&ICHG) dp->di_ctime = time; ip->i_flag &= ~(IUPD|IACC|ICHG); - bdwrite(bp); + if (waitfor) + bwrite(bp); + else + bdwrite(bp); } } @@ -269,12 +275,30 @@ register struct inode *ip; register i; dev_t dev; daddr_t bn; + struct inode itmp; if (ip->i_vfdcnt) panic("itrunc"); i = ip->i_mode & IFMT; if (i!=IFREG && i!=IFDIR) return; + + /* + * Clean inode on disk before freeing blocks + * to insure no duplicates if system crashes. + */ + itmp = *ip; + itmp.i_size = 0; + for (i = 0; i < NADDR; i++) + itmp.i_un.i_addr[i] = 0; + itmp.i_flag |= ICHG|IUPD; + iupdat(&itmp, &time, &time, 1); + ip->i_flag &= ~(IUPD|IACC|ICHG); + + /* + * Now return blocks to free list... if machine + * crashes, they will be harmless MISSING blocks. + */ dev = ip->i_dev; for(i=NADDR-1; i>=0; i--) { bn = ip->i_un.i_addr[i]; @@ -300,7 +324,10 @@ register struct inode *ip; } } ip->i_size = 0; - ip->i_flag |= ICHG|IUPD; + /* + * Inode was written and flags updated above. + * No need to modify flags here. + */ } tloop(dev, bn, f1, f2) @@ -357,6 +384,12 @@ maknode(mode) ip->i_nlink = 1; ip->i_uid = u.u_uid; ip->i_gid = u.u_gid; + + /* + * Make sure inode goes to disk before directory entry. + */ + iupdat(ip, &time, &time, 1); + wdir(ip); return(ip); } diff --git a/usr/src/sys/ufs/ufs/ufs_vnops.c b/usr/src/sys/ufs/ufs/ufs_vnops.c index fb00bab450..bcd3b7fc91 100644 --- a/usr/src/sys/ufs/ufs/ufs_vnops.c +++ b/usr/src/sys/ufs/ufs/ufs_vnops.c @@ -1,4 +1,4 @@ -/* ufs_vnops.c 3.4 %G% */ +/* ufs_vnops.c 3.5 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -65,7 +65,7 @@ off_t pipeadj; register struct buf *bp; struct stat ds; - IUPDAT(ip, &time, &time); + IUPDAT(ip, &time, &time, 0); /* * first copy from inode table */ -- 2.20.1