Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/lfs Protect lfs_{bmapv, markv} with vfs_{un, }busy. F...
details: https://anonhg.NetBSD.org/src/rev/b16244084ee5
branches: trunk
changeset: 499563:b16244084ee5
user: perseant <perseant%NetBSD.org@localhost>
date: Wed Nov 22 22:11:34 2000 +0000
description:
Protect lfs_{bmapv,markv} with vfs_{un,}busy. Fix a reference/lock leak
in an error case in lfs_markv. Change the vfs_getvfs() error to return
ENOENT, for consistency with failure of vfs_busy().
99% of this patch was from Jesse Off <joff%gci-net.com@localhost> (PR #11547).
diffstat:
sys/ufs/lfs/lfs_syscalls.c | 49 +++++++++++++++++++++++++++++++++++++--------
1 files changed, 40 insertions(+), 9 deletions(-)
diffs (179 lines):
diff -r 63db0835c407 -r b16244084ee5 sys/ufs/lfs/lfs_syscalls.c
--- a/sys/ufs/lfs/lfs_syscalls.c Wed Nov 22 21:14:25 2000 +0000
+++ b/sys/ufs/lfs/lfs_syscalls.c Wed Nov 22 22:11:34 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_syscalls.c,v 1.52 2000/11/17 19:14:41 perseant Exp $ */
+/* $NetBSD: lfs_syscalls.c,v 1.53 2000/11/22 22:11:34 perseant Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -175,13 +175,14 @@
return (error);
if ((mntp = vfs_getvfs(&fsid)) == NULL)
- return (EINVAL);
+ return (ENOENT);
fs = VFSTOUFS(mntp)->um_lfs;
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
+
maxino = (dbtofsb(fs, VTOI(fs->lfs_ivnode)->i_ffs_blocks) -
fs->lfs_cleansz - fs->lfs_segtabsz) * fs->lfs_ifpb;
@@ -191,6 +192,9 @@
if (error)
goto err1;
+ if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
+ return (error);
+
/*
* This seglock is just to prevent the fact that we might have to sleep
* from allowing the possibility that our blocks might become
@@ -357,15 +361,15 @@
if (blkp->bi_lbn == LFS_UNUSED_LBN) {
/* XXX need to make sure that the inode gets written in this case */
/* XXX but only write the inode if it's the right one */
- if (blkp->bi_inode != LFS_IFILE_INUM) {
- LFS_IENTRY(ifp, fs, blkp->bi_inode, bp);
- if(ifp->if_daddr == blkp->bi_daddr
+ if (blkp->bi_inode != LFS_IFILE_INUM) {
+ LFS_IENTRY(ifp, fs, blkp->bi_inode, bp);
+ if(ifp->if_daddr == blkp->bi_daddr
|| blkp->bi_daddr == LFS_FORCE_WRITE)
{
LFS_SET_UINO(ip, IN_CLEANING);
}
- brelse(bp);
- }
+ brelse(bp);
+ }
continue;
}
@@ -472,6 +476,7 @@
}
#endif
+ vfs_unbusy(mntp);
if(error)
return (error);
else if(do_again)
@@ -481,7 +486,13 @@
err2:
printf("lfs_markv err2\n");
+ if(lfs_fastvget_unlock) {
+ VOP_UNLOCK(vp, 0);
+ --numlocked;
+ }
lfs_vunref(vp);
+ --numrefed;
+
/* Free up fakebuffers -- have to take these from the LOCKED list */
again:
s = splbio();
@@ -494,6 +505,8 @@
splx(s);
goto again;
}
+ if(bp->b_flags & B_DELWRI)
+ fs->lfs_avail += btodb(bp->b_bcount);
bremfree(bp);
splx(s);
brelse(bp);
@@ -503,6 +516,13 @@
splx(s);
free(start, M_SEGMENT);
lfs_segunlock(fs);
+ vfs_unbusy(mntp);
+#ifdef DEBUG_LFS
+ if(numlocked != 0 || numrefed != 0) {
+ panic("lfs_markv: numlocked=%d numrefed=%d", numlocked, numrefed);
+ }
+#endif
+
return (error);
err1:
@@ -557,15 +577,18 @@
if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
return (error);
if ((mntp = vfs_getvfs(&fsid)) == NULL)
- return (EINVAL);
+ return (ENOENT);
ump = VFSTOUFS(mntp);
+ if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
+ return (error);
origcnt = cnt = SCARG(uap, blkcnt);
start = malloc(cnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
error = copyin(SCARG(uap, blkiov), start, cnt * sizeof(BLOCK_INFO));
if (error) {
free(start, M_SEGMENT);
+ vfs_unbusy(mntp);
return (error);
}
@@ -583,6 +606,7 @@
printf("lfs_bmapv: attempt to clean current segment? (#%d)\n",
datosn(fs, fs->lfs_curseg));
free(start,M_SEGMENT);
+ vfs_unbusy(mntp);
return (EBUSY);
}
#endif /* DEBUG */
@@ -599,6 +623,7 @@
printf("lfs_bmapv: attempt to clean pending segment? (#%d)\n",
datosn(fs, fs->lfs_pending[j]));
free(start,M_SEGMENT);
+ vfs_unbusy(mntp);
return (EBUSY);
}
}
@@ -735,6 +760,7 @@
copyout(start, SCARG(uap, blkiov), origcnt * sizeof(BLOCK_INFO));
free(start, M_SEGMENT);
+ vfs_unbusy(mntp);
return 0;
}
@@ -771,20 +797,24 @@
if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
return (error);
if ((mntp = vfs_getvfs(&fsid)) == NULL)
- return (EINVAL);
+ return (ENOENT);
fs = VFSTOUFS(mntp)->um_lfs;
if (datosn(fs, fs->lfs_curseg) == SCARG(uap, segment))
return (EBUSY);
+ if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
+ return (error);
LFS_SEGENTRY(sup, fs, SCARG(uap, segment), bp);
if (sup->su_flags & SEGUSE_ACTIVE) {
brelse(bp);
+ vfs_unbusy(mntp);
return (EBUSY);
}
if (!(sup->su_flags & SEGUSE_DIRTY)) {
brelse(bp);
+ vfs_unbusy(mntp);
return (EALREADY);
}
@@ -808,6 +838,7 @@
cip->avail = fs->lfs_avail - fs->lfs_ravail;
(void) VOP_BWRITE(bp);
wakeup(&fs->lfs_avail);
+ vfs_unbusy(mntp);
return (0);
}
Home |
Main Index |
Thread Index |
Old Index