summaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1997-10-06 20:23:17 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1997-10-06 20:23:17 +0000
commit85674180ac0b414993bec634994ea51b28390306 (patch)
tree5ce384dfed739e368b8605fc6db4ed1f26a43609 /sys/ufs
parent44f83f3e77b70fbce9f014e39cf5c97bae700213 (diff)
back out vfs lite2 till after 2.2
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_alloc.c210
-rw-r--r--sys/ufs/ffs/ffs_balloc.c188
-rw-r--r--sys/ufs/ffs/ffs_extern.h59
-rw-r--r--sys/ufs/ffs/ffs_inode.c63
-rw-r--r--sys/ufs/ffs/ffs_subr.c31
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c298
-rw-r--r--sys/ufs/ffs/ffs_vnops.c96
-rw-r--r--sys/ufs/ffs/fs.h16
-rw-r--r--sys/ufs/mfs/mfs_extern.h6
-rw-r--r--sys/ufs/mfs/mfs_vfsops.c65
-rw-r--r--sys/ufs/mfs/mfs_vnops.c15
-rw-r--r--sys/ufs/mfs/mfsnode.h8
-rw-r--r--sys/ufs/ufs/inode.h28
-rw-r--r--sys/ufs/ufs/ufs_extern.h35
-rw-r--r--sys/ufs/ufs/ufs_ihash.c108
-rw-r--r--sys/ufs/ufs/ufs_inode.c47
-rw-r--r--sys/ufs/ufs/ufs_lookup.c341
-rw-r--r--sys/ufs/ufs/ufs_quota.c63
-rw-r--r--sys/ufs/ufs/ufs_readwrite.c12
-rw-r--r--sys/ufs/ufs/ufs_vfsops.c55
-rw-r--r--sys/ufs/ufs/ufs_vnops.c704
21 files changed, 908 insertions, 1540 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index e4bf9e3d285..27ea5b9671f 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_alloc.c,v 1.8 1997/10/06 15:26:28 csapuntz Exp $ */
+/* $OpenBSD: ffs_alloc.c,v 1.9 1997/10/06 20:21:33 deraadt Exp $ */
/* $NetBSD: ffs_alloc.c,v 1.11 1996/05/11 18:27:09 mycroft Exp $ */
/*
@@ -59,7 +59,7 @@
extern u_long nextgennumber;
static daddr_t ffs_alloccg __P((struct inode *, int, daddr_t, int));
-static daddr_t ffs_alloccgblk __P((struct inode *, struct buf *, daddr_t));
+static daddr_t ffs_alloccgblk __P((struct fs *, struct cg *, daddr_t));
static daddr_t ffs_clusteralloc __P((struct inode *, int, daddr_t, int));
static ino_t ffs_dirpref __P((struct fs *));
static daddr_t ffs_fragextend __P((struct inode *, int, long, int, int));
@@ -70,11 +70,6 @@ static u_long ffs_hashalloc __P((struct inode *, int, long, int,
static daddr_t ffs_nodealloccg __P((struct inode *, int, daddr_t, int));
static daddr_t ffs_mapsearch __P((struct fs *, struct cg *, daddr_t, int));
-#ifdef DIAGNOSTIC
-static int ffs_checkblk __P((struct inode *, daddr_t, long));
-#endif
-int ffs_freefile __P((struct vop_vfree_args *));
-
/*
* Allocate a block in the file system.
*
@@ -277,8 +272,7 @@ ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp)
if (bno > 0) {
bp->b_blkno = fsbtodb(fs, bno);
(void) vnode_pager_uncache(ITOV(ip));
- if (!DOINGSOFTDEP(ITOV(ip)))
- ffs_blkfree(ip, bprev, (long)osize);
+ ffs_blkfree(ip, bprev, (long)osize);
if (nsize < request)
ffs_blkfree(ip, bno + numfrags(fs, nsize),
(long)(request - nsize));
@@ -320,10 +314,15 @@ nospace:
* Note that the error return is not reflected back to the user. Rather
* the previous block allocation will be used.
*/
-
+#ifdef DEBUG
+#include <sys/sysctl.h>
int doasyncfree = 1;
-int doreallocblks = 1;
+struct ctldebug debug14 = { "doasyncfree", &doasyncfree };
int prtrealloc = 0;
+struct ctldebug debug15 = { "prtrealloc", &prtrealloc };
+#else
+#define doasyncfree 1
+#endif
int
ffs_reallocblks(v)
@@ -344,9 +343,6 @@ ffs_reallocblks(v)
int i, len, start_lvl, end_lvl, pref, ssize;
struct timespec ts;
- if (doreallocblks == 0)
- return (ENOSPC);
-
vp = ap->a_vp;
ip = VTOI(vp);
fs = ip->i_fs;
@@ -356,22 +352,10 @@ ffs_reallocblks(v)
len = buflist->bs_nchildren;
start_lbn = buflist->bs_children[0]->b_lblkno;
end_lbn = start_lbn + len - 1;
-
#ifdef DIAGNOSTIC
- for (i = 0; i < len; i++)
- if (!ffs_checkblk(ip,
- dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
- panic("ffs_reallocblks: unallocated block 1");
-
for (i = 1; i < len; i++)
if (buflist->bs_children[i]->b_lblkno != start_lbn + i)
- panic("ffs_reallocblks: non-logical cluster");
-
- blkno = buflist->bs_children[0]->b_blkno;
- ssize = fsbtodb(fs, fs->fs_frag);
- for (i = 1; i < len - 1; i++)
- if (buflist->bs_children[i]->b_blkno != blkno + (i * ssize))
- panic("ffs_reallocblks: non-physical cluster %d", i);
+ panic("ffs_reallocblks: non-cluster");
#endif
/*
* If the latest allocation is in a new cylinder group, assume that
@@ -438,14 +422,9 @@ ffs_reallocblks(v)
#endif
blkno = newblk;
for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->fs_frag) {
- if (i == ssize) {
+ if (i == ssize)
bap = ebap;
- soff = -i;
- }
#ifdef DIAGNOSTIC
- if (!ffs_checkblk(ip,
- dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
- panic("ffs_reallocblks: unallocated block 2");
if (dbtofsb(fs, buflist->bs_children[i]->b_blkno) != *bap)
panic("ffs_reallocblks: alloc mismatch");
#endif
@@ -453,17 +432,6 @@ ffs_reallocblks(v)
if (prtrealloc)
printf(" %d,", *bap);
#endif
- if (DOINGSOFTDEP(vp)) {
- if (sbap == &ip->i_ffs_db[0] && i < ssize)
- softdep_setup_allocdirect(ip, start_lbn + i,
- blkno, *bap, fs->fs_bsize, fs->fs_bsize,
- buflist->bs_children[i]);
- else
- softdep_setup_allocindir_page(ip, start_lbn + i,
- i < ssize ? sbp : ebp, soff + i, blkno,
- *bap, buflist->bs_children[i]);
- }
-
*bap++ = blkno;
}
/*
@@ -505,15 +473,10 @@ ffs_reallocblks(v)
printf("\n\tnew:");
#endif
for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) {
- if (!DOINGSOFTDEP(vp))
- ffs_blkfree(ip,
- dbtofsb(fs, buflist->bs_children[i]->b_blkno),
- fs->fs_bsize);
+ ffs_blkfree(ip, dbtofsb(fs, buflist->bs_children[i]->b_blkno),
+ fs->fs_bsize);
buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
#ifdef DEBUG
- if (!ffs_checkblk(ip,
- dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))
- panic("ffs_reallocblks: unallocated block 3");
if (prtrealloc)
printf(" %d,", blkno);
#endif
@@ -852,9 +815,6 @@ ffs_fragextend(ip, cg, bprev, osize, nsize)
fs->fs_cs(fs, cg).cs_nffree--;
}
fs->fs_fmod = 1;
- if (DOINGSOFTDEP(ITOV(ip)))
- softdep_setup_blkmapdep(bp, fs, bprev);
-
bdwrite(bp);
return (bprev);
}
@@ -875,8 +835,8 @@ ffs_alloccg(ip, cg, bpref, size)
register struct fs *fs;
register struct cg *cgp;
struct buf *bp;
- daddr_t bno, blkno;
- int error, i, frags, allocsiz;
+ register int i;
+ int error, bno, frags, allocsiz;
fs = ip->i_fs;
if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize)
@@ -895,7 +855,7 @@ ffs_alloccg(ip, cg, bpref, size)
}
cgp->cg_time = time.tv_sec;
if (size == fs->fs_bsize) {
- bno = ffs_alloccgblk(ip, bp, bpref);
+ bno = ffs_alloccgblk(fs, cgp, bpref);
bdwrite(bp);
return (bno);
}
@@ -917,7 +877,7 @@ ffs_alloccg(ip, cg, bpref, size)
brelse(bp);
return (NULL);
}
- bno = ffs_alloccgblk(ip, bp, bpref);
+ bno = ffs_alloccgblk(fs, cgp, bpref);
bpref = dtogd(fs, bno);
for (i = frags; i < fs->fs_frag; i++)
setbit(cg_blksfree(cgp), bpref + i);
@@ -944,12 +904,8 @@ ffs_alloccg(ip, cg, bpref, size)
cgp->cg_frsum[allocsiz]--;
if (frags != allocsiz)
cgp->cg_frsum[allocsiz - frags]++;
-
- blkno = cg * fs->fs_fpg + bno;
- if (DOINGSOFTDEP(ITOV(ip)))
- softdep_setup_blkmapdep(bp, fs, blkno);
- bdwrite(bp);
- return ((u_long)blkno);
+ bdwrite(bp);
+ return (cg * fs->fs_fpg + bno);
}
/*
@@ -964,20 +920,16 @@ ffs_alloccg(ip, cg, bpref, size)
* blocks may be fragmented by the routine that allocates them.
*/
static daddr_t
-ffs_alloccgblk(ip, bp, bpref)
- struct inode *ip;
- struct buf *bp;
+ffs_alloccgblk(fs, cgp, bpref)
+ register struct fs *fs;
+ register struct cg *cgp;
daddr_t bpref;
{
- struct fs *fs;
- struct cg *cgp;
daddr_t bno, blkno;
int cylno, pos, delta;
short *cylbp;
register int i;
- fs = ip->i_fs;
- cgp = (struct cg *)bp->b_data;
if (bpref == 0 || dtog(fs, bpref) != cgp->cg_cgx) {
bpref = cgp->cg_rotor;
goto norot;
@@ -1068,10 +1020,7 @@ gotit:
cg_blks(fs, cgp, cylno)[cbtorpos(fs, bno)]--;
cg_blktot(cgp)[cylno]--;
fs->fs_fmod = 1;
- blkno = cgp->cg_cgx * fs->fs_fpg + bno;
- if (DOINGSOFTDEP(ITOV(ip)))
- softdep_setup_blkmapdep(bp, fs, blkno);
- return (blkno);
+ return (cgp->cg_cgx * fs->fs_fpg + bno);
}
/*
@@ -1091,7 +1040,7 @@ ffs_clusteralloc(ip, cg, bpref, len)
register struct fs *fs;
register struct cg *cgp;
struct buf *bp;
- int i, got, run, bno, bit, map;
+ int i, run, bno, bit, map;
u_char *mapp;
int32_t *lp;
@@ -1145,7 +1094,7 @@ ffs_clusteralloc(ip, cg, bpref, len)
mapp = &cg_clustersfree(cgp)[bpref / NBBY];
map = *mapp++;
bit = 1 << (bpref % NBBY);
- for (run = 0, got = bpref; got < cgp->cg_nclusterblks; got++) {
+ for (run = 0, i = bpref; i < cgp->cg_nclusterblks; i++) {
if ((map & bit) == 0) {
run = 0;
} else {
@@ -1153,32 +1102,22 @@ ffs_clusteralloc(ip, cg, bpref, len)
if (run == len)
break;
}
- if ((got & (NBBY - 1)) != (NBBY - 1)) {
+ if ((i & (NBBY - 1)) != (NBBY - 1)) {
bit <<= 1;
} else {
map = *mapp++;
bit = 1;
}
}
- if (got >= cgp->cg_nclusterblks)
+ if (i >= cgp->cg_nclusterblks)
goto fail;
/*
* Allocate the cluster that we have found.
*/
-#ifdef DIAGNOSTIC
- for (i = 1; i <= len; i++)
- if (!ffs_isblock(fs, cg_blksfree(cgp), got - run + i))
- panic("ffs_clusteralloc: map mismatch");
-#endif
- bno = cg * fs->fs_fpg + blkstofrags(fs, got - run + 1);
-#ifdef DIAGNOSTIC
- if (dtog(fs, bno) != cg)
- panic("ffs_clusteralloc: allocated out of group");
-#endif
-
+ bno = cg * fs->fs_fpg + blkstofrags(fs, i - run + 1);
len = blkstofrags(fs, len);
for (i = 0; i < len; i += fs->fs_frag)
- if (ffs_alloccgblk(ip, bp, bno + i) != bno + i)
+ if (ffs_alloccgblk(fs, cgp, bno + i) != bno + i)
panic("ffs_clusteralloc: lost block");
bdwrite(bp);
return (bno);
@@ -1256,9 +1195,6 @@ ffs_nodealloccg(ip, cg, ipref, mode)
panic("ffs_nodealloccg: block not in map");
/* NOTREACHED */
gotit:
- if (DOINGSOFTDEP(ITOV(ip)))
- softdep_setup_inomapdep(bp, ip, cg * fs->fs_ipg + ipref);
-
setbit(cg_inosused(cgp), ipref);
cgp->cg_cs.cs_nifree--;
fs->fs_cstotal.cs_nifree--;
@@ -1293,8 +1229,7 @@ ffs_blkfree(ip, bno, size)
int i, error, cg, blk, frags, bbase;
fs = ip->i_fs;
- if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0 ||
- fragnum(fs, bno) + numfrags(fs, size) > fs->fs_frag) {
+ if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) {
printf("dev = 0x%x, bsize = %d, size = %ld, fs = %s\n",
ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt);
panic("blkfree: bad size");
@@ -1320,7 +1255,7 @@ ffs_blkfree(ip, bno, size)
bno = dtogd(fs, bno);
if (size == fs->fs_bsize) {
blkno = fragstoblks(fs, bno);
- if (!ffs_isfreeblock(fs, cg_blksfree(cgp), blkno)) {
+ if (ffs_isblock(fs, cg_blksfree(cgp), blkno)) {
printf("dev = 0x%x, block = %d, fs = %s\n",
ip->i_dev, bno, fs->fs_fsmnt);
panic("blkfree: freeing free block");
@@ -1383,6 +1318,8 @@ ffs_blkfree(ip, bno, size)
/*
* Free an inode.
+ *
+ * The specified inode is placed back in the free map.
*/
int
ffs_vfree(v)
@@ -1393,28 +1330,6 @@ ffs_vfree(v)
ino_t a_ino;
int a_mode;
} */ *ap = v;
-
-
- if (DOINGSOFTDEP(ap->a_pvp)) {
- softdep_freefile(ap);
- return (0);
- }
-
- return (ffs_freefile(ap));
-}
-
-/*
- * Do the actual free operation.
- * The specified inode is placed back in the free map.
- */
-int
-ffs_freefile(ap)
- struct vop_vfree_args /* {
- struct vnode *a_pvp;
- ino_t a_ino;
- int a_mode;
- } */ *ap;
-{
register struct fs *fs;
register struct cg *cgp;
register struct inode *pip;
@@ -1432,7 +1347,7 @@ ffs_freefile(ap)
(int)fs->fs_cgsize, NOCRED, &bp);
if (error) {
brelse(bp);
- return (error);
+ return (0);
}
cgp = (struct cg *)bp->b_data;
if (!cg_chkmagic(cgp)) {
@@ -1463,60 +1378,6 @@ ffs_freefile(ap)
return (0);
}
-#ifdef DIAGNOSTIC
-/*
- * Verify allocation of a block or fragment. Returns true if block or
- * fragment is allocated, false if it is free.
- */
-int
-ffs_checkblk(ip, bno, size)
- struct inode *ip;
- daddr_t bno;
- long size;
-{
- struct fs *fs;
- struct cg *cgp;
- struct buf *bp;
- int i, error, frags, free;
-
- fs = ip->i_fs;
- if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) {
- printf("bsize = %d, size = %d, fs = %s\n",
- fs->fs_bsize, size, fs->fs_fsmnt);
- panic("checkblk: bad size");
- }
- if ((u_int)bno >= fs->fs_size)
- panic("checkblk: bad block %d", bno);
- error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, dtog(fs, bno))),
- (int)fs->fs_cgsize, NOCRED, &bp);
- if (error) {
- /* XXX -probably should pannic here */
- brelse(bp);
- return (-1);
- }
- cgp = (struct cg *)bp->b_data;
- if (!cg_chkmagic(cgp)) {
- /* XXX -probably should pannic here */
- brelse(bp);
- return (-1);
- }
- bno = dtogd(fs, bno);
- if (size == fs->fs_bsize) {
- free = ffs_isblock(fs, cg_blksfree(cgp), fragstoblks(fs, bno));
- } else {
- frags = numfrags(fs, size);
- for (free = 0, i = 0; i < frags; i++)
- if (isset(cg_blksfree(cgp), bno + i))
- free++;
- if (free != 0 && free != frags)
- panic("checkblk: partially free fragment");
- }
- brelse(bp);
- return (!free);
-}
-#endif /* DIAGNOSTIC */
-
-
/*
* Find a block of the specified size in the specified cylinder group.
*
@@ -1689,4 +1550,3 @@ ffs_fserr(fs, uid, cp)
log(LOG_ERR, "uid %d on %s: %s\n", uid, fs->fs_fsmnt, cp);
}
-
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
index 285ca5f2ca7..46daac066d7 100644
--- a/sys/ufs/ffs/ffs_balloc.c
+++ b/sys/ufs/ffs/ffs_balloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_balloc.c,v 1.4 1997/10/06 15:26:29 csapuntz Exp $ */
+/* $OpenBSD: ffs_balloc.c,v 1.5 1997/10/06 20:21:34 deraadt Exp $ */
/* $NetBSD: ffs_balloc.c,v 1.3 1996/02/09 22:22:21 christos Exp $ */
/*
@@ -41,7 +41,6 @@
#include <sys/buf.h>
#include <sys/proc.h>
#include <sys/file.h>
-#include <sys/mount.h>
#include <sys/vnode.h>
#include <vm/vm.h>
@@ -59,44 +58,27 @@
* the inode and the logical block number in a file.
*/
int
-ffs_balloc(v)
- void *v;
-{
- struct vop_balloc_args /* {
- struct vnode *a_vp;
- off_t a_startpoint;
- int a_size;
- struct ucred *a_cred;
- int a_flags;
- struct buf *a_bpp;
- } */ *ap = v;
-
- struct inode *ip;
- daddr_t lbn;
+ffs_balloc(ip, bn, size, cred, bpp, flags)
+ register struct inode *ip;
+ register daddr_t bn;
int size;
struct ucred *cred;
+ struct buf **bpp;
int flags;
- struct fs *fs;
- daddr_t nb;
+{
+ register struct fs *fs;
+ register daddr_t nb;
struct buf *bp, *nbp;
- struct vnode *vp;
+ struct vnode *vp = ITOV(ip);
struct indir indirs[NIADDR + 2];
- daddr_t newb, *bap, pref;
- int deallocated, osize, nsize, num, i, error;
- daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR+1];
+ daddr_t newb, lbn, *bap, pref;
+ int osize, nsize, num, i, error;
- vp = ap->a_vp;
- ip = VTOI(vp);
- fs = ip->i_fs;
- lbn = lblkno(fs, ap->a_startoffset);
- size = blkoff(fs, ap->a_startoffset) + ap->a_size;
- if (size > fs->fs_bsize)
- panic("ffs_balloc; blk too big");
- *ap->a_bpp = NULL;
- if (lbn < 0)
+ *bpp = NULL;
+ if (bn < 0)
return (EFBIG);
- cred = ap->a_cred;
- flags = ap->a_flags;
+ fs = ip->i_fs;
+ lbn = bn;
/*
* If the next write will extend the file into a new block,
@@ -104,7 +86,7 @@ ffs_balloc(v)
* this fragment has to be extended to be a full block.
*/
nb = lblkno(fs, ip->i_ffs_size);
- if (nb < NDADDR && nb < lbn) {
+ if (nb < NDADDR && nb < bn) {
osize = blksize(fs, ip, nb);
if (osize < fs->fs_bsize && osize > 0) {
error = ffs_realloccg(ip, nb,
@@ -112,11 +94,6 @@ ffs_balloc(v)
osize, (int)fs->fs_bsize, cred, &bp);
if (error)
return (error);
- if (DOINGSOFTDEP(vp))
- softdep_setup_allocdirect(ip, nb,
- dbtofsb(fs, bp->b_blkno), ip->i_ffs_db[nb],
- fs->fs_bsize, osize, bp);
-
ip->i_ffs_size = (nb + 1) * fs->fs_bsize;
vnode_pager_setsize(vp, (u_long)ip->i_ffs_size);
ip->i_ffs_db[nb] = dbtofsb(fs, bp->b_blkno);
@@ -130,15 +107,15 @@ ffs_balloc(v)
/*
* The first NDADDR blocks are direct blocks
*/
- if (lbn < NDADDR) {
- nb = ip->i_ffs_db[lbn];
- if (nb != 0 && ip->i_ffs_size >= (lbn + 1) * fs->fs_bsize) {
- error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
+ if (bn < NDADDR) {
+ nb = ip->i_ffs_db[bn];
+ if (nb != 0 && ip->i_ffs_size >= (bn + 1) * fs->fs_bsize) {
+ error = bread(vp, bn, fs->fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
- *ap->a_bpp = bp;
+ *bpp = bp;
return (0);
}
if (nb != 0) {
@@ -148,52 +125,43 @@ ffs_balloc(v)
osize = fragroundup(fs, blkoff(fs, ip->i_ffs_size));
nsize = fragroundup(fs, size);
if (nsize <= osize) {
- error = bread(vp, lbn, osize, NOCRED, &bp);
+ error = bread(vp, bn, osize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
} else {
- error = ffs_realloccg(ip, lbn,
- ffs_blkpref(ip, lbn, (int)lbn,
- &ip->i_ffs_db[0]),
+ error = ffs_realloccg(ip, bn,
+ ffs_blkpref(ip, bn, (int)bn, &ip->i_ffs_db[0]),
osize, nsize, cred, &bp);
if (error)
return (error);
- if (DOINGSOFTDEP(vp))
- softdep_setup_allocdirect(ip, lbn,
- dbtofsb(fs, bp->b_blkno), nb,
- nsize, osize, bp);
}
} else {
- if (ip->i_ffs_size < (lbn + 1) * fs->fs_bsize)
+ if (ip->i_ffs_size < (bn + 1) * fs->fs_bsize)
nsize = fragroundup(fs, size);
else
nsize = fs->fs_bsize;
- error = ffs_alloc(ip, lbn,
- ffs_blkpref(ip, lbn, (int)lbn, &ip->i_ffs_db[0]),
+ error = ffs_alloc(ip, bn,
+ ffs_blkpref(ip, bn, (int)bn, &ip->i_ffs_db[0]),
nsize, cred, &newb);
if (error)
return (error);
- bp = getblk(vp, lbn, nsize, 0, 0);
+ bp = getblk(vp, bn, nsize, 0, 0);
bp->b_blkno = fsbtodb(fs, newb);
if (flags & B_CLRBUF)
clrbuf(bp);
- if (DOINGSOFTDEP(vp))
- softdep_setup_allocdirect(ip, lbn, newb, 0,
- nsize, 0, bp);
-
}
- ip->i_ffs_db[lbn] = dbtofsb(fs, bp->b_blkno);
+ ip->i_ffs_db[bn] = dbtofsb(fs, bp->b_blkno);
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- *ap->a_bpp = bp;
+ *bpp = bp;
return (0);
}
/*
* Determine the number of levels of indirection.
*/
pref = 0;
- if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
+ if ((error = ufs_getlbns(vp, bn, indirs, &num)) != 0)
return(error);
#ifdef DIAGNOSTIC
if (num < 1)
@@ -204,9 +172,6 @@ ffs_balloc(v)
*/
--num;
nb = ip->i_ffs_ib[indirs[0].in_off];
-
- allocib = NULL;
- allocblk = allociblk;
if (nb == 0) {
pref = ffs_blkpref(ip, lbn, 0, (daddr_t *)0);
error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
@@ -214,26 +179,18 @@ ffs_balloc(v)
if (error)
return (error);
nb = newb;
-
- *allocblk++ = nb;
bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0);
- bp->b_blkno = fsbtodb(fs, nb);
+ bp->b_blkno = fsbtodb(fs, newb);
clrbuf(bp);
-
- if (DOINGSOFTDEP(vp)) {
- softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off,
- newb, 0, fs->fs_bsize, 0, bp);
- bdwrite(bp);
- } else {
- /*
- * Write synchronously so that indirect blocks
- * never point at garbage.
- */
- if ((error = bwrite(bp)) != 0)
- goto fail;
- }
- allocib = &ip->i_ffs_ib[indirs[0].in_off];
- *allocib = nb;
+ /*
+ * Write synchronously so that indirect blocks
+ * never point at garbage.
+ */
+ if ((error = bwrite(bp)) != 0) {
+ ffs_blkfree(ip, nb, fs->fs_bsize);
+ return (error);
+ }
+ ip->i_ffs_ib[indirs[0].in_off] = newb;
ip->i_flag |= IN_CHANGE | IN_UPDATE;
}
/*
@@ -244,7 +201,7 @@ ffs_balloc(v)
indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
- goto fail;
+ return (error);
}
bap = (daddr_t *)bp->b_data;
nb = bap[indirs[i].in_off];
@@ -261,27 +218,20 @@ ffs_balloc(v)
&newb);
if (error) {
brelse(bp);
- goto fail;
+ return (error);
}
nb = newb;
- *allocblk++ = nb;
nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0);
nbp->b_blkno = fsbtodb(fs, nb);
clrbuf(nbp);
-
- if (DOINGSOFTDEP(vp)) {
- softdep_setup_allocindir_meta(nbp, ip, bp,
- indirs[i - 1].in_off, nb);
- bdwrite(nbp);
- } else {
- /*
- * Write synchronously so that indirect blocks
- * never point at garbage.
- */
- if ((error = bwrite(nbp)) != 0) {
- brelse(bp);
- goto fail;
- }
+ /*
+ * Write synchronously so that indirect blocks
+ * never point at garbage.
+ */
+ if ((error = bwrite(nbp)) != 0) {
+ ffs_blkfree(ip, nb, fs->fs_bsize);
+ brelse(bp);
+ return (error);
}
bap[indirs[i - 1].in_off] = nb;
/*
@@ -303,17 +253,13 @@ ffs_balloc(v)
&newb);
if (error) {
brelse(bp);
- goto fail;
+ return (error);
}
nb = newb;
- *allocblk++ = nb;
nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
nbp->b_blkno = fsbtodb(fs, nb);
if (flags & B_CLRBUF)
clrbuf(nbp);
- if (DOINGSOFTDEP(vp))
- softdep_setup_allocindir_page(ip, lbn, bp,
- indirs[i].in_off, nb, 0, nbp);
bap[indirs[i].in_off] = nb;
/*
* If required, write synchronously, otherwise use
@@ -324,7 +270,7 @@ ffs_balloc(v)
} else {
bdwrite(bp);
}
- *ap->a_bpp = nbp;
+ *bpp = nbp;
return (0);
}
brelse(bp);
@@ -332,36 +278,12 @@ ffs_balloc(v)
error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
if (error) {
brelse(nbp);
- goto fail;
+ return (error);
}
} else {
nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
nbp->b_blkno = fsbtodb(fs, nb);
}
- *ap->a_bpp = nbp;
+ *bpp = nbp;
return (0);
-
-fail:
- /*
- * If we have failed part way through block allocation, we
- * have to deallocate any indirect blocks that we have allocated.
- */
- for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {
- ffs_blkfree(ip, *blkp, fs->fs_bsize);
- deallocated += fs->fs_bsize;
- }
- if (allocib != NULL)
- *allocib = 0;
- if (deallocated) {
-#ifdef QUOTA
- /*
- * Restore user's disk quota because allocation failed.
- */
- (void) chkdq(ip, (long)-btodb(deallocated), cred, FORCE);
-#endif
- ip->i_ffs_blocks -= btodb(deallocated);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- }
- return (error);
-
}
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index 3fe5a46bfa8..08480c57903 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_extern.h,v 1.3 1997/10/06 15:26:29 csapuntz Exp $ */
+/* $OpenBSD: ffs_extern.h,v 1.4 1997/10/06 20:21:35 deraadt Exp $ */
/* $NetBSD: ffs_extern.h,v 1.4 1996/02/09 22:22:22 christos Exp $ */
/*-
@@ -36,21 +36,6 @@
* @(#)ffs_extern.h 8.3 (Berkeley) 4/16/94
*/
-#define FFS_CLUSTERREAD 1 /* cluster reading enabled */
-#define FFS_CLUSTERWRITE 2 /* cluster writing enabled */
-#define FFS_REALLOCBLKS 3 /* block reallocation enabled */
-#define FFS_ASYNCFREE 4 /* asynchronous block freeing enabled */
-#define FFS_MAXID 5 /* number of valid ffs ids */
-
-#define FFS_NAMES { \
- { 0, 0 }, \
- { "doclusterread", CTLTYPE_INT }, \
- { "doclusterwrite", CTLTYPE_INT }, \
- { "doreallocblks", CTLTYPE_INT }, \
- { "doasyncfree", CTLTYPE_INT }, \
-}
-
-
struct buf;
struct fid;
struct fs;
@@ -62,7 +47,6 @@ struct statfs;
struct timeval;
struct ucred;
struct ufsmount;
-struct vfsconf;
struct uio;
struct vnode;
struct mbuf;
@@ -83,10 +67,11 @@ int ffs_vfree __P((void *));
void ffs_clusteracct __P((struct fs *, struct cg *, daddr_t, int));
/* ffs_balloc.c */
-int ffs_balloc __P((void *));
+int ffs_balloc __P((struct inode *, daddr_t, int, struct ucred *,
+ struct buf **, int));
/* ffs_inode.c */
-int ffs_init __P((struct vfsconf *));
+void ffs_init __P((void));
int ffs_update __P((void *));
int ffs_truncate __P((void *));
@@ -96,8 +81,6 @@ void ffs_fragacct __P((struct fs *, int, int32_t[], int));
#ifdef DIAGNOSTIC
void ffs_checkoverlap __P((struct buf *, struct inode *));
#endif
-int ffs_freefile __P((struct vop_vfree_args *));
-int ffs_isfreeblock __P((struct fs *, unsigned char *, daddr_t));
int ffs_isblock __P((struct fs *, unsigned char *, daddr_t));
void ffs_clrblock __P((struct fs *, u_char *, daddr_t));
void ffs_setblock __P((struct fs *, unsigned char *, daddr_t));
@@ -117,8 +100,6 @@ int ffs_vget __P((struct mount *, ino_t, struct vnode **));
int ffs_fhtovp __P((struct mount *, struct fid *, struct mbuf *,
struct vnode **, int *, struct ucred **));
int ffs_vptofh __P((struct vnode *, struct fid *));
-int ffs_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
- struct proc *));
int ffs_sbupdate __P((struct ufsmount *, int));
int ffs_cgupdate __P((struct ufsmount *, int));
@@ -127,38 +108,6 @@ int ffs_read __P((void *));
int ffs_write __P((void *));
int ffs_fsync __P((void *));
int ffs_reclaim __P((void *));
-
-
-/*
- * Soft dependency function prototypes.
- */
-
-struct vop_vfree_args;
-struct vop_fsync_args;
-
-void softdep_initialize __P((void));
-int softdep_process_worklist __P((struct mount *));
-int softdep_mount __P((struct vnode *, struct mount *, struct fs *,
- struct ucred *));
-int softdep_flushfiles __P((struct mount *, int, struct proc *));
-void softdep_update_inodeblock __P((struct inode *, struct buf *, int));
-void softdep_load_inodeblock __P((struct inode *));
-int softdep_fsync __P((struct vnode *));
-void softdep_freefile __P((struct vop_vfree_args *));
-void softdep_setup_freeblocks __P((struct inode *, off_t));
-void softdep_deallocate_dependencies __P((struct buf *));
-void softdep_setup_inomapdep __P((struct buf *, struct inode *, ino_t));
-void softdep_setup_blkmapdep __P((struct buf *, struct fs *, daddr_t));
-void softdep_setup_allocdirect __P((struct inode *, ufs_lbn_t, daddr_t,
- daddr_t, long, long, struct buf *));
-void softdep_setup_allocindir_meta __P((struct buf *, struct inode *,
- struct buf *, int, daddr_t));
-void softdep_setup_allocindir_page __P((struct inode *, ufs_lbn_t,
- struct buf *, int, daddr_t, daddr_t, struct buf *));
-void softdep_disk_io_initiation __P((struct buf *));
-void softdep_disk_write_complete __P((struct buf *));
-int softdep_sync_metadata __P((struct vop_fsync_args *));
-
__END_DECLS
extern int (**ffs_vnodeop_p) __P((void *));
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index ba1eb996cb9..7324d6442dd 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_inode.c,v 1.7 1997/10/06 15:26:30 csapuntz Exp $ */
+/* $OpenBSD: ffs_inode.c,v 1.8 1997/10/06 20:21:36 deraadt Exp $ */
/* $NetBSD: ffs_inode.c,v 1.10 1996/05/11 18:27:19 mycroft Exp $ */
/*
@@ -61,12 +61,10 @@
static int ffs_indirtrunc __P((struct inode *, daddr_t, daddr_t, daddr_t, int,
long *));
-int
-ffs_init(vfsp)
- struct vfsconf *vfsp;
+void
+ffs_init()
{
- softdep_initialize();
- return (ufs_init(vfsp));
+ ufs_init();
}
/*
@@ -103,8 +101,7 @@ ffs_update(v)
ip->i_flag &= ~IN_ACCESS;
}
if ((ip->i_flag &
- (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
- ap->a_waitfor != MNT_WAIT)
+ (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)
return (0);
if (ip->i_flag & IN_ACCESS) {
ip->i_ffs_atime = ap->a_access->tv_sec;
@@ -136,17 +133,11 @@ ffs_update(v)
brelse(bp);
return (error);
}
-
- if (DOINGSOFTDEP(ap->a_vp))
- softdep_update_inodeblock(ip, bp, ap->a_waitfor);
- else if (ip->i_effnlink != ip->i_ffs_nlink)
- panic("ffs_update: bad link cnt");
-
*((struct dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number)) = ip->i_din.ffs_din;
- if (ap->a_waitfor && (ap->a_vp->v_mount->mnt_flag & MNT_ASYNC) == 0) {
+ if (ap->a_waitfor)
return (bwrite(bp));
- } else {
+ else {
bdwrite(bp);
return (0);
}
@@ -188,8 +179,6 @@ ffs_truncate(v)
if (length < 0)
return (EINVAL);
oip = VTOI(ovp);
- if (oip->i_ffs_size == length)
- return (0);
TIMEVAL_TO_TIMESPEC(&time, &ts);
if (ovp->v_type == VLNK &&
(oip->i_ffs_size < ovp->v_mount->mnt_maxsymlinklen ||
@@ -213,34 +202,8 @@ ffs_truncate(v)
return (error);
#endif
vnode_pager_setsize(ovp, (u_long)length);
- ovp->v_lasta = ovp->v_clen = ovp->v_cstart = ovp->v_lastw = 0;
- if (DOINGSOFTDEP(ovp)) {
- if (length > 0) {
- /*
- * If a file is only partially truncated, then
- * we have to clean up the data structures
- * describing the allocation past the truncation
- * point. Finding and deallocating those structures
- * is a lot of work. Since partial truncation occurs
- * rarely, we solve the problem by syncing the file
- * so that it will have no data structures left.
- */
- if ((error = VOP_FSYNC(ovp, ap->a_cred, MNT_WAIT,
- ap->a_p)) != 0)
- return (error);
- } else {
-#ifdef QUOTA
- (void) chkdq(oip, -oip->i_ffs_blocks, NOCRED, 0);
-#endif
- softdep_setup_freeblocks(oip, length);
- (void) vinvalbuf(ovp, 0, ap->a_cred, ap->a_p, 0, 0);
- oip->i_flag |= IN_CHANGE | IN_UPDATE;
- return (VOP_UPDATE(ovp, &ts, &ts, 0));
- }
- }
-
fs = oip->i_fs;
- osize = oip->i_ffs_size;
+ osize = oip->i_ffs_size;
/*
* Lengthen the size of the file. We must ensure that the
* last byte of the file is allocated. Since the smallest
@@ -254,12 +217,11 @@ ffs_truncate(v)
aflags = B_CLRBUF;
if (ap->a_flags & IO_SYNC)
aflags |= B_SYNC;
- error = VOP_BALLOC(ovp, length -1, 1,
- ap->a_cred, aflags, &bp);
+ error = ffs_balloc(oip, lbn, offset + 1, ap->a_cred, &bp,
+ aflags);
if (error)
return (error);
oip->i_ffs_size = length;
- vnode_pager_setsize(ovp, (u_long)length);
(void) vnode_pager_uncache(ovp);
if (aflags & B_SYNC)
bwrite(bp);
@@ -268,8 +230,6 @@ ffs_truncate(v)
oip->i_flag |= IN_CHANGE | IN_UPDATE;
return (VOP_UPDATE(ovp, &ts, &ts, 1));
}
- vnode_pager_setsize(ovp, (u_long)length);
-
/*
* Shorten the size of the file. If the file is not being
* truncated to a block boundry, the contents of the
@@ -285,8 +245,7 @@ ffs_truncate(v)
aflags = B_CLRBUF;
if (ap->a_flags & IO_SYNC)
aflags |= B_SYNC;
- error = VOP_BALLOC(ovp, length - 1, 1,
- ap->a_cred, aflags, &bp);
+ error = ffs_balloc(oip, lbn, offset, ap->a_cred, &bp, aflags);
if (error)
return (error);
oip->i_ffs_size = length;
diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index 7e5e417cf53..f2ed4c775a3 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_subr.c,v 1.4 1997/10/06 15:26:31 csapuntz Exp $ */
+/* $OpenBSD: ffs_subr.c,v 1.5 1997/10/06 20:21:36 deraadt Exp $ */
/* $NetBSD: ffs_subr.c,v 1.6 1996/03/17 02:16:23 christos Exp $ */
/*
@@ -42,10 +42,10 @@
#ifdef _KERNEL
#include <sys/systm.h>
#include <sys/vnode.h>
+#include <ufs/ffs/ffs_extern.h>
#include <sys/buf.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
-#include <ufs/ffs/ffs_extern.h>
/*
* Return buffer with the contents of block "offset" from the beginning of
@@ -240,30 +240,3 @@ ffs_setblock(fs, cp, h)
panic("ffs_setblock");
}
}
-
-
-/*
- * check if a block is free
- */
-int
-ffs_isfreeblock(fs, cp, h)
- struct fs *fs;
- unsigned char *cp;
- daddr_t h;
-{
-
- switch ((int)fs->fs_frag) {
- case 8:
- return (cp[h] == 0);
- case 4:
- return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
- case 2:
- return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
- case 1:
- return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
- default:
- panic("ffs_isfreeblock");
- }
-}
-
-
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 7b5f8b2463a..7d85820a10d 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_vfsops.c,v 1.10 1997/10/06 15:26:31 csapuntz Exp $ */
+/* $OpenBSD: ffs_vfsops.c,v 1.11 1997/10/06 20:21:37 deraadt Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */
/*
@@ -51,7 +51,6 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
-#include <sys/sysctl.h>
#include <dev/rndvar.h>
@@ -69,6 +68,7 @@
int ffs_sbupdate __P((struct ufsmount *, int));
struct vfsops ffs_vfsops = {
+ MOUNT_FFS,
ffs_mount,
ufs_start,
ffs_unmount,
@@ -80,53 +80,61 @@ struct vfsops ffs_vfsops = {
ffs_fhtovp,
ffs_vptofh,
ffs_init,
- ffs_sysctl
};
extern u_long nextgennumber;
/*
* Called by main() when ufs is going to be mounted as root.
+ *
+ * Name is updated by mount(8) after booting.
*/
+#define ROOTNAME "root_device"
int
ffs_mountroot()
{
extern struct vnode *rootvp;
- struct fs *fs;
- struct mount *mp;
+ register struct fs *fs;
+ register struct mount *mp;
struct proc *p = curproc; /* XXX */
struct ufsmount *ump;
+ size_t size;
int error;
/*
* Get vnodes for swapdev and rootdev.
*/
- if ((error = bdevvp(swapdev, &swapdev_vp)) ||
- (error = bdevvp(rootdev, &rootvp))) {
- printf("ffs_mountroot: can't setup bdevvp's");
+ if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
+ panic("ffs_mountroot: can't setup bdevvp's");
+
+ mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
+ bzero((char *)mp, (u_long)sizeof(struct mount));
+ mp->mnt_op = &ffs_vfsops;
+ mp->mnt_flag = MNT_RDONLY;
+ if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
+ free(mp, M_MOUNT);
return (error);
}
-
- if ((error = vfs_rootmountalloc("ffs", "root_device", &mp)) != 0)
+ if ((error = vfs_lock(mp)) != 0) {
+ (void)ffs_unmount(mp, 0, p);
+ free(mp, M_MOUNT);
return (error);
- if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
- mp->mnt_vfc->vfc_refcount--;
- vfs_unbusy(mp, p);
- free(mp, M_MOUNT);
- return (error);
- }
- simple_lock(&mountlist_slock);
+ }
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- simple_unlock(&mountlist_slock);
- ump = VFSTOUFS(mp);
- fs = ump->um_fs;
- (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
- (void)ffs_statfs(mp, &mp->mnt_stat, p);
-
- vfs_unbusy(mp, p);
- inittodr(fs->fs_time);
- return (0);
+ mp->mnt_vnodecovered = NULLVP;
+ ump = VFSTOUFS(mp);
+ fs = ump->um_fs;
+ bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
+ fs->fs_fsmnt[0] = '/';
+ bcopy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN);
+ (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
+ &size);
+ bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ (void)ffs_statfs(mp, &mp->mnt_stat, p);
+ vfs_unlock(mp);
+ inittodr(fs->fs_time);
+ return (0);
}
/*
@@ -164,6 +172,8 @@ ffs_mount(mp, path, data, ndp, p)
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
+ if (vfs_busy(mp))
+ return (EBUSY);
error = ffs_flushfiles(mp, flags, p);
if (error == 0 &&
ffs_cgupdate(ump, MNT_WAIT) == 0 &&
@@ -171,6 +181,7 @@ ffs_mount(mp, path, data, ndp, p)
fs->fs_clean = FS_ISCLEAN;
(void) ffs_sbupdate(ump, MNT_WAIT);
}
+ vfs_unbusy(mp);
if (error)
return (error);
fs->fs_ronly = 1;
@@ -187,19 +198,18 @@ ffs_mount(mp, path, data, ndp, p)
*/
if (p->p_ucred->cr_uid != 0) {
devvp = ump->um_devvp;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
+ VOP_LOCK(devvp);
error = VOP_ACCESS(devvp, VREAD | VWRITE,
p->p_ucred, p);
if (error) {
- VOP_UNLOCK(devvp, 0, p);
+ VOP_UNLOCK(devvp);
return (error);
}
- VOP_UNLOCK(devvp, 0, p);
+ VOP_UNLOCK(devvp);
}
fs->fs_ronly = 0;
fs->fs_clean <<= 1;
fs->fs_fmod = 1;
- (void) ffs_sbupdate(ump, MNT_WAIT);
}
if (args.fspec == 0) {
/*
@@ -233,13 +243,13 @@ ffs_mount(mp, path, data, ndp, p)
accessmode = VREAD;
if ((mp->mnt_flag & MNT_RDONLY) == 0)
accessmode |= VWRITE;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
+ VOP_LOCK(devvp);
error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p);
if (error) {
vput(devvp);
return (error);
}
- VOP_UNLOCK(devvp, 0, p);
+ VOP_UNLOCK(devvp);
}
if ((mp->mnt_flag & MNT_UPDATE) == 0)
error = ffs_mountfs(devvp, mp, p);
@@ -307,12 +317,8 @@ ffs_reload(mountp, cred, p)
* Step 1: invalidate all cached meta-data.
*/
devvp = VFSTOUFS(mountp)->um_devvp;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
- error = vinvalbuf(devvp, 0, cred, p, 0, 0);
- VOP_UNLOCK(devvp, 0, p);
- if (error)
+ if (vinvalbuf(devvp, 0, cred, p, 0, 0))
panic("ffs_reload: dirty1");
-
/*
* Step 2: re-read superblock from disk.
*/
@@ -369,26 +375,19 @@ ffs_reload(mountp, cred, p)
}
loop:
- simple_lock(&mntvnode_slock);
for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
- if (vp->v_mount != mountp) {
- simple_unlock(&mntvnode_slock);
- goto loop;
- }
-
nvp = vp->v_mntvnodes.le_next;
/*
* Step 4: invalidate all inactive vnodes.
*/
- if (vrecycle(vp, &mntvnode_slock, p))
- goto loop;
-
+ if (vp->v_usecount == 0) {
+ vgone(vp);
+ continue;
+ }
/*
* Step 5: invalidate all cached file data.
*/
- simple_lock(&vp->v_interlock);
- simple_unlock(&mntvnode_slock);
- if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
+ if (vget(vp, 1))
goto loop;
if (vinvalbuf(vp, 0, cred, p, 0, 0))
panic("ffs_reload: dirty2");
@@ -404,12 +403,11 @@ loop:
}
ip->i_din.ffs_din = *((struct dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number));
- ip->i_effnlink = ip->i_ffs_nlink;
brelse(bp);
vput(vp);
- simple_lock(&mntvnode_slock);
+ if (vp->v_mount != mountp)
+ goto loop;
}
- simple_unlock(&mntvnode_slock);
return (0);
}
@@ -428,7 +426,8 @@ ffs_mountfs(devvp, mp, p)
dev_t dev;
struct partinfo dpart;
caddr_t base, space;
- int error, i, blks, size, ronly;
+ int blks;
+ int error, i, size, ronly;
int32_t *lp;
struct ucred *cred;
extern struct vnode *rootvp;
@@ -446,10 +445,7 @@ ffs_mountfs(devvp, mp, p)
return (error);
if (vcount(devvp) > 1 && devvp != rootvp)
return (EBUSY);
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
- error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0);
- VOP_UNLOCK(devvp, 0, p);
- if (error)
+ if ((error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0)) != 0)
return (error);
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
@@ -488,6 +484,10 @@ ffs_mountfs(devvp, mp, p)
bp = NULL;
fs = ump->um_fs;
fs->fs_ronly = ronly;
+ if (ronly == 0) {
+ fs->fs_clean <<= 1;
+ fs->fs_fmod = 1;
+ }
size = fs->fs_cssize;
blks = howmany(size, fs->fs_fsize);
if (fs->fs_contigsumsize > 0)
@@ -520,8 +520,9 @@ ffs_mountfs(devvp, mp, p)
if (fs->fs_id[0] != 0 && fs->fs_id[1] != 0)
mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1];
else
- mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
+ mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_FFS);
mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
+ mp->mnt_flag |= MNT_LOCAL;
ump->um_mountp = mp;
ump->um_dev = dev;
ump->um_devvp = devvp;
@@ -530,24 +531,14 @@ ffs_mountfs(devvp, mp, p)
ump->um_seqinc = fs->fs_frag;
for (i = 0; i < MAXQUOTAS; i++)
ump->um_quotas[i] = NULLVP;
- devvp->v_specmountpoint = mp;
+ devvp->v_specflags |= SI_MOUNTEDON;
ffs_oldfscompat(fs);
ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */
maxfilesize = (u_int64_t)0x80000000 * fs->fs_bsize - 1; /* XXX */
if (fs->fs_maxfilesize > maxfilesize) /* XXX */
fs->fs_maxfilesize = maxfilesize; /* XXX */
- if (ronly == 0) {
- if ((fs->fs_flags & FS_DOSOFTDEP) &&
- (error = softdep_mount(devvp, mp, fs, cred)) != 0) {
- free(base, M_UFSMNT);
- goto out;
- }
- fs->fs_clean = 0;
- (void) ffs_sbupdate(ump, MNT_WAIT);
- }
return (0);
out:
- devvp->v_specmountpoint = NULL;
if (bp)
brelse(bp);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
@@ -604,14 +595,8 @@ ffs_unmount(mp, mntflags, p)
flags = 0;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
- if (mp->mnt_flag & MNT_SOFTDEP) {
- if ((error = softdep_flushfiles(mp, flags, p)) != 0)
- return (error);
- } else {
- if ((error = ffs_flushfiles(mp, flags, p)) != 0)
- return (error);
- }
-
+ if ((error = ffs_flushfiles(mp, flags, p)) != 0)
+ return (error);
ump = VFSTOUFS(mp);
fs = ump->um_fs;
if (fs->fs_ronly == 0 &&
@@ -620,7 +605,7 @@ ffs_unmount(mp, mntflags, p)
fs->fs_clean = FS_ISCLEAN;
(void) ffs_sbupdate(ump, MNT_WAIT);
}
- ump->um_devvp->v_specmountpoint = NULL;
+ ump->um_devvp->v_specflags &= ~SI_MOUNTEDON;
error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
NOCRED, p);
vrele(ump->um_devvp);
@@ -628,6 +613,7 @@ ffs_unmount(mp, mntflags, p)
free(fs, M_UFSMNT);
free(ump, M_UFSMNT);
mp->mnt_data = (qaddr_t)0;
+ mp->mnt_flag &= ~MNT_LOCAL;
return (error);
}
@@ -640,9 +626,12 @@ ffs_flushfiles(mp, flags, p)
int flags;
struct proc *p;
{
+ extern int doforce;
register struct ufsmount *ump;
int error;
+ if (!doforce)
+ flags &= ~FORCECLOSE;
ump = VFSTOUFS(mp);
#ifdef QUOTA
if (mp->mnt_flag & MNT_QUOTA) {
@@ -660,17 +649,7 @@ ffs_flushfiles(mp, flags, p)
*/
}
#endif
- /*
- * Flush all the files.
- */
- if ((error = vflush(mp, NULL, flags)) != 0)
- return (error);
- /*
- * Flush filesystem metadata.
- */
- vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p);
- error = VOP_FSYNC(ump->um_devvp, p->p_ucred, MNT_WAIT, p);
- VOP_UNLOCK(ump->um_devvp, 0, p);
+ error = vflush(mp, NULLVP, flags);
return (error);
}
@@ -705,11 +684,10 @@ ffs_statfs(mp, sbp, p)
sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO;
sbp->f_ffree = fs->fs_cstotal.cs_nifree;
if (sbp != &mp->mnt_stat) {
- sbp->f_type = mp->mnt_vfc->vfc_typenum;
bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
}
- strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
+ strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
return (0);
}
@@ -727,7 +705,7 @@ ffs_sync(mp, waitfor, cred, p)
struct ucred *cred;
struct proc *p;
{
- register struct vnode *vp, *nvp;
+ register struct vnode *vp;
register struct inode *ip;
register struct ufsmount *ump = VFSTOUFS(mp);
register struct fs *fs;
@@ -739,71 +717,49 @@ ffs_sync(mp, waitfor, cred, p)
* Consistency check that the superblock
* is still in the buffer cache.
*/
- if (fs->fs_fmod != 0 && fs->fs_ronly != 0) {
- printf("fs = %s\n", fs->fs_fsmnt);
- panic("update: rofs mod");
+ if (fs->fs_fmod != 0) {
+ if (fs->fs_ronly != 0) { /* XXX */
+ printf("fs = %s\n", fs->fs_fsmnt);
+ panic("update: rofs mod");
+ }
+ fs->fs_fmod = 0;
+ fs->fs_time = time.tv_sec;
+ allerror = ffs_cgupdate(ump, waitfor);
}
/*
* Write back each (modified) inode.
*/
- simple_lock(&mntvnode_slock);
loop:
for (vp = mp->mnt_vnodelist.lh_first;
vp != NULL;
- vp = nvp) {
+ vp = vp->v_mntvnodes.le_next) {
/*
* If the vnode that we are about to sync is no longer
* associated with this mount point, start over.
*/
if (vp->v_mount != mp)
goto loop;
-
- simple_lock(&vp->v_interlock);
- nvp = vp->v_mntvnodes.le_next;
- ip = VTOI(vp);
- if (vp->v_type == VNON || ((ip->i_flag &
- (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
- vp->v_dirtyblkhd.lh_first == NULL) ||
- waitfor == MNT_LAZY) {
- simple_unlock(&vp->v_interlock);
+ if (VOP_ISLOCKED(vp))
continue;
- }
- simple_unlock(&mntvnode_slock);
- error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p);
- if (error) {
- simple_lock(&mntvnode_slock);
- if (error == ENOENT)
- goto loop;
+ ip = VTOI(vp);
+ if ((ip->i_flag &
+ (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
+ vp->v_dirtyblkhd.lh_first == NULL)
continue;
- }
+ if (vget(vp, 1))
+ goto loop;
if ((error = VOP_FSYNC(vp, cred, waitfor, p)) != 0)
allerror = error;
- VOP_UNLOCK(vp, 0, p);
- vrele(vp);
- simple_lock(&mntvnode_slock);
+ vput(vp);
}
- simple_unlock(&mntvnode_slock);
/*
* Force stale file system control information to be flushed.
*/
- if (waitfor != MNT_LAZY) {
- if (ump->um_mountp->mnt_flag & MNT_SOFTDEP)
- waitfor = MNT_NOWAIT;
- vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p);
- if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0)
- allerror = error;
- VOP_UNLOCK(ump->um_devvp, 0, p);
- }
+ if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0)
+ allerror = error;
#ifdef QUOTA
qsync(mp);
#endif
- /*
- * Write back modified superblock.
- */
-
- if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0)
- allerror = error;
-
return (allerror);
}
@@ -840,7 +796,6 @@ ffs_vget(mp, ino, vpp)
type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */
MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK);
bzero((caddr_t)ip, sizeof(struct inode));
- lockinit(&ip->i_lock, PINOD, "inode", 0, 0);
vp->v_data = ip;
ip->i_vnode = vp;
ip->i_fs = fs = ump->um_fs;
@@ -878,10 +833,6 @@ ffs_vget(mp, ino, vpp)
return (error);
}
ip->i_din.ffs_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino));
- if (DOINGSOFTDEP(vp))
- softdep_load_inodeblock(ip);
- else
- ip->i_effnlink = ip->i_ffs_nlink;
brelse(bp);
/*
@@ -1014,7 +965,7 @@ ffs_cgupdate(mp, waitfor)
struct ufsmount *mp;
int waitfor;
{
- register struct fs *fs = mp->um_fs, *dfs;
+ register struct fs *fs = mp->um_fs;
register struct buf *bp;
int blks;
caddr_t space;
@@ -1036,74 +987,7 @@ ffs_cgupdate(mp, waitfor)
else
bawrite(bp);
}
-
- /*
- * Now write back the superblock itself. If any errors occurred
- * up to this point, then fail so that the superblock avoids
- * being written out as clean.
- */
- if (allerror)
- return (allerror);
- bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0);
- fs->fs_fmod = 0;
- fs->fs_time = time.tv_sec;
- bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
- /* Restore compatibility to old file systems. XXX */
- dfs = (struct fs *)bp->b_data; /* XXX */
- if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
- dfs->fs_nrpos = -1; /* XXX */
- if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
- int32_t *lp, tmp; /* XXX */
- /* XXX */
- lp = (int32_t *)&dfs->fs_qbmask; /* XXX */
- tmp = lp[4]; /* XXX */
- for (i = 4; i > 0; i--) /* XXX */
- lp[i] = lp[i-1]; /* XXX */
- lp[0] = tmp; /* XXX */
- } /* XXX */
- dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */
- if (waitfor != MNT_WAIT)
- bawrite(bp);
- else if ((error = bwrite(bp)) != 0)
+ if (!allerror && error)
allerror = error;
-
return (allerror);
}
-
-/*
- * fast filesystem related variables.
- */
-int
-ffs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
- int *name;
- u_int namelen;
- void *oldp;
- size_t *oldlenp;
- void *newp;
- size_t newlen;
- struct proc *p;
-{
- extern int doclusterread, doclusterwrite, doreallocblks, doasyncfree;
-
- /* all sysctl names at this level are terminal */
- if (namelen != 1)
- return (ENOTDIR); /* overloaded */
-
- switch (name[0]) {
- case FFS_CLUSTERREAD:
- return (sysctl_int(oldp, oldlenp, newp, newlen,
- &doclusterread));
- case FFS_CLUSTERWRITE:
- return (sysctl_int(oldp, oldlenp, newp, newlen,
- &doclusterwrite));
- case FFS_REALLOCBLKS:
- return (sysctl_int(oldp, oldlenp, newp, newlen,
- &doreallocblks));
- case FFS_ASYNCFREE:
- return (sysctl_int(oldp, oldlenp, newp, newlen, &doasyncfree));
- default:
- return (EOPNOTSUPP);
- }
- /* NOTREACHED */
-}
-
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 088ba291a3a..b55b2ca2505 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_vnops.c,v 1.4 1997/10/06 15:26:32 csapuntz Exp $ */
+/* $OpenBSD: ffs_vnops.c,v 1.5 1997/10/06 20:21:38 deraadt Exp $ */
/* $NetBSD: ffs_vnops.c,v 1.7 1996/05/11 18:27:24 mycroft Exp $ */
/*
@@ -82,7 +82,6 @@ struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
{ &vop_lease_desc, ufs_lease_check }, /* lease */
{ &vop_ioctl_desc, ufs_ioctl }, /* ioctl */
{ &vop_select_desc, ufs_select }, /* select */
- { &vop_revoke_desc, ufs_revoke }, /* revoke */
{ &vop_mmap_desc, ufs_mmap }, /* mmap */
{ &vop_fsync_desc, ffs_fsync }, /* fsync */
{ &vop_seek_desc, ufs_seek }, /* seek */
@@ -107,7 +106,6 @@ struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
{ &vop_advlock_desc, ufs_advlock }, /* advlock */
{ &vop_blkatoff_desc, ffs_blkatoff }, /* blkatoff */
{ &vop_valloc_desc, ffs_valloc }, /* valloc */
- { &vop_balloc_desc, ffs_balloc }, /* balloc */
{ &vop_reallocblks_desc, ffs_reallocblks }, /* reallocblks */
{ &vop_vfree_desc, ffs_vfree }, /* vfree */
{ &vop_truncate_desc, ffs_truncate }, /* truncate */
@@ -134,7 +132,6 @@ struct vnodeopv_entry_desc ffs_specop_entries[] = {
{ &vop_lease_desc, spec_lease_check }, /* lease */
{ &vop_ioctl_desc, spec_ioctl }, /* ioctl */
{ &vop_select_desc, spec_select }, /* select */
- { &vop_revoke_desc, spec_revoke }, /* revoke */
{ &vop_mmap_desc, spec_mmap }, /* mmap */
{ &vop_fsync_desc, ffs_fsync }, /* fsync */
{ &vop_seek_desc, spec_seek }, /* seek */
@@ -186,7 +183,6 @@ struct vnodeopv_entry_desc ffs_fifoop_entries[] = {
{ &vop_lease_desc, fifo_lease_check }, /* lease */
{ &vop_ioctl_desc, fifo_ioctl }, /* ioctl */
{ &vop_select_desc, fifo_select }, /* select */
- { &vop_revoke_desc, fifo_revoke }, /* revoke */
{ &vop_mmap_desc, fifo_mmap }, /* mmap */
{ &vop_fsync_desc, ffs_fsync }, /* fsync */
{ &vop_seek_desc, fifo_seek }, /* seek */
@@ -222,11 +218,20 @@ struct vnodeopv_desc ffs_fifoop_opv_desc =
{ &ffs_fifoop_p, ffs_fifoop_entries };
#endif /* FIFO */
+#ifdef DEBUG
/*
* Enabling cluster read/write operations.
*/
+#include <sys/sysctl.h>
int doclusterread = 1;
+struct ctldebug debug11 = { "doclusterread", &doclusterread };
int doclusterwrite = 1;
+struct ctldebug debug12 = { "doclusterwrite", &doclusterwrite };
+#else
+/* XXX for ufs_readwrite */
+#define doclusterread 1
+#define doclusterwrite 1
+#endif
#include <ufs/ufs/ufs_readwrite.c>
@@ -244,84 +249,12 @@ ffs_fsync(v)
int a_waitfor;
struct proc *a_p;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct buf *bp, *nbp;
+ register struct vnode *vp = ap->a_vp;
struct timespec ts;
- int s, error, passes, skipmeta;
- /*
- * Flush all dirty buffers associated with a vnode
- */
- passes = NIADDR;
- skipmeta = 0;
- if (ap->a_waitfor == MNT_WAIT)
- skipmeta = 1;
-loop:
- s = splbio();
-loop2:
- for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) {
- nbp = bp->b_vnbufs.le_next;
- if ((bp->b_flags & B_BUSY))
- continue;
- if ((bp->b_flags & B_DELWRI) == 0)
- panic("ffs_fsync: not dirty");
- if (skipmeta && bp->b_lblkno < 0)
- continue;
- bremfree(bp);
- bp->b_flags |= B_BUSY;
- splx(s);
- /*
- * Wait for I/O associated with indirect blocks to complete,
- * since there is no way to quickly wait for them below.
- */
- if (bp->b_vp == vp || ap->a_waitfor != MNT_WAIT)
- (void) bawrite(bp);
- else if ((error = bwrite(bp)) != 0)
- return (error);
- goto loop;
- }
- if (skipmeta) {
- skipmeta = 0;
- goto loop2;
- }
- if (ap->a_waitfor == MNT_WAIT) {
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
- }
- /*
- * Ensure that any filesystem metatdata associated
- * with the vnode has been written.
- */
- splx(s);
- if ((error = softdep_sync_metadata(ap)) != 0)
- return (error);
- s = splbio();
- if (vp->v_dirtyblkhd.lh_first) {
- /*
- * Block devices associated with filesystems may
- * have new I/O requests posted for them even if
- * the vnode is locked, so no amount of trying will
- * get them clean. Thus we give block devices a
- * good effort, then just give up. For all other file
- * types, go around and try again until it is clean.
- */
- if (passes > 0) {
- passes -= 1;
- goto loop2;
- }
-#ifdef DIAGNOSTIC
- if (vp->v_type != VBLK)
- vprint("ffs_fsync: dirty", vp);
-#endif
- }
- }
- splx(s);
+ vflushbuf(vp, ap->a_waitfor == MNT_WAIT);
TIMEVAL_TO_TIMESPEC(&time, &ts);
- if ((error = VOP_UPDATE(vp, &ts, &ts, ap->a_waitfor == MNT_WAIT)) != 0) return (error);
- if (DOINGSOFTDEP(vp) && ap->a_waitfor == MNT_WAIT)
- error = softdep_fsync(vp);
- return (error);
+ return (VOP_UPDATE(ap->a_vp, &ts, &ts, ap->a_waitfor == MNT_WAIT));
}
/*
@@ -333,12 +266,11 @@ ffs_reclaim(v)
{
struct vop_reclaim_args /* {
struct vnode *a_vp;
- sturct proc *a_p;
} */ *ap = v;
register struct vnode *vp = ap->a_vp;
int error;
- if ((error = ufs_reclaim(vp, ap->a_p)) != 0)
+ if ((error = ufs_reclaim(vp)) != 0)
return (error);
FREE(vp->v_data, VFSTOUFS(vp->v_mount)->um_devvp->v_tag == VT_MFS ?
M_MFSNODE : M_FFSNODE);
diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h
index 2979a3c4fe9..6086da88456 100644
--- a/sys/ufs/ffs/fs.h
+++ b/sys/ufs/ffs/fs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: fs.h,v 1.5 1997/10/06 15:26:32 csapuntz Exp $ */
+/* $OpenBSD: fs.h,v 1.6 1997/10/06 20:21:39 deraadt Exp $ */
/* $NetBSD: fs.h,v 1.6 1995/04/12 21:21:02 mycroft Exp $ */
/*
@@ -221,7 +221,7 @@ struct fs {
int8_t fs_fmod; /* super block modified flag */
int8_t fs_clean; /* file system is clean flag */
int8_t fs_ronly; /* mounted read-only flag */
- int8_t fs_flags; /* see FS_ below */
+ int8_t fs_flags; /* currently unused flag */
u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
/* these fields retain the current block allocation info */
int32_t fs_cgrotor; /* last cg searched */
@@ -267,12 +267,6 @@ struct fs {
#define FS_OPTTIME 0 /* minimize allocation time */
#define FS_OPTSPACE 1 /* minimize disk fragmentation */
-/*
- * Filesystem falgs.
- */
-#define FS_UNCLEAN 0x01 /* filesystem not clean at mount */
-#define FS_DOSOFTDEP 0x02 /* filesystem using soft dependencies */
-
/*
* Rotational layout table format types
*/
@@ -496,12 +490,6 @@ struct ocg {
? (fs)->fs_bsize \
: (fragroundup(fs, blkoff(fs, (dip)->di_size))))
-#define sblksize(fs, size, lbn) \
- (((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
- ? (fs)->fs_bsize \
- : (fragroundup(fs, blkoff(fs, (size)))))
-
-
/*
* Number of disk sectors per block/fragment; assumes DEV_BSIZE byte
* sector size.
diff --git a/sys/ufs/mfs/mfs_extern.h b/sys/ufs/mfs/mfs_extern.h
index 3616acedf76..2e6990373c1 100644
--- a/sys/ufs/mfs/mfs_extern.h
+++ b/sys/ufs/mfs/mfs_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfs_extern.h,v 1.3 1997/10/06 15:27:12 csapuntz Exp $ */
+/* $OpenBSD: mfs_extern.h,v 1.4 1997/10/06 20:21:40 deraadt Exp $ */
/* $NetBSD: mfs_extern.h,v 1.4 1996/02/09 22:31:27 christos Exp $ */
/*-
@@ -43,7 +43,6 @@ struct proc;
struct statfs;
struct ucred;
struct vnode;
-struct vfsconf;
__BEGIN_DECLS
/* mfs_vfsops.c */
@@ -54,7 +53,7 @@ int mfs_mount __P((struct mount *, char *, caddr_t,
int mfs_start __P((struct mount *, int, struct proc *));
int mfs_statfs __P((struct mount *, struct statfs *, struct proc *));
-int mfs_init __P((struct vfsconf *));
+void mfs_init __P((void));
/* mfs_vnops.c */
int mfs_open __P((void *));
@@ -66,7 +65,6 @@ int mfs_close __P((void *));
int mfs_inactive __P((void *));
int mfs_reclaim __P((void *));
int mfs_print __P((void *));
-#define mfs_revoke vop_revoke
int mfs_badop __P((void *));
__END_DECLS
diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c
index dbd32e6ea2f..24f94b86582 100644
--- a/sys/ufs/mfs/mfs_vfsops.c
+++ b/sys/ufs/mfs/mfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfs_vfsops.c,v 1.3 1997/10/06 15:27:12 csapuntz Exp $ */
+/* $OpenBSD: mfs_vfsops.c,v 1.4 1997/10/06 20:21:41 deraadt Exp $ */
/* $NetBSD: mfs_vfsops.c,v 1.10 1996/02/09 22:31:28 christos Exp $ */
/*
@@ -69,6 +69,7 @@ extern int (**mfs_vnodeop_p) __P((void *));
* mfs vfs operations.
*/
struct vfsops mfs_vfsops = {
+ MOUNT_MFS,
mfs_mount,
mfs_start,
ffs_unmount,
@@ -80,31 +81,37 @@ struct vfsops mfs_vfsops = {
ffs_fhtovp,
ffs_vptofh,
mfs_init,
- ffs_sysctl
};
/*
* Called by main() when mfs is going to be mounted as root.
+ *
+ * Name is updated by mount(8) after booting.
*/
+#define ROOTNAME "mfs_root"
int
mfs_mountroot()
{
extern struct vnode *rootvp;
register struct fs *fs;
- struct mount *mp;
+ register struct mount *mp;
struct proc *p = curproc; /* XXX */
struct ufsmount *ump;
struct mfsnode *mfsp;
+ size_t size;
int error;
- if ((error = bdevvp(swapdev, &swapdev_vp)) ||
- (error = bdevvp(rootdev, &rootvp))) {
- printf("mfs_mountroot: can't setup bdevvp's");
- return (error);
- }
- if ((error = vfs_rootmountalloc("mfs", "mfs_root", &mp)) != 0)
- return (error);
+ /*
+ * Get vnodes for swapdev and rootdev.
+ */
+ if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
+ panic("mfs_mountroot: can't setup bdevvp's");
+
+ mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
+ bzero((char *)mp, (u_long)sizeof(struct mount));
+ mp->mnt_op = &mfs_vfsops;
+ mp->mnt_flag = MNT_RDONLY;
mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK);
rootvp->v_data = mfsp;
rootvp->v_op = mfs_vnodeop_p;
@@ -115,20 +122,28 @@ mfs_mountroot()
mfsp->mfs_pid = p->p_pid;
mfsp->mfs_buflist = (struct buf *)0;
if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
- mp->mnt_vfc->vfc_refcount--;
- vfs_unbusy(mp, p);
free(mp, M_MOUNT);
free(mfsp, M_MFSNODE);
return (error);
}
- simple_lock(&mountlist_slock);
+ if ((error = vfs_lock(mp)) != 0) {
+ (void)ffs_unmount(mp, 0, p);
+ free(mp, M_MOUNT);
+ free(mfsp, M_MFSNODE);
+ return (error);
+ }
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- simple_unlock(&mountlist_slock);
+ mp->mnt_vnodecovered = NULLVP;
ump = VFSTOUFS(mp);
fs = ump->um_fs;
- (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
+ bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
+ fs->fs_fsmnt[0] = '/';
+ bcopy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN);
+ (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
+ &size);
+ bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
(void)ffs_statfs(mp, &mp->mnt_stat, p);
- vfs_unbusy(mp, p);
+ vfs_unlock(mp);
inittodr((time_t)0);
return (0);
}
@@ -192,7 +207,10 @@ mfs_mount(mp, path, data, ndp, p)
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
+ if (vfs_busy(mp))
+ return (EBUSY);
error = ffs_flushfiles(mp, flags, p);
+ vfs_unbusy(mp);
if (error)
return (error);
}
@@ -254,6 +272,7 @@ mfs_start(mp, flags, p)
register struct mfsnode *mfsp = VTOMFS(vp);
register struct buf *bp;
register caddr_t base;
+ int error = 0;
base = mfsp->mfs_baseoff;
while (mfsp->mfs_buflist != (struct buf *)-1) {
@@ -270,11 +289,13 @@ mfs_start(mp, flags, p)
* otherwise we will loop here, as tsleep will always return
* EINTR/ERESTART.
*/
- if (tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0) &&
- dounmount(mp, 0, p) != 0)
- CLRSIG(p, CURSIG(p));
+ if ((error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) != 0) {
+ DOIO();
+ if (dounmount(mp, 0, p) != 0)
+ CLRSIG(p, CURSIG(p));
+ }
}
- return (0);
+ return (error);
}
/*
@@ -290,10 +311,10 @@ mfs_statfs(mp, sbp, p)
error = ffs_statfs(mp, sbp, p);
#ifdef COMPAT_09
- sbp->f_type = mp->mnt_vfc->vfc_typenum;
+ sbp->f_type = 3;
#else
sbp->f_type = 0;
#endif
- strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
+ strncpy(&sbp->f_fstypename[0], mp->mnt_op->vfs_name, MFSNAMELEN);
return (error);
}
diff --git a/sys/ufs/mfs/mfs_vnops.c b/sys/ufs/mfs/mfs_vnops.c
index 84a5ed3d368..23121dfa94b 100644
--- a/sys/ufs/mfs/mfs_vnops.c
+++ b/sys/ufs/mfs/mfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfs_vnops.c,v 1.5 1997/10/06 15:27:13 csapuntz Exp $ */
+/* $OpenBSD: mfs_vnops.c,v 1.6 1997/10/06 20:21:42 deraadt Exp $ */
/* $NetBSD: mfs_vnops.c,v 1.8 1996/03/17 02:16:32 christos Exp $ */
/*
@@ -72,7 +72,6 @@ struct vnodeopv_entry_desc mfs_vnodeop_entries[] = {
{ &vop_write_desc, mfs_write }, /* write */
{ &vop_ioctl_desc, mfs_ioctl }, /* ioctl */
{ &vop_select_desc, mfs_select }, /* select */
- { &vop_revoke_desc, mfs_revoke }, /* revoke */
{ &vop_mmap_desc, mfs_mmap }, /* mmap */
{ &vop_fsync_desc, spec_fsync }, /* fsync */
{ &vop_seek_desc, mfs_seek }, /* seek */
@@ -232,9 +231,6 @@ mfs_bmap(v)
*ap->a_vpp = ap->a_vp;
if (ap->a_bnp != NULL)
*ap->a_bnp = ap->a_bn;
- if (ap->a_runp != NULL)
- *ap->a_runp = 0;
-
return (0);
}
@@ -298,14 +294,12 @@ mfs_inactive(v)
{
struct vop_inactive_args /* {
struct vnode *a_vp;
- struct proc *a_p;
} */ *ap = v;
register struct mfsnode *mfsp = VTOMFS(ap->a_vp);
if (mfsp->mfs_buflist && mfsp->mfs_buflist != (struct buf *)(-1))
panic("mfs_inactive: not inactive (mfs_buflist %p)",
mfsp->mfs_buflist);
- VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
return (0);
}
@@ -358,9 +352,8 @@ mfs_badop(v)
/*
* Memory based filesystem initialization.
*/
-int
-mfs_init(vfsp)
- struct vfsconf *vfsp;
+void
+mfs_init()
{
- return (0);
+
}
diff --git a/sys/ufs/mfs/mfsnode.h b/sys/ufs/mfs/mfsnode.h
index 29c290c4e09..384c3dc2475 100644
--- a/sys/ufs/mfs/mfsnode.h
+++ b/sys/ufs/mfs/mfsnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfsnode.h,v 1.4 1997/10/06 15:27:13 csapuntz Exp $ */
+/* $OpenBSD: mfsnode.h,v 1.5 1997/10/06 20:21:43 deraadt Exp $ */
/* $NetBSD: mfsnode.h,v 1.3 1996/02/09 22:31:31 christos Exp $ */
/*
@@ -76,9 +76,9 @@ struct mfsnode {
#define mfs_readdir mfs_badop
#define mfs_readlink mfs_badop
#define mfs_abortop mfs_badop
-#define mfs_lock vop_nolock
-#define mfs_unlock vop_nounlock
-#define mfs_islocked vop_noislocked
+#define mfs_lock nullop
+#define mfs_unlock nullop
+#define mfs_islocked nullop
#define mfs_pathconf mfs_badop
#define mfs_advlock mfs_badop
#define mfs_blkatoff mfs_badop
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index 0a9a7a24151..1c42e308cbb 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: inode.h,v 1.7 1997/10/06 15:27:36 csapuntz Exp $ */
+/* $OpenBSD: inode.h,v 1.8 1997/10/06 20:21:44 deraadt Exp $ */
/* $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $ */
/*
@@ -45,8 +45,6 @@
#include <ufs/ufs/dir.h>
#include <ufs/ext2fs/ext2fs_dinode.h>
-typedef long ufs_lbn_t;
-
/*
* Per-filesystem inode extensions.
*/
@@ -65,13 +63,13 @@ struct ext2fs_inode_ext {
* active, and is put back when the file is no longer being used.
*/
struct inode {
- LIST_ENTRY(inode) i_hash; /* Hash chain */
+ struct inode *i_next; /* Hash chain forward. */
+ struct inode **i_prev; /* Hash chain back. */
struct vnode *i_vnode;/* Vnode associated with this inode. */
struct vnode *i_devvp;/* Vnode for block I/O. */
u_int32_t i_flag; /* flags, see below */
dev_t i_dev; /* Device associated with the inode. */
ino_t i_number; /* The identity of the inode. */
- int i_effnlink; /* i_nlink when I/O completes */
union { /* Associated filesystem. */
struct fs *fs; /* FFS */
@@ -85,8 +83,8 @@ struct inode {
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for NFS lease. */
struct lockf *i_lockf;/* Head of byte-level lock list. */
- struct lock i_lock; /* Inode lock */
-
+ pid_t i_lockholder; /* DEBUG: holder of inode lock. */
+ pid_t i_lockwaiter; /* DEBUG: latest blocked for inode lock. */
/*
* Side effects; used during directory lookup.
*/
@@ -182,11 +180,14 @@ struct inode {
/* These flags are kept in i_flag. */
#define IN_ACCESS 0x0001 /* Access time update request. */
#define IN_CHANGE 0x0002 /* Inode change time update request. */
-#define IN_UPDATE 0x0004 /* Modification time update request */
-#define IN_MODIFIED 0x0008 /* Inode has been modified. */
-#define IN_RENAME 0x0010 /* Inode is being renamed. */
-#define IN_SHLOCK 0x0020 /* FIle has shared lock. */
-#define IN_EXLOCK 0x0040 /* File has exclusive lock. */
+#define IN_EXLOCK 0x0004 /* File has exclusive lock. */
+#define IN_LOCKED 0x0008 /* Inode lock. */
+#define IN_LWAIT 0x0010 /* Process waiting on file lock. */
+#define IN_MODIFIED 0x0020 /* Inode has been modified. */
+#define IN_RENAME 0x0040 /* Inode is being renamed. */
+#define IN_SHLOCK 0x0080 /* File has shared lock. */
+#define IN_UPDATE 0x0100 /* Modification time update request. */
+#define IN_WANTED 0x0200 /* Inode is wanted by a process. */
#ifdef _KERNEL
/*
@@ -241,9 +242,6 @@ struct indir {
} \
}
-/* Determine if soft dependencies are being done */
-#define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
-
/* This overlays the fid structure (see mount.h). */
struct ufid {
u_int16_t ufid_len; /* Length of structure. */
diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h
index 166d8f43684..01fb64ac124 100644
--- a/sys/ufs/ufs/ufs_extern.h
+++ b/sys/ufs/ufs/ufs_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_extern.h,v 1.3 1997/10/06 15:27:36 csapuntz Exp $ */
+/* $OpenBSD: ufs_extern.h,v 1.4 1997/10/06 20:21:45 deraadt Exp $ */
/* $NetBSD: ufs_extern.h,v 1.5 1996/02/09 22:36:03 christos Exp $ */
/*-
@@ -54,7 +54,6 @@ struct ufs_args;
struct ufsmount;
struct uio;
struct vattr;
-struct vfsconf;
struct vnode;
__BEGIN_DECLS
@@ -87,7 +86,6 @@ int ufs_readdir __P((void *));
int ufs_readlink __P((void *));
int ufs_remove __P((void *));
int ufs_rename __P((void *));
-#define ufs_revoke vop_revoke
int ufs_rmdir __P((void *));
int ufs_seek __P((void *));
int ufs_select __P((void *));
@@ -119,19 +117,19 @@ void ufs_ihashins __P((struct inode *));
void ufs_ihashrem __P((struct inode *));
/* ufs_inode.c */
-int ufs_init __P((struct vfsconf *));
-int ufs_reclaim __P((struct vnode *, struct proc *));
+void ufs_init __P((void));
+int ufs_reclaim __P((struct vnode *));
/* ufs_lookup.c */
void ufs_dirbad __P((struct inode *, doff_t, char *));
int ufs_dirbadentry __P((struct vnode *, struct direct *, int));
-void ufs_makedirentry __P((struct inode *, struct componentname *,
- struct direct *));
-int ufs_direnter __P((struct vnode *, struct direct *,
- struct componentname *, struct buf *));
-int ufs_dirremove __P((struct vnode *, struct inode *, int, int));
+int ufs_direnter __P((struct inode *, struct vnode *,
+ struct componentname *));
+int ufs_direnter2 __P((struct vnode *, struct direct *, struct ucred *,
+ struct proc *));
+int ufs_dirremove __P((struct vnode *, struct componentname *));
int ufs_dirrewrite __P((struct inode *, struct inode *,
- ino_t, int, int));
+ struct componentname *));
int ufs_dirempty __P((struct inode *, ino_t, struct ucred *));
int ufs_checkpath __P((struct inode *, struct inode *, struct ucred *));
@@ -167,19 +165,4 @@ int ufs_vinit __P((struct mount *, int (**) __P((void *)),
int (**) __P((void *)), struct vnode **));
int ufs_makeinode __P((int, struct vnode *, struct vnode **,
struct componentname *));
-
-
-/*
- * Soft dependency function prototypes.
- */
-void softdep_setup_directory_add __P((struct buf *, struct inode *, off_t,
- long, struct buf *));
-void softdep_change_directoryentry_offset __P((struct inode *, caddr_t,
- caddr_t, caddr_t, int));
-void softdep_setup_remove __P((struct buf *,struct inode *, struct inode *,
- int));
-void softdep_setup_directory_change __P((struct buf *, struct inode *,
- struct inode *, long, int));
-void softdep_increase_linkcnt __P((struct inode *));
-
__END_DECLS
diff --git a/sys/ufs/ufs/ufs_ihash.c b/sys/ufs/ufs/ufs_ihash.c
index 84ff51b8b39..57197b77212 100644
--- a/sys/ufs/ufs/ufs_ihash.c
+++ b/sys/ufs/ufs/ufs_ihash.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_ihash.c,v 1.3 1997/10/06 15:27:37 csapuntz Exp $ */
+/* $OpenBSD: ufs_ihash.c,v 1.4 1997/10/06 20:21:45 deraadt Exp $ */
/* $NetBSD: ufs_ihash.c,v 1.3 1996/02/09 22:36:04 christos Exp $ */
/*
@@ -49,10 +49,9 @@
/*
* Structures associated with inode cacheing.
*/
-LIST_HEAD(ihashhead, inode) *ihashtbl;
+struct inode **ihashtbl;
u_long ihash; /* size of hash table - 1 */
-#define INOHASH(device, inum) (&ihashtbl[((device) + (inum)) & ihash])
-struct simplelock ufs_ihash_slock;
+#define INOHASH(device, inum) (((device) + (inum)) & ihash)
/*
* Initialize inode hash table.
@@ -62,7 +61,6 @@ ufs_ihashinit()
{
ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash);
- simple_lock_init(&ufs_ihash_slock);
}
/*
@@ -70,21 +68,19 @@ ufs_ihashinit()
* to it. If it is in core, return it, even if it is locked.
*/
struct vnode *
-ufs_ihashlookup(dev, inum)
- dev_t dev;
+ufs_ihashlookup(device, inum)
+ dev_t device;
ino_t inum;
{
- struct inode *ip;
+ register struct inode *ip;
- simple_lock(&ufs_ihash_slock);
- for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next)
- if (inum == ip->i_number && dev == ip->i_dev)
- break;
- simple_unlock(&ufs_ihash_slock);
-
- if (ip)
- return (ITOV(ip));
- return (NULLVP);
+ for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) {
+ if (ip == NULL)
+ return (NULL);
+ if (inum == ip->i_number && device == ip->i_dev)
+ return (ITOV(ip));
+ }
+ /* NOTREACHED */
}
/*
@@ -92,28 +88,30 @@ ufs_ihashlookup(dev, inum)
* to it. If it is in core, but locked, wait for it.
*/
struct vnode *
-ufs_ihashget(dev, inum)
- dev_t dev;
+ufs_ihashget(device, inum)
+ dev_t device;
ino_t inum;
{
- struct proc *p = curproc;
- struct inode *ip;
+ register struct inode *ip;
struct vnode *vp;
-loop:
- simple_lock(&ufs_ihash_slock);
- for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) {
- if (inum == ip->i_number && dev == ip->i_dev) {
- vp = ITOV(ip);
- simple_lock(&vp->v_interlock);
- simple_unlock(&ufs_ihash_slock);
- if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
- goto loop;
- return (vp);
- }
- }
- simple_unlock(&ufs_ihash_slock);
- return (NULL);
+ for (;;)
+ for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) {
+ if (ip == NULL)
+ return (NULL);
+ if (inum == ip->i_number && device == ip->i_dev) {
+ if (ip->i_flag & IN_LOCKED) {
+ ip->i_flag |= IN_WANTED;
+ sleep(ip, PINOD);
+ break;
+ }
+ vp = ITOV(ip);
+ if (!vget(vp, 1))
+ return (vp);
+ break;
+ }
+ }
+ /* NOTREACHED */
}
/*
@@ -123,16 +121,21 @@ void
ufs_ihashins(ip)
struct inode *ip;
{
- struct proc *p = curproc; /* XXX */
- struct ihashhead *ipp;
+ struct inode **ipp, *iq;
- /* lock the inode, then put it on the appropriate hash list */
- lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p);
-
- simple_lock(&ufs_ihash_slock);
- ipp = INOHASH(ip->i_dev, ip->i_number);
- LIST_INSERT_HEAD(ipp, ip, i_hash);
- simple_unlock(&ufs_ihash_slock);
+ ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];
+ if ((iq = *ipp) != NULL)
+ iq->i_prev = &ip->i_next;
+ ip->i_next = iq;
+ ip->i_prev = ipp;
+ *ipp = ip;
+ if (ip->i_flag & IN_LOCKED)
+ panic("ufs_ihashins: already locked");
+ if (curproc)
+ ip->i_lockholder = curproc->p_pid;
+ else
+ ip->i_lockholder = -1;
+ ip->i_flag |= IN_LOCKED;
}
/*
@@ -140,14 +143,15 @@ ufs_ihashins(ip)
*/
void
ufs_ihashrem(ip)
- struct inode *ip;
+ register struct inode *ip;
{
- simple_lock(&ufs_ihash_slock);
- LIST_REMOVE(ip, i_hash);
- #ifdef DIAGNOSTIC
- ip->i_hash.le_next = NULL;
- ip->i_hash.le_prev = NULL;
- #endif
- simple_unlock(&ufs_ihash_slock);
+ register struct inode *iq;
+ if ((iq = ip->i_next) != NULL)
+ iq->i_prev = ip->i_prev;
+ *ip->i_prev = iq;
+#ifdef DIAGNOSTIC
+ ip->i_next = NULL;
+ ip->i_prev = NULL;
+#endif
}
diff --git a/sys/ufs/ufs/ufs_inode.c b/sys/ufs/ufs/ufs_inode.c
index 31437cd4bfd..db2b1d9cdcb 100644
--- a/sys/ufs/ufs/ufs_inode.c
+++ b/sys/ufs/ufs/ufs_inode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_inode.c,v 1.5 1997/10/06 15:27:37 csapuntz Exp $ */
+/* $OpenBSD: ufs_inode.c,v 1.6 1997/10/06 20:21:46 deraadt Exp $ */
/* $NetBSD: ufs_inode.c,v 1.7 1996/05/11 18:27:52 mycroft Exp $ */
/*
@@ -57,7 +57,6 @@
u_long nextgennumber; /* Next generation number to assign. */
-#if 0
void
ufs_init()
{
@@ -72,7 +71,7 @@ ufs_init()
#endif
return;
}
-#endif
+
/*
* Last reference to an inode. If necessary, write or delete it.
*/
@@ -82,29 +81,39 @@ ufs_inactive(v)
{
struct vop_inactive_args /* {
struct vnode *a_vp;
- sturct proc *a_p;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
- struct proc *p = ap->a_p;
+ register struct vnode *vp = ap->a_vp;
+ register struct inode *ip = VTOI(vp);
struct timespec ts;
- int mode, error = 0;
+ int mode, error;
extern int prtactive;
if (prtactive && vp->v_usecount != 0)
vprint("ffs_inactive: pushing active", vp);
- /*
- * Ignore inodes related to stale file handles.
- */
- if (ip->i_ffs_mode == 0)
- goto out;
+ /* Get rid of inodes related to stale file handles. */
+ if (ip->i_ffs_mode == 0) {
+ if ((vp->v_flag & VXLOCK) == 0)
+ vgone(vp);
+ return (0);
+ }
+
+ error = 0;
+#ifdef DIAGNOSTIC
+ if (VOP_ISLOCKED(vp))
+ panic("ffs_inactive: locked inode");
+ if (curproc)
+ ip->i_lockholder = curproc->p_pid;
+ else
+ ip->i_lockholder = -1;
+#endif
+ ip->i_flag |= IN_LOCKED;
if (ip->i_ffs_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
#ifdef QUOTA
if (!getinoquota(ip))
(void)chkiq(ip, -1, NOCRED, 0);
#endif
- error = VOP_TRUNCATE(vp, (off_t)0, 0, NOCRED, p);
+ error = VOP_TRUNCATE(vp, (off_t)0, 0, NOCRED, NULL);
ip->i_ffs_rdev = 0;
mode = ip->i_ffs_mode;
ip->i_ffs_mode = 0;
@@ -115,14 +124,13 @@ ufs_inactive(v)
TIMEVAL_TO_TIMESPEC(&time, &ts);
VOP_UPDATE(vp, &ts, &ts, 0);
}
-out:
- VOP_UNLOCK(vp, 0, p);
+ VOP_UNLOCK(vp);
/*
* If we are done with the inode, reclaim it
* so that it can be reused immediately.
*/
- if (ip->i_ffs_mode == 0)
- vrecycle(vp, (struct simplelock *)0, p);
+ if (vp->v_usecount == 0 && ip->i_ffs_mode == 0)
+ vgone(vp);
return (error);
}
@@ -130,9 +138,8 @@ out:
* Reclaim an inode so that it can be used for other purposes.
*/
int
-ufs_reclaim(vp, p)
+ufs_reclaim(vp)
register struct vnode *vp;
- struct proc *p;
{
register struct inode *ip;
extern int prtactive;
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index 47587cdd00a..6bb8bf6e4da 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_lookup.c,v 1.5 1997/10/06 15:27:38 csapuntz Exp $ */
+/* $OpenBSD: ufs_lookup.c,v 1.6 1997/10/06 20:21:47 deraadt Exp $ */
/* $NetBSD: ufs_lookup.c,v 1.7 1996/02/09 22:36:06 christos Exp $ */
/*
@@ -43,16 +43,12 @@
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/kernel.h>
#include <sys/namei.h>
#include <sys/buf.h>
#include <sys/file.h>
-#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/vnode.h>
-#include <vm/vm.h>
-
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/dir.h>
@@ -135,7 +131,6 @@ ufs_lookup(v)
struct ucred *cred = cnp->cn_cred;
int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop;
- struct proc *p = cnp->cn_proc;
bp = NULL;
slotoffset = -1;
@@ -153,10 +148,6 @@ ufs_lookup(v)
if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)) != 0)
return (error);
- if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
- (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
- return (EROFS);
-
/*
* We now have a segment name to search for, and a directory to search.
*
@@ -182,14 +173,14 @@ ufs_lookup(v)
VREF(vdp);
error = 0;
} else if (flags & ISDOTDOT) {
- VOP_UNLOCK(pdp, 0, p);
- error = vget(vdp, LK_EXCLUSIVE, p);
+ VOP_UNLOCK(pdp);
+ error = vget(vdp, 1);
if (!error && lockparent && (flags & ISLASTCN))
- error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
+ error = VOP_LOCK(pdp);
} else {
- error = vget(vdp, LK_EXCLUSIVE, p);
+ error = vget(vdp, 1);
if (!lockparent || error || !(flags & ISLASTCN))
- VOP_UNLOCK(pdp, 0, p);
+ VOP_UNLOCK(pdp);
}
/*
* Check that the capability number did not change
@@ -200,14 +191,13 @@ ufs_lookup(v)
return (0);
vput(vdp);
if (lockparent && pdp != vdp && (flags & ISLASTCN))
- VOP_UNLOCK(pdp, 0, p);
+ VOP_UNLOCK(pdp);
}
- *vpp = NULL;
-
- if ((error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p)) != 0)
+ if ((error = VOP_LOCK(pdp)) != 0)
return (error);
vdp = pdp;
dp = VTOI(pdp);
+ *vpp = NULL;
}
/*
@@ -406,7 +396,7 @@ notfound:
(nameiop == DELETE &&
(ap->a_cnp->cn_flags & DOWHITEOUT) &&
(ap->a_cnp->cn_flags & ISWHITEOUT))) &&
- (flags & ISLASTCN) && dp->i_effnlink != 0) {
+ (flags & ISLASTCN) && dp->i_ffs_nlink != 0) {
/*
* Access for write is interpreted as allowing
* creation of files in the directory.
@@ -456,7 +446,7 @@ notfound:
*/
cnp->cn_flags |= SAVENAME;
if (!lockparent)
- VOP_UNLOCK(vdp, 0, p);
+ VOP_UNLOCK(vdp);
return (EJUSTRETURN);
}
/*
@@ -534,7 +524,7 @@ found:
}
*vpp = tdp;
if (!lockparent)
- VOP_UNLOCK(vdp, 0, p);
+ VOP_UNLOCK(vdp);
return (0);
}
@@ -561,7 +551,7 @@ found:
*vpp = tdp;
cnp->cn_flags |= SAVENAME;
if (!lockparent)
- VOP_UNLOCK(vdp, 0, p);
+ VOP_UNLOCK(vdp);
return (0);
}
@@ -586,14 +576,14 @@ found:
*/
pdp = vdp;
if (flags & ISDOTDOT) {
- VOP_UNLOCK(pdp, 0, p); /* race to get the inode */
+ VOP_UNLOCK(pdp); /* race to get the inode */
error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
if (error) {
- vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
+ VOP_LOCK(pdp);
return (error);
}
if (lockparent && (flags & ISLASTCN) &&
- (error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
+ (error = VOP_LOCK(pdp))) {
vput(tdp);
return (error);
}
@@ -606,7 +596,7 @@ found:
if (error)
return (error);
if (!lockparent || !(flags & ISLASTCN))
- VOP_UNLOCK(pdp, 0, p);
+ VOP_UNLOCK(pdp);
*vpp = tdp;
}
@@ -681,130 +671,108 @@ bad:
}
/*
- * Construct a new directory entry after a call to namei, using the
- * parameters that it left in the componentname argument cnp. The
- * argument ip is the inode to which the new directory entry will refer.
+ * Write a directory entry after a call to namei, using the parameters
+ * that it left in nameidata. The argument ip is the inode which the new
+ * directory entry will refer to. Dvp is a pointer to the directory to
+ * be written, which was left locked by namei. Remaining parameters
+ * (dp->i_offset, dp->i_count) indicate how the space for the new
+ * entry is to be obtained.
*/
-void
-ufs_makedirentry(ip, cnp, newdirp)
- struct inode *ip;
- struct componentname *cnp;
- struct direct *newdirp;
+int
+ufs_direnter(ip, dvp, cnp)
+ struct inode *ip;
+ struct vnode *dvp;
+ register struct componentname *cnp;
{
-
+ register struct inode *dp;
+ struct direct newdir;
+
#ifdef DIAGNOSTIC
- if ((cnp->cn_flags & SAVENAME) == 0)
- panic("ufs_makedirentry: missing name");
+ if ((cnp->cn_flags & SAVENAME) == 0)
+ panic("direnter: missing name");
#endif
- newdirp->d_ino = ip->i_number;
- newdirp->d_namlen = cnp->cn_namelen;
- bcopy(cnp->cn_nameptr, newdirp->d_name, (unsigned)cnp->cn_namelen + 1);
- if (ITOV(ip)->v_mount->mnt_maxsymlinklen > 0)
- newdirp->d_type = IFTODT(ip->i_ffs_mode);
- else {
- newdirp->d_type = 0;
+ dp = VTOI(dvp);
+ newdir.d_ino = ip->i_number;
+ newdir.d_namlen = cnp->cn_namelen;
+ bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
+ if (dvp->v_mount->mnt_maxsymlinklen > 0)
+ newdir.d_type = IFTODT(ip->i_ffs_mode);
+ else {
+ newdir.d_type = 0;
# if (BYTE_ORDER == LITTLE_ENDIAN)
- { u_char tmp = newdirp->d_namlen;
- newdirp->d_namlen = newdirp->d_type;
- newdirp->d_type = tmp; }
+ { u_char tmp = newdir.d_namlen;
+ newdir.d_namlen = newdir.d_type;
+ newdir.d_type = tmp; }
# endif
- }
+ }
+ return (ufs_direnter2(dvp, &newdir, cnp->cn_cred, cnp->cn_proc));
}
-
+
/*
- * Write a directory entry after a call to namei, using the parameters
- * that it left in nameidata. The argument dirp is the new directory
- * entry contents. Dvp is a pointer to the directory to be written,
- * which was left locked by namei. Remaining parameters (dp->i_offset,
- * dp->i_count) indicate how the space for the new entry is to be obtained.
- * Non-null bp indicates that a directory is being created (for the
- * soft dependency code).
+ * Common entry point for directory entry removal used by ufs_direnter
+ * and ufs_whiteout
*/
int
-ufs_direnter(dvp, dirp, cnp, newdirbp)
- struct vnode *dvp;
- struct direct *dirp;
- struct componentname *cnp;
- struct buf *newdirbp;
+ufs_direnter2(dvp, dirp, cr, p)
+ struct vnode *dvp;
+ struct direct *dirp;
+ struct ucred *cr;
+ struct proc *p;
{
- struct ucred *cr;
- struct proc *p;
- int newentrysize;
- struct inode *dp;
- struct buf *bp;
- u_int dsize;
- struct direct *ep, *nep;
- int error, ret, blkoff, loc, spacefree, flags;
- char *dirbuf;
- struct timespec ts;
+ int newentrysize;
+ struct inode *dp;
+ struct buf *bp;
+ struct iovec aiov;
+ struct uio auio;
+ u_int dsize;
+ struct direct *ep, *nep;
+ int error, loc, spacefree;
+ char *dirbuf;
- error = 0;
- cr = cnp->cn_cred;
- p = cnp->cn_proc;
- dp = VTOI(dvp);
- newentrysize = DIRSIZ(FSFMT(dvp), dirp);
+ dp = VTOI(dvp);
+ newentrysize = DIRSIZ(FSFMT(dvp), dirp);
if (dp->i_count == 0) {
/*
* If dp->i_count is 0, then namei could find no
* space in the directory. Here, dp->i_offset will
* be on a directory block boundary and we will write the
- * new entry into a fresh block.
- */
- if (dp->i_offset & (DIRBLKSIZ - 1))
- panic("ufs_direnter: newblk");
- flags = B_CLRBUF;
- if (!DOINGSOFTDEP(dvp))
- flags |= B_SYNC;
- if ((error = VOP_BALLOC(dvp, (off_t)dp->i_offset, DIRBLKSIZ,
- cr, flags, &bp)) != 0) {
- if (DOINGSOFTDEP(dvp) && newdirbp != NULL)
- bdwrite(newdirbp);
- return (error);
+ * new entry into a fresh block.
+ */
+ if (dp->i_offset & (DIRBLKSIZ - 1))
+ panic("ufs_direnter2: newblk");
+ auio.uio_offset = dp->i_offset;
+ dirp->d_reclen = DIRBLKSIZ;
+ auio.uio_resid = newentrysize;
+ aiov.iov_len = newentrysize;
+ aiov.iov_base = (caddr_t)dirp;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_procp = (struct proc *)0;
+ error = VOP_WRITE(dvp, &auio, IO_SYNC, cr);
+ if (DIRBLKSIZ >
+ VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
+ /* XXX should grow with balloc() */
+ panic("ufs_direnter2: frag size");
+ else if (!error) {
+ dp->i_ffs_size = roundup(dp->i_ffs_size, DIRBLKSIZ);
+ dp->i_flag |= IN_CHANGE;
}
- dp->i_ffs_size = dp->i_offset + DIRBLKSIZ;
- dp->i_flag |= IN_CHANGE | IN_UPDATE;
- vnode_pager_setsize(dvp, (u_long)dp->i_ffs_size);
- dirp->d_reclen = DIRBLKSIZ;
- blkoff = dp->i_offset &
- (VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_iosize - 1);
- bcopy((caddr_t)dirp, (caddr_t)bp->b_data + blkoff,newentrysize);
- if (DOINGSOFTDEP(dvp)) {
- /*
- * Ensure that the entire newly allocated block is a
- * valid directory so that future growth within the
- * block does not have to ensure that the block is
- * written before the inode.
- */
- blkoff += DIRBLKSIZ;
- while (blkoff < bp->b_bcount) {
- ((struct direct *)
- (bp->b_data + blkoff))->d_reclen = DIRBLKSIZ;
- blkoff += DIRBLKSIZ;
- }
- softdep_setup_directory_add(bp, dp, dp->i_offset,
- dirp->d_ino, newdirbp);
- bdwrite(bp);
- } else {
- error = VOP_BWRITE(bp);
- }
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- ret = VOP_UPDATE(dvp, &ts, &ts, !DOINGSOFTDEP(dvp));
- if (error == 0)
- return (ret);
- return (error);
- }
-
- /*
- * If dp->i_count is non-zero, then namei found space for the new
- * entry in the range dp->i_offset to dp->i_offset + dp->i_count
- * in the directory. To use this space, we may have to compact
- * the entries located there, by copying them together towards the
- * beginning of the block, leaving the free space in one usable
- * chunk at the end.
- */
-
- /*
+ return (error);
+ }
+
+ /*
+ * If dp->i_count is non-zero, then namei found space
+ * for the new entry in the range dp->i_offset to
+ * dp->i_offset + dp->i_count in the directory.
+ * To use this space, we may have to compact the entries located
+ * there, by copying them together towards the beginning of the
+ * block, leaving the free space in one usable chunk at the end.
+ */
+
+ /*
* Increase size of directory if entry eats into new space.
* This should never push the size past a new multiple of
* DIRBLKSIZE.
@@ -816,17 +784,15 @@ ufs_direnter(dvp, dirp, cnp, newdirbp)
/*
* Get the block containing the space for the new directory entry.
*/
- if ((error = VOP_BLKATOFF(dvp, (off_t)dp->i_offset, &dirbuf, &bp))
- != 0) {
- if (DOINGSOFTDEP(dvp) && newdirbp != NULL)
- bdwrite(newdirbp);
- return (error);
- }
+ error = VOP_BLKATOFF(dvp, (off_t)dp->i_offset, &dirbuf, &bp);
+ if (error)
+ return (error);
/*
* Find space for the new entry. In the simple case, the entry at
* offset base will have the space. If it does not, then namei
* arranged that compacting the region dp->i_offset to
- * dp->i_offset + dp->i_count would yield the space.
+ * dp->i_offset + dp->i_count would yield the
+ * space.
*/
ep = (struct direct *)dirbuf;
dsize = DIRSIZ(FSFMT(dvp), ep);
@@ -844,11 +810,7 @@ ufs_direnter(dvp, dirp, cnp, newdirbp)
dsize = DIRSIZ(FSFMT(dvp), nep);
spacefree += nep->d_reclen - dsize;
loc += nep->d_reclen;
- if (DOINGSOFTDEP(dvp))
- softdep_change_directoryentry_offset(dp, dirbuf,
- (caddr_t)nep, (caddr_t)ep, dsize);
- else
- bcopy((caddr_t)nep, (caddr_t)ep, dsize);
+ bcopy((caddr_t)nep, (caddr_t)ep, dsize);
}
/*
* Update the pointer fields in the previous entry (if any),
@@ -858,26 +820,19 @@ ufs_direnter(dvp, dirp, cnp, newdirbp)
(ep->d_ino == WINO &&
bcmp(ep->d_name, dirp->d_name, dirp->d_namlen) == 0)) {
if (spacefree + dsize < newentrysize)
- panic("ufs_direnter: compact1");
+ panic("ufs_direnter2: compact1");
dirp->d_reclen = spacefree + dsize;
} else {
if (spacefree < newentrysize)
- panic("ufs_direnter: compact2");
+ panic("ufs_direnter2: compact2");
dirp->d_reclen = spacefree;
ep->d_reclen = dsize;
ep = (struct direct *)((char *)ep + dsize);
}
bcopy((caddr_t)dirp, (caddr_t)ep, (u_int)newentrysize);
-
- if (DOINGSOFTDEP(dvp)) {
- softdep_setup_directory_add(bp, dp,
- dp->i_offset + (caddr_t)ep - dirbuf, dirp->d_ino, newdirbp);
- bdwrite(bp);
- } else {
- error = VOP_BWRITE(bp);
- }
+ error = VOP_BWRITE(bp);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
- if (error == 0 && dp->i_endoff && dp->i_endoff < dp->i_ffs_size)
+ if (!error && dp->i_endoff && dp->i_endoff < dp->i_ffs_size)
error = VOP_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC, cr, p);
return (error);
}
@@ -895,20 +850,18 @@ ufs_direnter(dvp, dirp, cnp, newdirbp)
* to the size of the previous entry.
*/
int
-ufs_dirremove(dvp, ip, flags, isrmdir)
+ufs_dirremove(dvp, cnp)
struct vnode *dvp;
- struct inode *ip;
- int flags;
- int isrmdir;
+ struct componentname *cnp;
{
- struct inode *dp;
+ register struct inode *dp;
struct direct *ep;
struct buf *bp;
int error;
dp = VTOI(dvp);
- if (flags & DOWHITEOUT) {
+ if (cnp->cn_flags & DOWHITEOUT) {
/*
* Whiteout entry: set d_ino to WINO.
*/
@@ -918,39 +871,33 @@ ufs_dirremove(dvp, ip, flags, isrmdir)
return (error);
ep->d_ino = WINO;
ep->d_type = DT_WHT;
- goto out;
+ error = VOP_BWRITE(bp);
+ dp->i_flag |= IN_CHANGE | IN_UPDATE;
+ return (error);
}
- if ((error = VOP_BLKATOFF(dvp,
- (off_t)(dp->i_offset - dp->i_count), (char **)&ep, &bp)) != 0)
- return (error);
-
if (dp->i_count == 0) {
/*
* First entry in block: set d_ino to zero.
*/
+ error = VOP_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep,
+ &bp);
+ if (error)
+ return (error);
ep->d_ino = 0;
- } else {
- /*
- * Collapse new free space into previous entry.
- */
- ep->d_reclen += dp->i_reclen;
- }
-out:
- if (ip) {
- ip->i_effnlink--;
- ip->i_flag |= IN_CHANGE;
- }
- if (DOINGSOFTDEP(dvp)) {
- if (ip)
- softdep_setup_remove(bp, dp, ip, isrmdir);
- bdwrite(bp);
- } else {
- if (ip)
- ip->i_ffs_nlink--; /* XXX */
-
error = VOP_BWRITE(bp);
+ dp->i_flag |= IN_CHANGE | IN_UPDATE;
+ return (error);
}
+ /*
+ * Collapse new free space into previous entry.
+ */
+ error = VOP_BLKATOFF(dvp, (off_t)(dp->i_offset - dp->i_count),
+ (char **)&ep, &bp);
+ if (error)
+ return (error);
+ ep->d_reclen += dp->i_reclen;
+ error = VOP_BWRITE(bp);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
return (error);
}
@@ -961,11 +908,9 @@ out:
* set up by a call to namei.
*/
int
-ufs_dirrewrite(dp, oip, newinum, newtype, isrmdir)
- struct inode *dp, *oip;
- ino_t newinum;
- int newtype;
- int isrmdir;
+ufs_dirrewrite(dp, ip, cnp)
+ struct inode *dp, *ip;
+ struct componentname *cnp;
{
struct buf *bp;
struct direct *ep;
@@ -975,18 +920,10 @@ ufs_dirrewrite(dp, oip, newinum, newtype, isrmdir)
error = VOP_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp);
if (error)
return (error);
- ep->d_ino = newinum;
+ ep->d_ino = ip->i_number;
if (vdp->v_mount->mnt_maxsymlinklen > 0)
- ep->d_type = newtype;
- oip->i_effnlink--;
- oip->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(vdp)) {
- softdep_setup_directory_change(bp, dp, oip, newinum, isrmdir);
- bdwrite(bp);
- } else {
- oip->i_ffs_nlink--; /* XXX */
- error = VOP_BWRITE(bp);
- }
+ ep->d_type = IFTODT(ip->i_ffs_mode);
+ error = VOP_BWRITE(bp);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
return (error);
}
@@ -1046,7 +983,7 @@ ufs_dirempty(ip, parentino, cred)
* 1 implies ".", 2 implies ".." if second
* char is also "."
*/
- if (namlen == 1 && dp->d_ino == ip->i_number)
+ if (namlen == 1)
continue;
if (dp->d_name[1] == '.' && dp->d_ino == parentino)
continue;
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index bc295d57e26..9338ef1afcd 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_quota.c,v 1.4 1997/10/06 15:27:38 csapuntz Exp $ */
+/* $OpenBSD: ufs_quota.c,v 1.5 1997/10/06 20:21:48 deraadt Exp $ */
/* $NetBSD: ufs_quota.c,v 1.8 1996/02/09 22:36:09 christos Exp $ */
/*
@@ -376,11 +376,15 @@ quotaon(p, mp, type, fname)
if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0)
return (error);
vp = nd.ni_vp;
- VOP_UNLOCK(vp, 0, p);
+ VOP_UNLOCK(vp);
if (vp->v_type != VREG) {
(void) vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
return (EACCES);
}
+ if (vfs_busy(mp)) {
+ (void) vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
+ return (EBUSY);
+ }
if (*vpp != vp)
quotaoff(p, mp, type);
ump->um_qflags[type] |= QTF_OPENING;
@@ -410,9 +414,9 @@ quotaon(p, mp, type, fname)
again:
for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nextvp) {
nextvp = vp->v_mntvnodes.le_next;
- if (vp->v_type == VNON || vp->v_writecount == 0)
+ if (vp->v_writecount == 0)
continue;
- if (vget(vp, LK_EXCLUSIVE, p))
+ if (vget(vp, 1))
goto again;
if ((error = getinoquota(VTOI(vp))) != 0) {
vput(vp);
@@ -425,6 +429,7 @@ again:
ump->um_qflags[type] &= ~QTF_OPENING;
if (error)
quotaoff(p, mp, type);
+ vfs_unbusy(mp);
return (error);
}
@@ -444,6 +449,8 @@ quotaoff(p, mp, type)
register struct inode *ip;
int error;
+ if ((mp->mnt_flag & MNT_MPBUSY) == 0)
+ panic("quotaoff: not busy");
if ((qvp = ump->um_quotas[type]) == NULLVP)
return (0);
ump->um_qflags[type] |= QTF_CLOSING;
@@ -454,9 +461,7 @@ quotaoff(p, mp, type)
again:
for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nextvp) {
nextvp = vp->v_mntvnodes.le_next;
- if (vp->v_type == VNON)
- continue;
- if (vget(vp, LK_EXCLUSIVE, p))
+ if (vget(vp, 1))
goto again;
ip = VTOI(vp);
dq = ip->i_dquot[type];
@@ -616,16 +621,16 @@ qsync(mp)
struct mount *mp;
{
struct ufsmount *ump = VFSTOUFS(mp);
- struct proc *p = curproc;
register struct vnode *vp, *nextvp;
register struct dquot *dq;
register int i;
- int error = 0;
/*
* Check if the mount point has any quotas.
* If not, simply return.
*/
+ if ((mp->mnt_flag & MNT_MPBUSY) == 0)
+ panic("qsync: not busy");
for (i = 0; i < MAXQUOTAS; i++)
if (ump->um_quotas[i] != NULLVP)
break;
@@ -635,34 +640,22 @@ qsync(mp)
* Search vnodes associated with this mount point,
* synchronizing any modified dquot structures.
*/
- simple_lock(&mntvnode_slock);
again:
- for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nextvp) {
- if (vp->v_mount != mp)
- goto again;
- nextvp = vp->v_mntvnodes.le_next;
- if (vp->v_type == VNON)
+ for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nextvp) {
+ nextvp = vp->v_mntvnodes.le_next;
+ if (VOP_ISLOCKED(vp))
continue;
- simple_lock(&vp->v_interlock);
- simple_unlock(&mntvnode_slock);
- error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p);
- if (error) {
- simple_lock(&mntvnode_slock);
- if (error == ENOENT)
- goto again;
- continue;
- }
+ if (vget(vp, 1))
+ goto again;
for (i = 0; i < MAXQUOTAS; i++) {
dq = VTOI(vp)->i_dquot[i];
if (dq != NODQUOT && (dq->dq_flags & DQ_MOD))
dqsync(vp, dq);
}
vput(vp);
- simple_lock(&mntvnode_slock);
- if (vp->v_mntvnodes.le_next != nextvp)
- goto again;
- }
- simple_unlock(&mntvnode_slock);
+ if (vp->v_mntvnodes.le_next != nextvp || vp->v_mount != mp)
+ goto again;
+ }
return (0);
}
@@ -704,7 +697,6 @@ dqget(vp, id, ump, type, dqp)
register int type;
struct dquot **dqp;
{
- struct proc *p = curproc;
register struct dquot *dq;
struct dqhash *dqh;
register struct vnode *dqvp;
@@ -760,7 +752,7 @@ dqget(vp, id, ump, type, dqp)
* Initialize the contents of the dquot structure.
*/
if (vp != dqvp)
- vn_lock(dqvp, LK_EXCLUSIVE | LK_RETRY, p);
+ VOP_LOCK(dqvp);
LIST_INSERT_HEAD(dqh, dq, dq_hash);
DQREF(dq);
dq->dq_flags = DQ_LOCK;
@@ -780,7 +772,7 @@ dqget(vp, id, ump, type, dqp)
if (auio.uio_resid == sizeof(struct dqblk) && error == 0)
bzero((caddr_t)&dq->dq_dqb, sizeof(struct dqblk));
if (vp != dqvp)
- VOP_UNLOCK(dqvp, 0, p);
+ VOP_UNLOCK(dqvp);
if (dq->dq_flags & DQ_WANT)
wakeup((caddr_t)dq);
dq->dq_flags = 0;
@@ -852,7 +844,6 @@ dqsync(vp, dq)
struct vnode *vp;
register struct dquot *dq;
{
- struct proc *p = curproc;
struct vnode *dqvp;
struct iovec aiov;
struct uio auio;
@@ -865,13 +856,13 @@ dqsync(vp, dq)
if ((dqvp = dq->dq_ump->um_quotas[dq->dq_type]) == NULLVP)
panic("dqsync: file");
if (vp != dqvp)
- vn_lock(dqvp, LK_EXCLUSIVE | LK_RETRY, p);
+ VOP_LOCK(dqvp);
while (dq->dq_flags & DQ_LOCK) {
dq->dq_flags |= DQ_WANT;
sleep((caddr_t)dq, PINOD+2);
if ((dq->dq_flags & DQ_MOD) == 0) {
if (vp != dqvp)
- VOP_UNLOCK(dqvp, 0, p);
+ VOP_UNLOCK(dqvp);
return (0);
}
}
@@ -892,7 +883,7 @@ dqsync(vp, dq)
wakeup((caddr_t)dq);
dq->dq_flags &= ~(DQ_MOD|DQ_LOCK|DQ_WANT);
if (vp != dqvp)
- VOP_UNLOCK(dqvp, 0, p);
+ VOP_UNLOCK(dqvp);
return (error);
}
diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c
index 25148b78f61..8946393c20a 100644
--- a/sys/ufs/ufs/ufs_readwrite.c
+++ b/sys/ufs/ufs/ufs_readwrite.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_readwrite.c,v 1.10 1997/10/06 15:27:39 csapuntz Exp $ */
+/* $OpenBSD: ufs_readwrite.c,v 1.11 1997/10/06 20:21:48 deraadt Exp $ */
/* $NetBSD: ufs_readwrite.c,v 1.9 1996/05/11 18:27:57 mycroft Exp $ */
/*-
@@ -242,13 +242,19 @@ WRITE(v)
xfersize = fs->fs_bsize - blkoffset;
if (uio->uio_resid < xfersize)
xfersize = uio->uio_resid;
+#ifdef LFS_READWRITE
+ (void)lfs_check(vp, lbn);
+ error = lfs_balloc(vp, blkoffset, xfersize, lbn, &bp);
+#else
if (fs->fs_bsize > xfersize)
flags |= B_CLRBUF;
else
flags &= ~B_CLRBUF;
- if ((error = VOP_BALLOC(vp, uio->uio_offset, xfersize,
- ap->a_cred, flags, &bp)) != 0)
+ error = ffs_balloc(ip,
+ lbn, blkoffset + xfersize, ap->a_cred, &bp, flags);
+#endif
+ if (error)
break;
if (uio->uio_offset + xfersize > ip->i_ffs_size) {
ip->i_ffs_size = uio->uio_offset + xfersize;
diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c
index 11dfa3086c4..6ac4ceea5ab 100644
--- a/sys/ufs/ufs/ufs_vfsops.c
+++ b/sys/ufs/ufs/ufs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_vfsops.c,v 1.4 1997/10/06 15:27:39 csapuntz Exp $ */
+/* $OpenBSD: ufs_vfsops.c,v 1.5 1997/10/06 20:21:49 deraadt Exp $ */
/* $NetBSD: ufs_vfsops.c,v 1.4 1996/02/09 22:36:12 christos Exp $ */
/*
@@ -125,64 +125,39 @@ ufs_quotactl(mp, cmds, uid, arg, p)
if ((u_int)type >= MAXQUOTAS)
return (EINVAL);
- if (vfs_busy(mp, LK_NOWAIT, 0, p))
- return (0);
-
-
switch (cmd) {
case Q_QUOTAON:
- error = quotaon(p, mp, type, arg);
- break;
+ return (quotaon(p, mp, type, arg));
case Q_QUOTAOFF:
+ if (vfs_busy(mp))
+ return (0);
error = quotaoff(p, mp, type);
- break;
+ vfs_unbusy(mp);
+ return (error);
case Q_SETQUOTA:
- error = setquota(mp, uid, type, arg) ;
- break;
+ return (setquota(mp, uid, type, arg));
case Q_SETUSE:
- error = setuse(mp, uid, type, arg);
- break;
+ return (setuse(mp, uid, type, arg));
case Q_GETQUOTA:
- error = getquota(mp, uid, type, arg);
- break;
+ return (getquota(mp, uid, type, arg));
case Q_SYNC:
+ if (vfs_busy(mp))
+ return (0);
error = qsync(mp);
- break;
+ vfs_unbusy(mp);
+ return (error);
default:
- error = EINVAL;
- break;
+ return (EINVAL);
}
-
- vfs_unbusy(mp, p);
- return (error);
-#endif
-}
-
-
-/*
- * Initial UFS filesystems, done only once.
- */
-int
-ufs_init(vfsp)
- struct vfsconf *vfsp;
-{
- static int done;
-
- if (done)
- return (0);
- done = 1;
- ufs_ihashinit();
-#ifdef QUOTA
- dqinit();
+ /* NOTREACHED */
#endif
- return (0);
}
/*
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index fd5cb7961f4..4045a44bfe2 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_vnops.c,v 1.12 1997/10/06 19:37:27 kstailey Exp $ */
+/* $OpenBSD: ufs_vnops.c,v 1.13 1997/10/06 20:21:50 deraadt Exp $ */
/* $NetBSD: ufs_vnops.c,v 1.18 1996/05/11 18:28:04 mycroft Exp $ */
/*
@@ -90,19 +90,6 @@ union _qcvt {
(q) = tmp.qcvt; \
}
-
-/*
- * A virgin directory (no blushing please).
- */
-static struct dirtemplate mastertemplate = {
- 0, 12, DT_DIR, 1, ".",
- 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
-};
-static struct odirtemplate omastertemplate = {
- 0, 12, 1, ".",
- 0, DIRBLKSIZ - 12, 2, ".."
-};
-
/*
* Create a regular file
*/
@@ -130,19 +117,19 @@ ufs_mknod(v)
void *v;
{
struct vop_mknod_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap = v;
- struct vattr *vap = ap->a_vap;
- struct vnode **vpp = ap->a_vpp;
- struct inode *ip;
+ struct vnode *a_dvp;
+ struct vnode **a_vpp;
+ struct componentname *a_cnp;
+ struct vattr *a_vap;
+ } */ *ap = v;
+ register struct vattr *vap = ap->a_vap;
+ register struct vnode **vpp = ap->a_vpp;
+ register struct inode *ip;
int error;
if ((error =
- ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
- ap->a_dvp, vpp, ap->a_cnp)) != 0)
+ ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
+ ap->a_dvp, vpp, ap->a_cnp)) != 0)
return (error);
ip = VTOI(*vpp);
ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
@@ -176,11 +163,11 @@ ufs_open(v)
void *v;
{
struct vop_open_args /* {
- struct vnode *a_vp;
- int a_mode;
- struct ucred *a_cred;
- struct proc *a_p;
- } */ *ap = v;
+ struct vnode *a_vp;
+ int a_mode;
+ struct ucred *a_cred;
+ struct proc *a_p;
+ } */ *ap = v;
/*
* Files marked append-only must be opened for appending.
@@ -207,13 +194,11 @@ ufs_close(v)
struct ucred *a_cred;
struct proc *a_p;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
+ register struct vnode *vp = ap->a_vp;
+ register struct inode *ip = VTOI(vp);
- simple_lock(&vp->v_interlock);
- if (vp->v_usecount > 1)
+ if (vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED))
ITIMES(ip, &time, &time);
- simple_unlock(&vp->v_interlock);
return (0);
}
@@ -227,29 +212,25 @@ ufs_access(v)
struct ucred *a_cred;
struct proc *a_p;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
+ register struct vnode *vp = ap->a_vp;
+ register struct inode *ip = VTOI(vp);
mode_t mode = ap->a_mode;
- /*
- * Disallow write attempts on read-only file systems;
- * unless the file is a socket, fifo, or a block or
- * character device resident on the file system.
- */
- if (mode & VWRITE) {
- switch (vp->v_type) {
+#ifdef DIAGNOSTIC
+ if (!VOP_ISLOCKED(vp)) {
+ vprint("ufs_access: not locked", vp);
+ panic("ufs_access: not locked");
+ }
+#endif
#ifdef QUOTA
+ if (mode & VWRITE)
+ switch (vp->v_type) {
int error;
-#endif
case VDIR:
case VLNK:
case VREG:
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
-#ifdef QUOTA
if ((error = getinoquota(ip)) != 0)
return (error);
-#endif
break;
case VBAD:
case VBLK:
@@ -258,9 +239,8 @@ ufs_access(v)
case VFIFO:
case VNON:
break;
-
}
- }
+#endif
/* If immutable bit set, nobody gets to write it. */
if ((mode & VWRITE) && (ip->i_ffs_flags & IMMUTABLE))
@@ -281,9 +261,9 @@ ufs_getattr(v)
struct ucred *a_cred;
struct proc *a_p;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
- struct vattr *vap = ap->a_vap;
+ register struct vnode *vp = ap->a_vp;
+ register struct inode *ip = VTOI(vp);
+ register struct vattr *vap = ap->a_vap;
ITIMES(ip, &time, &time);
/*
@@ -292,7 +272,7 @@ ufs_getattr(v)
vap->va_fsid = ip->i_dev;
vap->va_fileid = ip->i_number;
vap->va_mode = ip->i_ffs_mode & ~IFMT;
- vap->va_nlink = ip->i_effnlink;
+ vap->va_nlink = ip->i_ffs_nlink;
vap->va_uid = ip->i_ffs_uid;
vap->va_gid = ip->i_ffs_gid;
vap->va_rdev = (dev_t)ip->i_ffs_rdev;
@@ -331,11 +311,11 @@ ufs_setattr(v)
struct ucred *a_cred;
struct proc *a_p;
} */ *ap = v;
- struct vattr *vap = ap->a_vap;
- struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
- struct ucred *cred = ap->a_cred;
- struct proc *p = ap->a_p;
+ register struct vattr *vap = ap->a_vap;
+ register struct vnode *vp = ap->a_vp;
+ register struct inode *ip = VTOI(vp);
+ register struct ucred *cred = ap->a_cred;
+ register struct proc *p = ap->a_p;
int error;
/*
@@ -348,8 +328,6 @@ ufs_setattr(v)
return (EINVAL);
}
if (vap->va_flags != VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
if (cred->cr_uid != ip->i_ffs_uid &&
(error = suser(cred, &p->p_acflag)))
return (error);
@@ -359,8 +337,7 @@ ufs_setattr(v)
return (EPERM);
ip->i_ffs_flags = vap->va_flags;
} else {
- if (ip->i_ffs_flags & (SF_IMMUTABLE | SF_APPEND) ||
- (vap->va_flags & UF_SETTABLE) != vap->va_flags)
+ if (ip->i_ffs_flags & (SF_IMMUTABLE | SF_APPEND))
return (EPERM);
ip->i_ffs_flags &= SF_SETTABLE;
ip->i_ffs_flags |= (vap->va_flags & UF_SETTABLE);
@@ -375,36 +352,19 @@ ufs_setattr(v)
* Go through the fields and update if not VNOVAL.
*/
if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p);
if (error)
return (error);
}
if (vap->va_size != VNOVAL) {
- /*
- * Disallow write attempts on read-only file systems;
- * unless the file is a socket, fifo, or a block or
- * character device resident on the file system.
- */
- switch (vp->v_type) {
- case VDIR:
- return (EISDIR);
- case VLNK:
- case VREG:
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- break;
- default:
- break;
- }
- if ((error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p)) != 0)
- return (error);
+ if (vp->v_type == VDIR)
+ return (EISDIR);
+ error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p);
+ if (error)
+ return (error);
}
ip = VTOI(vp);
if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
if (cred->cr_uid != ip->i_ffs_uid &&
(error = suser(cred, &p->p_acflag)) &&
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
@@ -414,16 +374,13 @@ ufs_setattr(v)
ip->i_flag |= IN_ACCESS;
if (vap->va_mtime.tv_sec != VNOVAL)
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- error = VOP_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 0);
+ error = VOP_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 1);
if (error)
return (error);
}
error = 0;
- if (vap->va_mode != (mode_t)VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
+ if (vap->va_mode != (mode_t)VNOVAL)
error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
- }
return (error);
}
@@ -433,12 +390,12 @@ ufs_setattr(v)
*/
static int
ufs_chmod(vp, mode, cred, p)
- struct vnode *vp;
- int mode;
- struct ucred *cred;
+ register struct vnode *vp;
+ register int mode;
+ register struct ucred *cred;
struct proc *p;
{
- struct inode *ip = VTOI(vp);
+ register struct inode *ip = VTOI(vp);
int error;
if (cred->cr_uid != ip->i_ffs_uid &&
@@ -464,18 +421,18 @@ ufs_chmod(vp, mode, cred, p)
*/
static int
ufs_chown(vp, uid, gid, cred, p)
- struct vnode *vp;
+ register struct vnode *vp;
uid_t uid;
gid_t gid;
struct ucred *cred;
struct proc *p;
{
- struct inode *ip = VTOI(vp);
+ register struct inode *ip = VTOI(vp);
uid_t ouid;
gid_t ogid;
int error = 0;
#ifdef QUOTA
- int i;
+ register int i;
long change;
#endif
@@ -657,9 +614,9 @@ ufs_remove(v)
struct vnode *a_vp;
struct componentname *a_cnp;
} */ *ap = v;
- struct inode *ip;
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
+ register struct inode *ip;
+ register struct vnode *vp = ap->a_vp;
+ register struct vnode *dvp = ap->a_dvp;
int error;
ip = VTOI(vp);
@@ -668,8 +625,10 @@ ufs_remove(v)
error = EPERM;
goto out;
}
- if ((error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0)) != 0)
- goto out;
+ if ((error = ufs_dirremove(dvp, ap->a_cnp)) == 0) {
+ ip->i_ffs_nlink--;
+ ip->i_flag |= IN_CHANGE;
+ }
out:
if (dvp == vp)
vrele(vp);
@@ -691,12 +650,10 @@ ufs_link(v)
struct vnode *a_vp;
struct componentname *a_cnp;
} */ *ap = v;
- struct vnode *dvp = ap->a_dvp;
- struct vnode *vp = ap->a_vp;
- struct componentname *cnp = ap->a_cnp;
- struct proc *p = cnp->cn_proc;
- struct inode *ip;
- struct direct newdir;
+ register struct vnode *dvp = ap->a_dvp;
+ register struct vnode *vp = ap->a_vp;
+ register struct componentname *cnp = ap->a_cnp;
+ register struct inode *ip;
struct timespec ts;
int error;
@@ -714,7 +671,7 @@ ufs_link(v)
error = EXDEV;
goto out2;
}
- if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE, p))) {
+ if (dvp != vp && (error = VOP_LOCK(vp))) {
VOP_ABORTOP(dvp, cnp);
goto out2;
}
@@ -729,25 +686,20 @@ ufs_link(v)
error = EPERM;
goto out1;
}
- ip->i_effnlink++;
ip->i_ffs_nlink++;
ip->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(vp))
- softdep_increase_linkcnt(ip);
TIMEVAL_TO_TIMESPEC(&time, &ts);
- if ((error = VOP_UPDATE(vp, &ts, &ts, !DOINGSOFTDEP(vp))) == 0) {
- ufs_makedirentry(ip, cnp, &newdir);
- error = ufs_direnter(dvp, &newdir, cnp, NULL);
- }
+ error = VOP_UPDATE(vp, &ts, &ts, 1);
+ if (!error)
+ error = ufs_direnter(ip, dvp, cnp);
if (error) {
- ip->i_effnlink--;
ip->i_ffs_nlink--;
ip->i_flag |= IN_CHANGE;
}
FREE(cnp->cn_pnbuf, M_NAMEI);
out1:
if (dvp != vp)
- VOP_UNLOCK(vp, 0, p);
+ VOP_UNLOCK(vp);
out2:
vput(dvp);
return (error);
@@ -790,7 +742,7 @@ ufs_whiteout(v)
newdir.d_namlen = cnp->cn_namelen;
bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
newdir.d_type = DT_WHT;
- error = ufs_direnter(dvp, &newdir, cnp, NULL);
+ error = ufs_direnter2(dvp, &newdir, cnp->cn_cred, cnp->cn_proc);
break;
case DELETE:
@@ -801,11 +753,8 @@ ufs_whiteout(v)
#endif
cnp->cn_flags &= ~DOWHITEOUT;
- error = ufs_dirremove(dvp, NULL, cnp->cn_flags, 0);
+ error = ufs_dirremove(dvp, cnp);
break;
- default:
- panic("ufs_whiteout: unknown op");
- /* NOTREACHED */
}
if (cnp->cn_flags & HASBUF) {
FREE(cnp->cn_pnbuf, M_NAMEI);
@@ -852,17 +801,17 @@ ufs_rename(v)
struct componentname *a_tcnp;
} */ *ap = v;
struct vnode *tvp = ap->a_tvp;
- struct vnode *tdvp = ap->a_tdvp;
+ register struct vnode *tdvp = ap->a_tdvp;
struct vnode *fvp = ap->a_fvp;
- struct vnode *fdvp = ap->a_fdvp;
- struct componentname *tcnp = ap->a_tcnp;
- struct componentname *fcnp = ap->a_fcnp;
- struct proc *p = fcnp->cn_proc;
- struct inode *ip, *xp, *dp;
- struct direct newdir;
+ register struct vnode *fdvp = ap->a_fdvp;
+ register struct componentname *tcnp = ap->a_tcnp;
+ register struct componentname *fcnp = ap->a_fcnp;
+ register struct inode *ip, *xp, *dp;
+ struct dirtemplate dirbuf;
struct timespec ts;
int doingdirectory = 0, oldparent = 0, newparent = 0;
int error = 0;
+ u_char namlen;
#ifdef DIAGNOSTIC
if ((tcnp->cn_flags & HASBUF) == 0 ||
@@ -919,13 +868,13 @@ abortit:
(void) relookup(fdvp, &fvp, fcnp);
return (VOP_REMOVE(fdvp, fvp, fcnp));
}
- if ((error = vn_lock(fvp, LK_EXCLUSIVE, p)) != 0)
+ if ((error = VOP_LOCK(fvp)) != 0)
goto abortit;
dp = VTOI(fdvp);
ip = VTOI(fvp);
if ((ip->i_ffs_flags & (IMMUTABLE | APPEND)) ||
(dp->i_ffs_flags & APPEND)) {
- VOP_UNLOCK(fvp, 0, p);
+ VOP_UNLOCK(fvp);
error = EPERM;
goto abortit;
}
@@ -934,7 +883,7 @@ abortit:
if (!error && tvp)
error = VOP_ACCESS(tvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
if (error) {
- VOP_UNLOCK(fvp, 0, p);
+ VOP_UNLOCK(fvp);
error = EACCES;
goto abortit;
}
@@ -946,7 +895,7 @@ abortit:
(fcnp->cn_flags & ISDOTDOT) ||
(tcnp->cn_flags & ISDOTDOT) ||
(ip->i_flag & IN_RENAME)) {
- VOP_UNLOCK(fvp, 0, p);
+ VOP_UNLOCK(fvp);
error = EINVAL;
goto abortit;
}
@@ -971,14 +920,11 @@ abortit:
* completing our work, the link count
* may be wrong, but correctable.
*/
- ip->i_effnlink++;
ip->i_ffs_nlink++;
ip->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(fvp))
- softdep_increase_linkcnt(ip);
TIMEVAL_TO_TIMESPEC(&time, &ts);
- if ((error = VOP_UPDATE(fvp, &ts, &ts, !DOINGSOFTDEP(fvp))) != 0) {
- VOP_UNLOCK(fvp, 0, p);
+ if ((error = VOP_UPDATE(fvp, &ts, &ts, 1)) != 0) {
+ VOP_UNLOCK(fvp);
goto bad;
}
@@ -993,7 +939,7 @@ abortit:
* call to checkpath().
*/
error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
- VOP_UNLOCK(fvp, 0, p);
+ VOP_UNLOCK(fvp);
if (oldparent != dp->i_number)
newparent = dp->i_number;
if (doingdirectory && newparent) {
@@ -1032,19 +978,13 @@ abortit:
error = EMLINK;
goto bad;
}
- dp->i_effnlink++;
dp->i_ffs_nlink++;
dp->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(tdvp))
- softdep_increase_linkcnt(dp);
- if ((error = VOP_UPDATE(tdvp, &ts, &ts,
- !DOINGSOFTDEP(tdvp))) != 0)
+ if ((error = VOP_UPDATE(tdvp, &ts, &ts, 1)) != 0)
goto bad;
}
- ufs_makedirentry(ip, tcnp, &newdir);
- if ((error = ufs_direnter(tdvp, &newdir, tcnp, NULL)) != 0) {
+ if ((error = ufs_direnter(ip, tdvp, tcnp)) != 0) {
if (doingdirectory && newparent) {
- dp->i_effnlink--;
dp->i_ffs_nlink--;
dp->i_flag |= IN_CHANGE;
(void)VOP_UPDATE(tdvp, &ts, &ts, 1);
@@ -1078,8 +1018,8 @@ abortit:
* (both directories, or both not directories).
*/
if ((xp->i_ffs_mode & IFMT) == IFDIR) {
- if (xp->i_effnlink > 2 ||
- !ufs_dirempty(xp, dp->i_number, tcnp->cn_cred)) {
+ if (!ufs_dirempty(xp, dp->i_number, tcnp->cn_cred) ||
+ xp->i_ffs_nlink > 2) {
error = ENOTEMPTY;
goto bad;
}
@@ -1092,35 +1032,37 @@ abortit:
error = EISDIR;
goto bad;
}
-
- if ((error = ufs_dirrewrite(dp, xp, ip->i_number,
- IFTODT(ip->i_ffs_mode), doingdirectory)) != 0)
- goto bad;
- if (doingdirectory) {
- dp->i_effnlink--;
+ if ((error = ufs_dirrewrite(dp, ip, tcnp)) != 0)
+ goto bad;
+ /*
+ * If the target directory is in the same
+ * directory as the source directory,
+ * decrement the link count on the parent
+ * of the target directory.
+ */
+ if (doingdirectory && !newparent) {
+ dp->i_ffs_nlink--;
dp->i_flag |= IN_CHANGE;
- xp->i_effnlink--;
- xp->i_flag |= IN_CHANGE;
}
- if (doingdirectory && !DOINGSOFTDEP(tvp)) {
- /*
- * Truncate inode. The only stuff left in the directory
- * is "." and "..". The "." reference is inconsequential
- * since we are quashing it. We have removed the "."
- * reference and the reference in the parent directory,
- * but there may be other hard links. The soft
- * dependency code will arrange to do these operations
- * after the parent directory entry has been deleted on
- * disk, so when running with that code we avoid doing
- * them now.
- */
- dp->i_ffs_nlink--;
- xp->i_ffs_nlink--;
- if ((error = VOP_TRUNCATE(tvp, (off_t)0, IO_SYNC,
- tcnp->cn_cred, tcnp->cn_proc)) != 0)
- goto bad;
- }
- vput(tdvp);
+ vput(tdvp);
+ /*
+ * Adjust the link count of the target to
+ * reflect the dirrewrite above. If this is
+ * a directory it is empty and there are
+ * no links to it, so we can squash the inode and
+ * any space associated with it. We disallowed
+ * renaming over top of a directory with links to
+ * it above, as the remaining link would point to
+ * a directory without "." or ".." entries.
+ */
+ xp->i_ffs_nlink--;
+ if (doingdirectory) {
+ if (--xp->i_ffs_nlink != 0)
+ panic("rename: linked directory");
+ error = VOP_TRUNCATE(tvp, (off_t)0, IO_SYNC,
+ tcnp->cn_cred, tcnp->cn_proc);
+ }
+ xp->i_flag |= IN_CHANGE;
vput(tvp);
xp = NULL;
}
@@ -1150,9 +1092,10 @@ abortit:
* changed while the new name has been entered. If the source is
* a file then the entry may have been unlinked or renamed. In
* either case there is no further work to be done. If the source
- * is a directory then it cannot have been rmdir'ed; the IN_RENAME
- * flag ensures that it cannot be moved by another rename or removed
- * by a rmdir.
+ * is a directory then it cannot have been rmdir'ed; its link
+ * count of three would cause a rmdir to fail with ENOTEMPTY.
+ * The IRENAME flag ensures that it cannot be moved by another
+ * rename.
*/
if (xp != ip) {
if (doingdirectory)
@@ -1165,11 +1108,44 @@ abortit:
* and ".." set to point to the new parent.
*/
if (doingdirectory && newparent) {
- xp->i_offset = mastertemplate.dot_reclen;
- ufs_dirrewrite(xp, dp, newparent, DT_DIR, 0);
- cache_purge(fdvp);
+ dp->i_ffs_nlink--;
+ dp->i_flag |= IN_CHANGE;
+ error = vn_rdwr(UIO_READ, fvp, (caddr_t)&dirbuf,
+ sizeof (struct dirtemplate), (off_t)0,
+ UIO_SYSSPACE, IO_NODELOCKED,
+ tcnp->cn_cred, (int *)0, (struct proc *)0);
+ if (error == 0) {
+# if (BYTE_ORDER == LITTLE_ENDIAN)
+ if (fvp->v_mount->mnt_maxsymlinklen <= 0)
+ namlen = dirbuf.dotdot_type;
+ else
+ namlen = dirbuf.dotdot_namlen;
+# else
+ namlen = dirbuf.dotdot_namlen;
+# endif
+ if (namlen != 2 ||
+ dirbuf.dotdot_name[0] != '.' ||
+ dirbuf.dotdot_name[1] != '.') {
+ ufs_dirbad(xp, (doff_t)12,
+ "rename: mangled dir");
+ } else {
+ dirbuf.dotdot_ino = newparent;
+ (void) vn_rdwr(UIO_WRITE, fvp,
+ (caddr_t)&dirbuf,
+ sizeof (struct dirtemplate),
+ (off_t)0, UIO_SYSSPACE,
+ IO_NODELOCKED|IO_SYNC,
+ tcnp->cn_cred, (int *)0,
+ (struct proc *)0);
+ cache_purge(fdvp);
+ }
+ }
+ }
+ error = ufs_dirremove(fdvp, fcnp);
+ if (!error) {
+ xp->i_ffs_nlink--;
+ xp->i_flag |= IN_CHANGE;
}
- error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0);
xp->i_flag &= ~IN_RENAME;
}
if (dp)
@@ -1186,8 +1162,7 @@ bad:
out:
if (doingdirectory)
ip->i_flag &= ~IN_RENAME;
- if (vn_lock(fvp, LK_EXCLUSIVE, p) == 0) {
- ip->i_effnlink--;
+ if (VOP_LOCK(fvp) == 0) {
ip->i_ffs_nlink--;
ip->i_flag |= IN_CHANGE;
vput(fvp);
@@ -1197,6 +1172,18 @@ out:
}
/*
+ * A virgin directory (no blushing please).
+ */
+static struct dirtemplate mastertemplate = {
+ 0, 12, DT_DIR, 1, ".",
+ 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
+};
+static struct odirtemplate omastertemplate = {
+ 0, 12, 1, ".",
+ 0, DIRBLKSIZ - 12, 2, ".."
+};
+
+/*
* Mkdir system call
*/
int
@@ -1209,13 +1196,11 @@ ufs_mkdir(v)
struct componentname *a_cnp;
struct vattr *a_vap;
} */ *ap = v;
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct componentname *cnp = ap->a_cnp;
- struct inode *ip, *dp;
+ register struct vnode *dvp = ap->a_dvp;
+ register struct vattr *vap = ap->a_vap;
+ register struct componentname *cnp = ap->a_cnp;
+ register struct inode *ip, *dp;
struct vnode *tvp;
- struct buf *bp;
- struct direct newdir;
struct dirtemplate dirtemplate, *dtp;
struct timespec ts;
int error, dmode;
@@ -1254,31 +1239,24 @@ ufs_mkdir(v)
ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
ip->i_ffs_mode = dmode;
tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */
- ip->i_effnlink = 2;
ip->i_ffs_nlink = 2;
- if (DOINGSOFTDEP(tvp))
- softdep_increase_linkcnt(ip);
-
if (cnp->cn_flags & ISWHITEOUT)
ip->i_ffs_flags |= UF_OPAQUE;
+ TIMEVAL_TO_TIMESPEC(&time, &ts);
+ error = VOP_UPDATE(tvp, &ts, &ts, 1);
/*
- * Bump link count in parent directory to reflect work done below.
- * Should be done before reference is create so cleanup is
- * possible if we crash.
+ * Bump link count in parent directory
+ * to reflect work done below. Should
+ * be done before reference is created
+ * so reparation is possible if we crash.
*/
- dp->i_effnlink++;
dp->i_ffs_nlink++;
dp->i_flag |= IN_CHANGE;
- if (DOINGSOFTDEP(dvp))
- softdep_increase_linkcnt(dp);
- TIMEVAL_TO_TIMESPEC(&time, &ts);
- if ((error = VOP_UPDATE(dvp, &ts, &ts, !DOINGSOFTDEP(dvp))) != 0)
+ if ((error = VOP_UPDATE(dvp, &ts, &ts, 1)) != 0)
goto bad;
- /*
- * Initialize directory with "." and ".." from static template.
- */
+ /* Initialize directory with "." and ".." from static template. */
if (dvp->v_mount->mnt_maxsymlinklen > 0)
dtp = &mastertemplate;
else
@@ -1286,56 +1264,40 @@ ufs_mkdir(v)
dirtemplate = *dtp;
dirtemplate.dot_ino = ip->i_number;
dirtemplate.dotdot_ino = dp->i_number;
-
- if ((error = VOP_BALLOC(tvp, (off_t)0, DIRBLKSIZ, cnp->cn_cred,
- B_CLRBUF, &bp)) != 0)
- goto bad;
- ip->i_ffs_size = DIRBLKSIZ;
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- vnode_pager_setsize(tvp, (u_long)ip->i_ffs_size);
- bcopy((caddr_t)&dirtemplate, (caddr_t)bp->b_data, sizeof dirtemplate);
- if ((error = VOP_UPDATE(tvp, &ts, &ts, !DOINGSOFTDEP(tvp))) != 0) {
- (void)VOP_BWRITE(bp);
+ error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
+ sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
+ IO_NODELOCKED|IO_SYNC, cnp->cn_cred, (int *)0, (struct proc *)0);
+ if (error) {
+ dp->i_ffs_nlink--;
+ dp->i_flag |= IN_CHANGE;
goto bad;
}
+ if (DIRBLKSIZ > VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
+ panic("ufs_mkdir: blksize"); /* XXX should grow with balloc() */
+ else {
+ ip->i_ffs_size = DIRBLKSIZ;
+ ip->i_flag |= IN_CHANGE;
+ }
+ /* Directory set up, now install it's entry in the parent directory. */
+ if ((error = ufs_direnter(ip, dvp, cnp)) != 0) {
+ dp->i_ffs_nlink--;
+ dp->i_flag |= IN_CHANGE;
+ }
+bad:
/*
- * Directory set up, now install it's entry in the parent directory.
- *
- * If we are not doing soft dependencies, then we must write out the
- * buffer containing the new directory body before entering the new
- * name in the parent. If we are doing soft dependencies, then the
- * buffer containing the new directory body will be passed to and
- * released in the soft dependency code after the code has attached
- * an appropriate ordering dependency to the buffer which ensures that
- * the buffer is written before the new name is written in the parent.
+ * No need to do an explicit VOP_TRUNCATE here, vrele will do this
+ * for us because we set the link count to 0.
*/
- if (!DOINGSOFTDEP(dvp) && ((error = VOP_BWRITE(bp)) != 0))
- goto bad;
- ufs_makedirentry(ip, cnp, &newdir);
- error = ufs_direnter(dvp, &newdir, cnp, bp);
-
-bad:
- if (error == 0) {
- *ap->a_vpp = tvp;
- } else {
- dp->i_effnlink--;
- dp->i_ffs_nlink--;
- dp->i_flag |= IN_CHANGE;
- /*
- * No need to do an explicit VOP_TRUNCATE here, vrele will
- * do this for us because we set the link count to 0.
- */
- ip->i_effnlink = 0;
- ip->i_ffs_nlink = 0;
- ip->i_flag |= IN_CHANGE;
-
+ if (error) {
+ ip->i_ffs_nlink = 0;
+ ip->i_flag |= IN_CHANGE;
vput(tvp);
- }
+ } else
+ *ap->a_vpp = tvp;
out:
FREE(cnp->cn_pnbuf, M_NAMEI);
vput(dvp);
-
return (error);
}
@@ -1351,10 +1313,10 @@ ufs_rmdir(v)
struct vnode *a_vp;
struct componentname *a_cnp;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
- struct componentname *cnp = ap->a_cnp;
- struct inode *ip, *dp;
+ register struct vnode *vp = ap->a_vp;
+ register struct vnode *dvp = ap->a_dvp;
+ register struct componentname *cnp = ap->a_cnp;
+ register struct inode *ip, *dp;
int error;
ip = VTOI(vp);
@@ -1368,17 +1330,14 @@ ufs_rmdir(v)
return (EINVAL);
}
/*
- * Do not remove a directory that is in the process of being renamed.
- * Verify the directory is empty (and valid). Rmdir ".." will not be
- * valid since ".." will contain a reference to the current directory
- * and thus be non-empty.
+ * Verify the directory is empty (and valid).
+ * (Rmdir ".." won't be valid since
+ * ".." will contain a reference to
+ * the current directory and thus be
+ * non-empty.)
*/
error = 0;
- if (ip->i_flag & IN_RENAME) {
- error = EINVAL;
- goto out;
- }
- if (ip->i_effnlink != 2 ||
+ if (ip->i_ffs_nlink != 2 ||
!ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
error = ENOTEMPTY;
goto out;
@@ -1393,33 +1352,31 @@ ufs_rmdir(v)
* inode. If we crash in between, the directory
* will be reattached to lost+found,
*/
- if ((error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1)) != 0)
+ if ((error = ufs_dirremove(dvp, cnp)) != 0)
goto out;
+ dp->i_ffs_nlink--;
+ dp->i_flag |= IN_CHANGE;
cache_purge(dvp);
- /*
- * Truncate inode. The only stuff left in the directory is "." and
- * "..". The "." reference is inconsequential since we are quashing
- * it. We have removed the "." reference and the reference in the
- * parent directory, but there may be other hard links. So,
- * ufs_dirremove will set the UF_IMMUTABLE flag to ensure that no
- * new entries are made. The soft dependency code will arrange to
- * do these operations after the parent directory entry has been
- * deleted on disk, so when running with that code we avoid doing
- * them now.
+ vput(dvp);
+ dvp = NULL;
+ /*
+ * Truncate inode. The only stuff left
+ * in the directory is "." and "..". The
+ * "." reference is inconsequential since
+ * we're quashing it. The ".." reference
+ * has already been adjusted above. We've
+ * removed the "." reference and the reference
+ * in the parent directory, but there may be
+ * other hard links so decrement by 2 and
+ * worry about them later.
*/
- dp->i_effnlink--;
- dp->i_flag |= IN_CHANGE;
- ip->i_effnlink--;
- ip->i_flag |= IN_CHANGE;
- if (!DOINGSOFTDEP(vp)) {
- dp->i_ffs_nlink--;
- ip->i_ffs_nlink--;
- error = VOP_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred,
- cnp->cn_proc);
- }
- cache_purge(vp);
+ ip->i_ffs_nlink -= 2;
+ error = VOP_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred,
+ cnp->cn_proc);
+ cache_purge(ITOV(ip));
out:
- vput(dvp);
+ if (dvp)
+ vput(dvp);
vput(vp);
return (error);
}
@@ -1438,8 +1395,8 @@ ufs_symlink(v)
struct vattr *a_vap;
char *a_target;
} */ *ap = v;
- struct vnode *vp, **vpp = ap->a_vpp;
- struct inode *ip;
+ register struct vnode *vp, **vpp = ap->a_vpp;
+ register struct inode *ip;
int len, error;
error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
@@ -1479,10 +1436,10 @@ ufs_readdir(v)
struct uio *a_uio;
struct ucred *a_cred;
int *a_eofflag;
- u_long **a_cookies;
- int *ncookies;
+ u_long *a_cookies;
+ int ncookies;
} */ *ap = v;
- struct uio *uio = ap->a_uio;
+ register struct uio *uio = ap->a_uio;
int error;
size_t count, lost;
off_t off = uio->uio_offset;
@@ -1538,10 +1495,9 @@ ufs_readdir(v)
error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
# endif
if (!error && ap->a_ncookies) {
- struct dirent *dp, *dpstart;
- off_t offstart;
- u_long *cookies;
- int ncookies;
+ register struct dirent *dp;
+ register u_long *cookies = ap->a_cookies;
+ register int ncookies = ap->a_ncookies;
/*
* Only the NFS server and emulations use cookies, and they
@@ -1550,28 +1506,17 @@ ufs_readdir(v)
*/
if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
panic("ufs_readdir: lost in space");
-
- dpstart = (struct dirent *)
- (uio->uio_iov->iov_base - (uio->uio_offset - off));
- offstart = off;
- for (dp = dpstart, ncookies = 0; off < uio->uio_offset; ) {
- if (dp->d_reclen == 0)
- break;
- off += dp->d_reclen;
- ncookies++;
- dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
- }
- lost += uio->uio_offset - off;
- uio->uio_offset = off;
- MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP,
- M_WAITOK);
- *ap->a_ncookies = ncookies;
- *ap->a_cookies = cookies;
- for (off = offstart, dp = dpstart; off < uio->uio_offset; ) {
- *(cookies++) = off;
+ dp = (struct dirent *)
+ (uio->uio_iov->iov_base - (uio->uio_offset - off));
+ while (ncookies-- && off < uio->uio_offset) {
+ if (dp->d_reclen == 0)
+ break;
off += dp->d_reclen;
- dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
+ *(cookies++) = off;
+ dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
}
+ lost += uio->uio_offset - off;
+ uio->uio_offset = off;
}
uio->uio_resid += lost;
*ap->a_eofflag = VTOI(ap->a_vp)->i_ffs_size <= uio->uio_offset;
@@ -1590,8 +1535,8 @@ ufs_readlink(v)
struct uio *a_uio;
struct ucred *a_cred;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
+ register struct vnode *vp = ap->a_vp;
+ register struct inode *ip = VTOI(vp);
int isize;
isize = ip->i_ffs_size;
@@ -1630,31 +1575,82 @@ ufs_lock(v)
{
struct vop_lock_args /* {
struct vnode *a_vp;
- int a_flags;
- sturct proc *a_p;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
+ register struct vnode *vp = ap->a_vp;
+ register struct inode *ip;
+#ifdef DIAGNOSTIC
+ struct proc *p = curproc; /* XXX */
+#endif
- return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock,
- ap->a_p));
+start:
+ while (vp->v_flag & VXLOCK) {
+ vp->v_flag |= VXWANT;
+ sleep((caddr_t)vp, PINOD);
+ }
+ if (vp->v_tag == VT_NON)
+ return (ENOENT);
+ ip = VTOI(vp);
+ if (ip->i_flag & IN_LOCKED) {
+ ip->i_flag |= IN_WANTED;
+#ifdef DIAGNOSTIC
+ if (p) {
+ if (p->p_pid == ip->i_lockholder)
+ panic("locking against myself");
+ ip->i_lockwaiter = p->p_pid;
+ } else
+ ip->i_lockwaiter = -1;
+#endif
+ (void) sleep((caddr_t)ip, PINOD);
+ goto start;
+ }
+#ifdef DIAGNOSTIC
+ ip->i_lockwaiter = 0;
+ if (ip->i_lockholder != 0)
+ panic("lockholder (%d) != 0", ip->i_lockholder);
+ if (p && p->p_pid == 0)
+ printf("locking by process 0\n");
+ if (p)
+ ip->i_lockholder = p->p_pid;
+ else
+ ip->i_lockholder = -1;
+#endif
+ ip->i_flag |= IN_LOCKED;
+ return (0);
}
/*
* Unlock an inode. If WANT bit is on, wakeup.
*/
+int lockcount = 90;
int
ufs_unlock(v)
void *v;
{
struct vop_unlock_args /* {
struct vnode *a_vp;
- int a_flags;
- struct proc *a_p;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
+ register struct inode *ip = VTOI(ap->a_vp);
+#ifdef DIAGNOSTIC
+ struct proc *p = curproc; /* XXX */
+#endif
- return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE,
- &vp->v_interlock, ap->a_p));
+#ifdef DIAGNOSTIC
+ if ((ip->i_flag & IN_LOCKED) == 0) {
+ vprint("ufs_unlock: unlocked inode", ap->a_vp);
+ panic("ufs_unlock NOT LOCKED");
+ }
+ if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 &&
+ ip->i_lockholder > -1 && lockcount++ < 100)
+ panic("unlocker (%d) != lock holder (%d)",
+ p->p_pid, ip->i_lockholder);
+ ip->i_lockholder = 0;
+#endif
+ ip->i_flag &= ~IN_LOCKED;
+ if (ip->i_flag & IN_WANTED) {
+ ip->i_flag &= ~IN_WANTED;
+ wakeup((caddr_t)ip);
+ }
+ return (0);
}
/*
@@ -1668,7 +1664,9 @@ ufs_islocked(v)
struct vnode *a_vp;
} */ *ap = v;
- return (lockstatus(&VTOI(ap->a_vp)->i_lock));
+ if (VTOI(ap->a_vp)->i_flag & IN_LOCKED)
+ return (1);
+ return (0);
}
/*
@@ -1682,9 +1680,9 @@ ufs_strategy(v)
struct vop_strategy_args /* {
struct buf *a_bp;
} */ *ap = v;
- struct buf *bp = ap->a_bp;
- struct vnode *vp = bp->b_vp;
- struct inode *ip;
+ register struct buf *bp = ap->a_bp;
+ register struct vnode *vp = bp->b_vp;
+ register struct inode *ip;
int error;
ip = VTOI(vp);
@@ -1722,8 +1720,8 @@ ufs_print(v)
struct vop_print_args /* {
struct vnode *a_vp;
} */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
+ register struct vnode *vp = ap->a_vp;
+ register struct inode *ip = VTOI(vp);
printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number,
major(ip->i_dev), minor(ip->i_dev));
@@ -1731,7 +1729,12 @@ ufs_print(v)
if (vp->v_type == VFIFO)
fifo_printinfo(vp);
#endif /* FIFO */
- lockmgr_printinfo(&ip->i_lock);
+ printf("%s\n", (ip->i_flag & IN_LOCKED) ? " (LOCKED)" : "");
+ if (ip->i_lockholder == 0)
+ return (0);
+ printf("\towner pid %d", ip->i_lockholder);
+ if (ip->i_lockwaiter)
+ printf(" waiting pid %d", ip->i_lockwaiter);
printf("\n");
return (0);
}
@@ -1793,12 +1796,10 @@ ufsspec_close(v)
struct ucred *a_cred;
struct proc *a_p;
} */ *ap = v;
- struct inode *ip = VTOI(ap->a_vp);
+ register struct inode *ip = VTOI(ap->a_vp);
- simple_lock(&vp->v_interlock);
- if (ap->a_vp->v_usecount > 1)
+ if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED))
ITIMES(ip, &time, &time);
- simple_unlock(&vp->v_interlock);
return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap));
}
@@ -1863,13 +1864,10 @@ ufsfifo_close(v)
struct proc *a_p;
} */ *ap = v;
extern int (**fifo_vnodeop_p) __P((void *));
- struct vnode *vp = ap->a_vp;
- struct inode *ip = VTOI(vp);
+ register struct inode *ip = VTOI(ap->a_vp);
- simple_lock(&vp->v_interlock);
- if (ap->a_vp->v_usecount > 1)
+ if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED))
ITIMES(ip, &time, &time);
- simple_unlock(&vp->v_interlock);
return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap));
}
#endif /* FIFO */
@@ -1926,7 +1924,7 @@ ufs_advlock(v)
struct flock *a_fl;
int a_flags;
} */ *ap = v;
- struct inode *ip = VTOI(ap->a_vp);
+ register struct inode *ip = VTOI(ap->a_vp);
return (lf_advlock(&ip->i_lockf, ip->i_ffs_size, ap->a_id, ap->a_op,
ap->a_fl, ap->a_flags));
@@ -1955,9 +1953,9 @@ ufs_vinit(mntp, specops, fifoops, vpp)
if ((nvp = checkalias(vp, ip->i_ffs_rdev, mntp)) != NULL) {
/*
* Discard unneeded vnode, but save its inode.
- * Note that the lock is carried over in the inode
- * to the replacement vnode.
*/
+ ufs_ihashrem(ip);
+ VOP_UNLOCK(vp);
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
@@ -1968,6 +1966,7 @@ ufs_vinit(mntp, specops, fifoops, vpp)
*/
vp = nvp;
ip->i_vnode = vp;
+ ufs_ihashins(ip);
}
break;
case VFIFO:
@@ -2006,8 +2005,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
struct vnode **vpp;
struct componentname *cnp;
{
- struct inode *ip, *pdir;
- struct direct newdir;
+ register struct inode *ip, *pdir;
struct timespec ts;
struct vnode *tvp;
int error;
@@ -2042,10 +2040,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
ip->i_ffs_mode = mode;
tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */
- ip->i_effnlink = 1;
ip->i_ffs_nlink = 1;
- if (DOINGSOFTDEP(tvp))
- softdep_increase_linkcnt(ip);
if ((ip->i_ffs_mode & ISGID) &&
!groupmember(ip->i_ffs_gid, cnp->cn_cred) &&
suser(cnp->cn_cred, NULL))
@@ -2058,13 +2053,10 @@ ufs_makeinode(mode, dvp, vpp, cnp)
* Make sure inode goes to disk before directory entry.
*/
TIMEVAL_TO_TIMESPEC(&time, &ts);
- if ((error = VOP_UPDATE(tvp, &ts, &ts, !DOINGSOFTDEP(tvp))) != 0)
+ if ((error = VOP_UPDATE(tvp, &ts, &ts, 1)) != 0)
goto bad;
-
- ufs_makedirentry(ip, cnp, &newdir);
- if ((error = ufs_direnter(dvp, &newdir, cnp, NULL)) != 0)
+ if ((error = ufs_direnter(ip, dvp, cnp)) != 0)
goto bad;
-
if ((cnp->cn_flags & SAVESTART) == 0)
FREE(cnp->cn_pnbuf, M_NAMEI);
vput(dvp);
@@ -2078,12 +2070,8 @@ bad:
*/
free(cnp->cn_pnbuf, M_NAMEI);
vput(dvp);
- ip->i_effnlink = 0;
ip->i_ffs_nlink = 0;
ip->i_flag |= IN_CHANGE;
vput(tvp);
-
return (error);
}
-
-