lkml.org 
[lkml]   [1999]   [Sep]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: strange mounting problem
        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/

    \
     
     \ /
      Last update: 2005-03-22 13:54    [W:2.976 / U:0.272 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site