-/* subr_xxx.c 3.2 %G% */
+/* subr_xxx.c 3.3 %G% */
#include "../h/param.h"
#include "../h/systm.h"
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;
}
}
/*
- * 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;
}
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
-/* vfs_syscalls.c 3.4 %G% */
+/* vfs_syscalls.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
register struct buf *bp;
struct stat ds;
- IUPDAT(ip, &time, &time);
+ IUPDAT(ip, &time, &time, 0);
/*
* first copy from inode table
*/
-/* ffs_inode.c 3.4 %G% */
+/* ffs_inode.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
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;
* 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;
if(ip->i_flag&ICHG)
dp->di_ctime = time;
ip->i_flag &= ~(IUPD|IACC|ICHG);
- bdwrite(bp);
+ if (waitfor)
+ bwrite(bp);
+ else
+ bdwrite(bp);
}
}
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];
}
}
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)
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);
}
-/* ffs_vnops.c 3.4 %G% */
+/* ffs_vnops.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
register struct buf *bp;
struct stat ds;
- IUPDAT(ip, &time, &time);
+ IUPDAT(ip, &time, &time, 0);
/*
* first copy from inode table
*/
-/* ufs_inode.c 3.4 %G% */
+/* ufs_inode.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
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;
* 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;
if(ip->i_flag&ICHG)
dp->di_ctime = time;
ip->i_flag &= ~(IUPD|IACC|ICHG);
- bdwrite(bp);
+ if (waitfor)
+ bwrite(bp);
+ else
+ bdwrite(bp);
}
}
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];
}
}
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)
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);
}
-/* ufs_vnops.c 3.4 %G% */
+/* ufs_vnops.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
register struct buf *bp;
struct stat ds;
- IUPDAT(ip, &time, &time);
+ IUPDAT(ip, &time, &time, 0);
/*
* first copy from inode table
*/
-/* lfs_inode.c 3.4 %G% */
+/* lfs_inode.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
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;
* 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;
if(ip->i_flag&ICHG)
dp->di_ctime = time;
ip->i_flag &= ~(IUPD|IACC|ICHG);
- bdwrite(bp);
+ if (waitfor)
+ bwrite(bp);
+ else
+ bdwrite(bp);
}
}
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];
}
}
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)
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);
}
-/* lfs_vnops.c 3.4 %G% */
+/* lfs_vnops.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
register struct buf *bp;
struct stat ds;
- IUPDAT(ip, &time, &time);
+ IUPDAT(ip, &time, &time, 0);
/*
* first copy from inode table
*/
-/* ufs_inode.c 3.4 %G% */
+/* ufs_inode.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
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;
* 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;
if(ip->i_flag&ICHG)
dp->di_ctime = time;
ip->i_flag &= ~(IUPD|IACC|ICHG);
- bdwrite(bp);
+ if (waitfor)
+ bwrite(bp);
+ else
+ bdwrite(bp);
}
}
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];
}
}
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)
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);
}
-/* ufs_vnops.c 3.4 %G% */
+/* ufs_vnops.c 3.5 %G% */
#include "../h/param.h"
#include "../h/systm.h"
register struct buf *bp;
struct stat ds;
- IUPDAT(ip, &time, &time);
+ IUPDAT(ip, &time, &time, 0);
/*
* first copy from inode table
*/