[comp.os.minix] Fix for hard disk ram image feature

kjt@minnow.UUCP (Kevin Thomas) (09/21/87)

There is a small bug in the enhancement of the Minix FS to be able to load
the ram disk off a hard disk partition in the case that the diskette in the
BOOT_DEV drive is not a valid Minix file system.  This enhancement was
distributed by Dr. Tanenbaum as a pre-Minix 1.3 enhancement to Minix 1.2
awhile ago.

The problem involves mounting a diskette immediately after the system is
booted from a hard disk partition.  During system boot, the diskette in
the BOOT_DEV is the boot image itself.  Therefore, when the super block
is read it is invalid and FS proceeds to attempt to read the RAM resident
root file system from the RAM_IMAGE hard disk partition.  All of this
activity takes place in function load_ram() of file main.c of FS.

Since blocks read from devices such as disks are cached in an FS buffering
scheme, the invalid super block read from the diskette is kept in a
buffer.  If that buffer is still in the buffer pool when a mount is
attempted of that same device, then the buffered (invalid) super block
is used by function do_mount() of file mount.c of FS.  Therefore the
mount request is rejected.

The fix to this problem is much simpler than the explanation.  Call
function put_block() before reading the hard disk partition super block
in load_ram() so that the buffer containing the invalid super block
is reused and overwritten.

This condition does not occur when a regular mount() system call is done
to an invalid file system because function do_mount() in file mount.c
of FS calls rw_super() rather than get_block() to read the super block,
and rw_super() always calls put_block().  This brings up an interesting
question (for which I do not know the answer):  Why doesn't load_ram()
call rw_super() (i.e. access the super block the normal way, through
super.c) instead of doing an end-run and directly calling get_block()?

This fix also corrects another problem concerning the mount() system
call.  If mount() is called after a hard disk partition boot and after
one forces a re-read of the diskette super block (e.g. with od /dev/fd0,
for instance) it returns with ENFILE (no free super block buffers
available).  This error only occurs once; a second mount() call will
find a super block buffer!  This appears to be a problem with function
load_bit_maps() in file super.c of FS:  load_bit_maps() errors because
not enough buffers are available.  This causes do_mount() to call function
invalidate() in file cache.c of FS which frees up a bunch of buffers
because it invalidates all buffers allocated to the mount device.

The upshot of all this is that the following is a diff which can be applied
with fix to main.c of FS to correct this problem.  This fix assumes that
you have a Minix 1.2 main.c file with the 1.3 enhancements which Dr.
Tanenbaum distributed.

249a250
> 	put_block(bp, ZUPER_BLOCK); /* free up buffer for reuse */
-- 
Kevin Thomas               UUCP: ...!amdahl!ems!minnow!kjt
Unisys Corporation               ...!ihnp4!meccts!ems!minnow!kjt
Phone: +1 612 635 6042    CSNET: kjt@minnow.SP.Unisys.Com