Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
145<br />
I/O Subsystem<br />
Close only for <strong>the</strong> last close of <strong>the</strong> device<br />
- kernel searches <strong>the</strong> file table to make sure that no o<strong>the</strong>r processes still have <strong>the</strong> device open<br />
- several process may access <strong>the</strong> device via different file table entry<br />
- several device files may specify <strong>the</strong> same device different inodes but same device<br />
- for block devices, kernel searches <strong>the</strong> mount table to make sure that <strong>the</strong> device does not contain a mounted file<br />
system<br />
- <strong>the</strong> kernel searches <strong>the</strong> buffer cache for blocks marked "delayed write" and writes <strong>the</strong>m before<br />
invoking <strong>the</strong> device close procedure.<br />
- kernel releases inode of <strong>the</strong> device file<br />
Kernel algorithms for read and write are similar to those of a regular file.<br />
The kernel can transmit data directly between address space and <strong>the</strong> device, or device drivers may buffer data<br />
internally e.g. terminal drivers use clist to buffer data.<br />
- memory mapped - status registers<br />
- programmed I/O - execute instructions<br />
- direct memory access (DMA) - used for bulk data transfer in parallel to CPU operations.<br />
- transfer data between device and user's address space faster (one less copy, no kernel buffers).<br />
! Strategy interface<br />
To transmit data between <strong>the</strong> buffer cache and a device. The process must be locked in memory until <strong>the</strong> I/O<br />
transfer is complete.<br />
! ioctl(fd, command, arg)<br />
Device specific<br />
! Interrupt handlers<br />
Many physical devices can be associated <strong>with</strong> one interrupt vector entry, <strong>the</strong> driver must be able to resolve which<br />
device caused <strong>the</strong> interrupt.<br />
Disk Drivers<br />
Partitioning <strong>the</strong> disk into sections, means that some<br />
sections can be read-only, some read-write, and some<br />
unmounted (no access)<br />
Section Name Start Length<br />
Block in Blocks<br />
0 0s0 0 64000<br />
1 0s1 64000 192000<br />
2 0s2 256000 256000<br />
3 0s3 0 512000<br />
Sections may overlap, but file systems must not.<br />
$ ls -1 Idev/dsk15 Idev/rdsk15<br />
br------- 2 root root 0,21 Feb 12 15:40<br />
/dev/dsk15<br />
crw-rw--- 2 root root 7,21 May 7 09:29<br />
/dev/rdsk15<br />
The kernel loops internally 4 times to read 4096 bytes<br />
Programs that read and write <strong>the</strong> disk directly can<br />
destroy <strong>the</strong> consistency of <strong>the</strong> file system data.<br />
Therefore "fsck" should not run on active file system.<br />
Figure 31. Reading Disk Data - block & raw interface<br />
#include "fcntl.h" #include <br />
main()<br />
{<br />
char buf1[4096], buf2[4096];<br />
int fdl, fd2, i;<br />
}<br />
if (((fdl =open("/dev/dsk5", O_RDONLY)) == -1) ||<br />
((fd2=open("/dev/rdsk5", O_RDONLY)) == -1))<br />
{<br />
printf("failure on open\n");<br />
exit();<br />
}<br />
lseek(fdl, 8192L, 0);<br />
lseek(fd2, 8l92L, 0);<br />
if ((read(fdl, bufl, sizeof(buf1)) == -1) ||<br />
(read(fd2, buf2, sizeof(buf2)) == -1))<br />
{<br />
printf("failure on read\n");<br />
exit(0);<br />
}<br />
for (i = 0; i < sizeof(buf1); i++)<br />
if (buf[I] != buf2[i])<br />
{<br />
printf("different at offset %d\n", i);<br />
exit(0);<br />
}<br />
printf("reads match\n");