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