What happens when you open and read a file: Basic system calls: . open . read . close . lseek . create . write ----------------------------------------------------------------------- The open-read-close cycle: 1. the process calls open("DATA.test", RD_ONLY); 2. the kernel: . get current working directory of the process; let's say "/p/course/cs537-2/public/project3" . call "namei": get the inode for the root directory "/"; for (each component in the path) { can we open and read the directory file? if no, open request failed, return error; if yes, read the blocks in the directory file ^^^^ based on the information from the i-node; read through the directory file to find the i-node for the next component; } at the end of the loop, we have the i-node for the file DATA.test; . find an empty slot "fd" in the file descriptor table for the process; . put the pointer to the i-node in the slot "fd"; . set the file pointer in the slot "fd" to 0; . return fd; 3. the process calls read(fd, buffer, length); 4. the kernel: . from "fd" find the file pointer; . based on the file system block size (let's say 4096), find the blocks where the bytes (file_pointer, file_pointer+length) lies; . read the i-node; ^^^^ for (each block) { . if the block no is <12, find the disk address of the block in the entries in the i-node; . if the block no is >12, but < 12 + (4096/4): . read the "single indirect" block; . index into the "single indirect" block to find the address of the block; . if the block no is > 12 + 1024, but < 12+ 1024 + 1024*1024, . read the "double indirect" block; . find the (block_no - 12 - 1024)/1024 'th entry in the block; . read the index block pointed by the entry; . index into the block at (block_no - 12 - 1024) % 1024; . that's the address for the block! . if the block no is still bigger: . go through the similar process through triple indirect block; . find the block's address; read the block from the disk; ^^^^ copy the bytes in the block to the appropriate location in buffer; } 5. the process calls close(fd); 6. the kernel: deallocate the fd entry: that is, mark it as empty; ---------------------------------------------------------------------- lseek: 1. the process calls lseek(fd, new_location); 2. the kernel: . from fd find the entry in the file descriptor table; . change the file pointer there to new_location; ----------------------------------------------------------------------- the create-write-close cycle: 1. the process calls create("project3.report"); 2. the kernel: . get current working directory of the process; let's say "/p/course/cs537-2/handin/project3" . call namei and see if a file name "project3.report" already exists in that directory; . if yes, return error "file already exists"; . if no: . allocate a new i-node; ^^^^^^^^^^^^^^^^^^^^^ . write the directory file "/p/course/cs537-2/handin/project3" to add a new entry for the ("project3.report", disk address of i-node) pair; . find an empty slot "fd" in the file descriptor table for the process; . put the pointer to the i-node in the slot "fd"; . set the file pointer in the slot "fd" to 0; . return fd; 3. the process calls write(fd, buffer, length); 4. the kernel: . from "fd" find the file pointer; . based on the file system block size (let's say 4096), find the blocks where the bytes (file_pointer, file_pointer+length) lies; for (each file block) { . if the block is new, allocate a new disk block; ^^^^^^^^^^^^^^^^^^^^^^^^^ . based on the block no, enter the block's address to the appropriate places in the i-node or the indirect blocks; (the indirect blocks are allocated as needed); . copy the bytes in buffer to the appropriate location in the block; } . change the file size field in i-node if necessary; 5. the process calls close(fd); 6. the kernel: deallocate the fd entry: that is, mark it as empty;