Date: Sun, 20 Sep 1998 21:09:06 +0000 (GMT) From: Terry Lambert <tlambert@primenet.com> To: dag-erli@ifi.uio.no (Dag-Erling C. =?iso-8859-1?Q?Sm=F8rgrav?=) Cc: finrod@ewox.org, current@FreeBSD.ORG Subject: Re: Strange CAM panics [LONG] Message-ID: <199809202109.OAA01085@usr04.primenet.com> In-Reply-To: <xzp3e9mc2pn.fsf@gjallarhorn.ifi.uio.no> from "Dag-Erling C. =?iso-8859-1?Q?Sm=F8rgrav?=" at Sep 20, 98 03:51:00 pm
next in thread | previous in thread | raw e-mail | index | archive | help
> > The strange thing is that the panic always occurs in mountd, which I
> > wouldn't think was related.
>
> Update: I commented out the NFS configuration from my rc.conf.local
> (effectively disabling mountd). Everything works just fine.
>
> Needless to say, it used to work fine *with* NFS enabled before CAM.
> IIRC, the last time I mounted a CD-ROM was when I copied the entire
> 2.2.2-RELEASE CD-ROM to disk last Thursday (September 10th), a few
> days before my CAM conversion.
The mount code for any FS capable of being NFS exported will call the
vfs_export() function.
The real question here is whether your CDROM is on the list of FS's
you are exporting or not.
The current mount code does:
---------------------------------------------------------------------
vfs_mountrootfs:
allocate struct mount for new root
save "mounted from"
call FS_mount with NULL path
put FS in mountlist
end vfs_mountrootfs
mount:
get arguments
find vnode to be covered
compatability cruft
allocate struct mount
call FS_mount with path to device name
put FS in mountlist
end mount
FS_mount:
if path == NULL
// is root device
if SLICE
inherit rootvp from root_device_vnode
else
make up rootvp using bdevvp
endif
call FS_mountfs
else
// is non-root device
copy in arguments
if MNT_UPDATE
do cruft better implemented by unmount/mount
endif
look up device node
do weenie credential checks
if MNT_UPDATE
make sure it's the same guy...
save "mounted on" information
call vfs_export
else
save "last mounted on"
save "mounted from"
call FS_mountfs
endif
endif
call FS_statfs to set up the mount struct contents
end FS_mount
FS_mountfs:
call vfs_mountedon // is device busy? if yes, fail.
call vcount // is vnode busy? if ys, fail (BOGUS).
call vinvalbuf // flush cached device data (soft updates)
call vfs_object_create // enable vmio
demonstrate promiscuous knowledge of disklabel code
read the superblock
fill out in core copy of superblock & per FS mount structure
update superblock
end FS_mountfs
---------------------------------------------------------------------
Note the this code has to be repeated in each FS implementation, which
is what has led to the current problem: different implementations
result in different interactions with new code.
Corrected code would:
---------------------------------------------------------------------
vfs_mountany:
allocate struct mount
call vfs_mountedon // is device busy? if yes, fail.
call vcount // is vnode busy? if ys, fail (BOGUS).
call vinvalbuf // flush cached device data (soft updates)
call vfs_object_create // enable vmio
demonstrate promiscuous knowledge of disklabel code
call FS_mount
call FS_statfs to set up the mount struct contents
put FS in mountlist
return &struct mount
end vfs_mountany
vfs_mountrootfs:
call vfs_mountany with root device vnode, "mounted from", "/"
set root mount structure to point at struct mount from vfs_mountany
end vfs_mountrootfs
mount:
get arguments
look up device node
find vnode to be covered
do weenie credential checks
if MNT_UPDATE
make sure it's the same guy...
unmount
mount (recurse)
return
endif
call vfs_mountany with device node
call FS_setmntinfo with "mounted from", "last mounted on"
set covered vnode to point to vp from struct mount from vfs_mountany
call vfs_export
end mount
FS_mount:
read the superblock
fill out in core copy of superblock & per FS mount structure
update superblock
end FS_mount
---------------------------------------------------------------------
In other words, the concept of covering a vnode, what a root FS
actually is, whether it's an update, whether the FS is NFS exported,
and all of the other FS consumer specific crap should go into a
common code layer that gets written once, and is never touched
again.
Then things like the CAM problem you are currently having would
either effect *all* FS's (and get fixed) or *no* FS's (and not
be a problem).
It would also remove a significant amount of code duplication, and
immediately support root mounts of all supported FS types, including
ext2, etc..
Oh well...
In any case, your problem is in the code path that depends from
/sys/isofs/cd9660/cd9660_vfsops.c:
/*
* If updating, check whether changing from read-only to
* read/write; if there is no device name, that's all we do.
* Disallow clearing MNT_NOCLUSTERR flag, if block device requests.
*/
if (mp->mnt_flag & MNT_UPDATE) {
imp = VFSTOISOFS(mp);
if (bdevsw[major(imp->im_devvp->v_rdev)]->d_flags &
D_NOCLUSTERR)
mp->mnt_flag |= MNT_NOCLUSTERR;
if (args.fspec == 0)
return (vfs_export(mp, &imp->im_export, &args.export));
}
Which you will probably have to fix in an FS dependent way, so that it
works in the current framework (at least until the next time it breaks
for not being implemented the same in all FS's, and someone making a bad
assumption about what FS's depend upon and what they don't).
Terry Lambert
terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199809202109.OAA01085>
