Subject: Re: kern/10231: panic in soft dependence code
To: Matthias Scheler <tron@lyssa.zhadum.de>
From: Charles M. Hannum <root@ihack.net>
List: current-users
Date: 05/30/2000 12:27:19
I believe this bug is now fixed. Let me know whether or not you get
more panics with the following patch.
Index: gnu/sys/ufs/ffs/ffs_softdep.c
===================================================================
RCS file: /cvsroot/gnusrc/gnu/sys/ufs/ffs/ffs_softdep.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -c -2 -r1.10 -r1.11
*** ffs_softdep.c 2000/05/27 06:51:30 1.10
--- ffs_softdep.c 2000/05/30 17:26:08 1.11
***************
*** 1,3 ****
! /* $NetBSD: ffs_softdep.c,v 1.10 2000/05/27 06:51:30 thorpej Exp $ */
/*
--- 1,3 ----
! /* $NetBSD: ffs_softdep.c,v 1.11 2000/05/30 17:26:08 mycroft Exp $ */
/*
***************
*** 3897,3900 ****
--- 3897,3901 ----
} */ *ap = v;
struct vnode *vp = ap->a_vp;
+ struct inodedep *inodedep;
struct pagedep *pagedep;
struct allocdirect *adp;
***************
*** 3943,3950 ****
waitfor = MNT_NOWAIT;
top:
! if (getdirtybuf(&vp->v_dirtyblkhd.lh_first, MNT_WAIT) == 0) {
! FREE_LOCK(&lk);
! return (0);
! }
bp = vp->v_dirtyblkhd.lh_first;
loop:
--- 3944,3949 ----
waitfor = MNT_NOWAIT;
top:
! if (getdirtybuf(&vp->v_dirtyblkhd.lh_first, MNT_WAIT) == 0)
! goto clean;
bp = vp->v_dirtyblkhd.lh_first;
loop:
***************
*** 4121,4141 ****
* devices, we may need to do further work.
*/
! if (vp->v_dirtyblkhd.lh_first == NULL) {
FREE_LOCK(&lk);
! return (0);
}
! FREE_LOCK(&lk);
/*
! * If we are trying to sync a block device, some of its buffers may
! * contain metadata that cannot be written until the contents of some
! * partially written files have been written to disk. The only easy
! * way to accomplish this is to sync the entire filesystem (luckily
! * this happens rarely).
! */
! if (vp->v_type == VBLK && vp->v_specmountpoint && !VOP_ISLOCKED(vp) &&
! (error = VFS_SYNC(vp->v_specmountpoint, MNT_WAIT, ap->a_cred,
! ap->a_p)) != 0)
! return (error);
return (0);
}
--- 4120,4150 ----
* devices, we may need to do further work.
*/
! if (vp->v_dirtyblkhd.lh_first != NULL) {
FREE_LOCK(&lk);
! /*
! * If we are trying to sync a block device, some of its buffers
! * may contain metadata that cannot be written until the
! * contents of some partially written files have been written
! * to disk. The only easy way to accomplish this is to sync the
! * entire filesystem (luckily this happens rarely).
! */
! if (vp->v_type == VBLK && vp->v_specmountpoint &&
! !VOP_ISLOCKED(vp) &&
! (error = VFS_SYNC(vp->v_specmountpoint, MNT_WAIT,
! ap->a_cred, ap->a_p)) != 0)
! return (error);
! ACQUIRE_LOCK(&lk);
}
! clean:
/*
! * If there is still an inodedep, we know that the inode has pending
! * modifications, and we must force it to be flushed to disk. We do
! * this by explicitly setting IN_MODIFIED so that ffs_update() will
! * see it.
! */
! if (inodedep_lookup(VTOI(vp)->i_fs, VTOI(vp)->i_number, 0, &inodedep))
! VTOI(vp)->i_flag |= IN_MODIFIED;
! FREE_LOCK(&lk);
return (0);
}
Index: sys/ufs/ffs/ffs_inode.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ffs/ffs_inode.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -c -2 -r1.34 -r1.35
*** ffs_inode.c 2000/05/29 18:04:30 1.34
--- ffs_inode.c 2000/05/30 17:23:52 1.35
***************
*** 1,3 ****
! /* $NetBSD: ffs_inode.c,v 1.34 2000/05/29 18:04:30 mycroft Exp $ */
/*
--- 1,3 ----
! /* $NetBSD: ffs_inode.c,v 1.35 2000/05/30 17:23:52 mycroft Exp $ */
/*
***************
*** 108,117 ****
if (flags == 0)
return (0);
- ip->i_flag &= ~flags;
fs = ip->i_fs;
! waitfor = ap->a_flags & UPDATE_WAIT;
! if ((ap->a_flags & UPDATE_DIROP) && !DOINGSOFTDEP(ap->a_vp))
! waitfor |= UPDATE_WAIT;
/*
--- 108,120 ----
if (flags == 0)
return (0);
fs = ip->i_fs;
! if ((flags & IN_MODIFIED) != 0 &&
! (ap->a_vp->v_mount->mnt_flag & MNT_ASYNC) == 0) {
! waitfor = ap->a_flags & UPDATE_WAIT;
! if ((ap->a_flags & UPDATE_DIROP) && !DOINGSOFTDEP(ap->a_vp))
! waitfor |= UPDATE_WAIT;
! } else
! waitfor = 0;
/*
***************
*** 130,133 ****
--- 133,137 ----
return (error);
}
+ ip->i_flag &= ~(IN_MODIFIED | IN_ACCESSED);
if (DOINGSOFTDEP(ap->a_vp))
softdep_update_inodeblock(ip, bp, waitfor);
***************
*** 142,147 ****
#endif
memcpy(cp, &ip->i_din.ffs_din, DINODE_SIZE);
! if (waitfor && (flags & IN_MODIFIED) != 0 &&
! (ap->a_vp->v_mount->mnt_flag & MNT_ASYNC) == 0) {
return (bwrite(bp));
} else {
--- 146,150 ----
#endif
memcpy(cp, &ip->i_din.ffs_din, DINODE_SIZE);
! if (waitfor) {
return (bwrite(bp));
} else {