kern/118322: [panic] Sometimes (seldom), "panic:page fault" happens after KDE automount occur when I insert CD/DVD

Kostik Belousov kostikbel at gmail.com
Fri Dec 28 10:56:02 PST 2007


On Wed, Dec 26, 2007 at 08:28:12PM +0200, Andriy Gapon wrote:
> 
> http://www.freebsd.org/cgi/query-pr.cgi?pr=118322
> 
> This panic looks like dereferencing a NULL pointer to a structure:
> > fault virtual address = 0x2c
> 44 is exactly an offset of 'perm' field in file_entry structure and
> fentry is a field of 'struct file_entry *' type in udf_node structure.
> 
> >From the code it seems that fentry field can not be NULL during "normal"
> life-cycle of udf_node. Memory allocation is properly checked for errors.

Yes, allocations are checked, but look at the series of the if()s after
the partially constructed vnode is put onto the hash. In the case any
of the if() fail, the vnode is simply vput()ed. This leaves the vnode
allocated and on the hash etc, while the unode->fentry is NULL. There,
the vnode can be found by the namei, that I believe causes the panic.

The difference between UFS and UDF code there is the ufs_inactive()
routine that is defined for UFS, and that reclaims the vnode when it is
in half-baked state.

Please, try the patch below (only compile-tested).

Note: it seems that the system shall say something before the
panic (see the printf()s before the vput() in the code).


diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c
index d08226b..373ee4d 100644
--- a/sys/fs/udf/udf_vfsops.c
+++ b/sys/fs/udf/udf_vfsops.c
@@ -630,6 +630,7 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
 	devvp = udfmp->im_devvp;
 	if ((error = RDSECTOR(devvp, sector, udfmp->bsize, &bp)) != 0) {
 		printf("Cannot read sector %d\n", sector);
+		vgone(vp);
 		vput(vp);
 		brelse(bp);
 		*vpp = NULL;
@@ -639,6 +640,7 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
 	fe = (struct file_entry *)bp->b_data;
 	if (udf_checktag(&fe->tag, TAGID_FENTRY)) {
 		printf("Invalid file entry!\n");
+		vgone(vp);
 		vput(vp);
 		brelse(bp);
 		*vpp = NULL;
@@ -649,6 +651,7 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
 	    M_NOWAIT | M_ZERO);
 	if (unode->fentry == NULL) {
 		printf("Cannot allocate file entry block\n");
+		vgone(vp);
 		vput(vp);
 		brelse(bp);
 		*vpp = NULL;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-fs/attachments/20071228/8405385d/attachment.pgp


More information about the freebsd-fs mailing list