Re: strange mounting problem

Guest section DW (dwguest@win.tue.nl)
Tue, 21 Sep 1999 19:30:24 +0200 (MET DST)


From toa@pop.agri.ch Tue Sep 21 15:35:47 1999
From: Andreas Tobler <toa@pop.agri.ch>

Alan Cox wrote:
>
> > A short browse through the code I saw he's using generic (sg.h). He
> > distingushes between cdrom eject and scsi eject, as far as I can
> > understand. If there is a message sent to the kernel?? I have to look in.
>
> If he uses scsi generic he also needs to tell the kernel to revalidate that
> drive

I'm looking at it now. He uses the ioctl(SCSI_IOCTL_SEND_COMMAND,(void
*)&scsi_cmd) in case of NOT cdrom's. Is this just enough?

No - that is sending commands to a SCSI device, not telling things
to the kernel.

One would hope that things work well without additional action from
user space. When you do mount or open (in case the disk is removable)
the routine check_disk_change() is called, which calls
check_scsidisk_media_change(), and if the latter reports a change
we do invalidate_buffers() and invalidate_inodes().

So, either we must make sure that check_scsidisk_media_change()
sees a change, or we must force the invalidate_*() ourselves.

This routine check_scsidisk_media_change() does a SCSI_IOCTL_START_UNIT
and hopes to see UNIT ATTENTION or so. Reasonable enough.

In your case this fails.
You may check, just to be sure, that the kernel indeed sees
the disk as removable. (It will say so in the boot messages.)
Next, you may check in check_scsidisk_media_change() what
the return status is of this SCSI_IOCTL_START_UNIT command.
Just curiosity.

I seem to recall that you mentioned that this disk was SCSI-1
and that things are fine for SCSI-2 compliant drives.

Now that this fails in your case, apparently because it expects
SCSI-2 behaviour, one may try to force things.
The ioctl BLKRRPART will do revalidate_scsidisk() which does
the required invalidate_*().

So, you might try the (of course untested) eject program below.

Andries

/*
* Eject SCSI disk and invalidate buffers - aeb
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/fs.h> /* BLKRRPART */

#define SCSI_IOCTL_SEND_COMMAND 1
#define PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
#define START_STOP_UNIT 0x1b

main() {
char *device = "/dev/sdc";
int fd;
int i;

struct {
int inlen;
int outlen;
char cmd[256];
} scsi_cmd;

fd = open(device, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
fprintf(stderr, "cannot open %s\n", device);
exit(1);
}

memset(&scsi_cmd, 0, sizeof(scsi_cmd));
scsi_cmd.cmd[0] = PREVENT_ALLOW_MEDIUM_REMOVAL;
scsi_cmd.cmd[4] = 0; /* Allow */
i = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd);
if (i) {
perror("SCSI_IOCTL_SEND_COMMAND (0)");
exit(1);
}

memset(&scsi_cmd, 0, sizeof(scsi_cmd));
scsi_cmd.cmd[0] = START_STOP_UNIT;
scsi_cmd.cmd[4] = 2; /* Stop and Eject */
i = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd);
if (i) {
perror("SCSI_IOCTL_SEND_COMMAND (2)");
exit(1);
}

if(ioctl(fd, BLKRRPART)) {
perror("BLKRRPART");
exit(1);
}

return 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/