Hello Driver List:

I am seeing some peculiar behavior when trying to fail accesses through the block device link. I was hoping y'all can help me understand what is going on. I've written a disk driver for a device that will enter a read only mode during certain error conditions. I'm testing the disk in this read only state and I see some writes returned successful which should be failed. I see correct behavior when the same writes are issued to the character device link (i.e. the writes return as failed). I have written a simple program which reproduces the issue. The program simply opens the device, and uses the read(2) and write(2) system calls to perform a 4K access. Interestingly enough when the read is removed from the program the write returns an error correctly! I have verified that bioerror(9F) is being called in my driver and that bioerror is setting the b_error field of the block IO structure on failed DMAs. Any explanation would be greatly appreciated.

Here are my test results (note that /dev/rdsk/c9d0p0 always exhibits correct behavior):

4K write:
% a.out /dev/rdsk/c9d0p0
write() returned -1 errno 6     <-- Correct
% a.out /dev/dsk/c9d0p0
write() returned -1 errno 6     <-- Correct

4K read followed by a 4K write:
% a.out /dev/rdsk/c9d0p0
read() returned 4096 errno 0
write() returned -1 errno 6     <-- Correct
% a.out /dev/dsk/c9d0p0
read() returned 4096 errno 0
write() returned 4096 errno 0   <-- Incorrect! This write should fail

4K write followed by a 4K read:
% a.out /dev/rdsk/c9d0p0
write() returned -1 errno 6
read() returned 4096 errno 0 <-- Correct
% a.out /dev/dsk/c9d0p0
write() returned -1 errno 6
read() returned -1 errno 6 <-- Incorrect! The read should return successful

And here is my test program:

#define BUF_SIZE 4096
int main(int argc, char **argv)
{
  int fd, st;
  char *buf;

  if (argc < 2)
  {
      printf("usage: %s <filename>\n", argv[0]);
      return 1;
  }

  buf = malloc(BUF_SIZE);
  if (!buf)
  {
      return 1;
  }

  memset(buf, 0, BUF_SIZE);

  fd = open(argv[1], O_RDWR | O_LARGEFILE | O_SYNC);
  if (fd < 0)
  {
      printf("Unable to open file %s (%d)\n", argv[1], errno);

      free(buf);
      return 1;
  }

  st = write(fd, buf, BUF_SIZE);
  printf("write() returned %d errno %d\n", st, errno);

  errno = 0;

  st = read(fd, buf, BUF_SIZE);
  printf("read() returned %d errno %d\n", st, errno);

  close(fd);
  free(buf);

  return 0;
}

Thank you,
Josh Morris
[email protected]


CONFIDENTIALITY NOTICE: This email and any attachments are Texas Memory Systems' proprietary material for the exclusive and confidential use of the intended recipient. If you are not the intended recipient, please do not read, distribute or take action in reliance upon this message. Any unauthorized disclosure is prohibited. If you have received this in error, please notify us immediately by return email and promptly delete all copies of this message and its attachments from your computer system.
_______________________________________________
driver-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/driver-discuss

Reply via email to