200 likes | 394 Views
CS6223: Distributed Systems. Unix File Systems. memory. disk. file. buf. } n bytes. File Systems. File system provides the most fundamental service for building any information systems. file storage, management and retrieve service. We look at two file operations:
E N D
CS6223: Distributed Systems Unix File Systems
memory disk file buf }n bytes File Systems • File system provides the most fundamental service for building any information systems. • file storage, management and retrieve service. We look at two file operations: fp = open (“cs4274/exam”, r, 0); r = read (fp, n, buf);
Hard disk Structure • File system at its low-end requests Hard Disk Controller (HDC) to access data in hard disk via BIOS (basic input/output service) interface with interrupt 13H. • The BIOS disk commands include “read sectors”, “write sectors”, “format cylinder”, etc. It accesses disk data in the unit of “sectors”. • The BIOS addresses a disk sector by head, cylinder, and sector numbers: • void read_sectors(hd, cyld, sect, buf) { • inregs.h.ah=0x42; // read cmdinregs.h.dl=0x80; // Drive Number • …….. // mv hd, cyld, sect, buf to inregs • /* Call Interrupt. */int86x(0x13,&inregs,&outregs,&segregs); • // Data & status are in outregs when returns fr interrupt • }
Data Block and Block Number • File system uses block as a data unit for disk operation • Usually a block size is 1K (>= sector size) • Disk block is referenced by its block number (blk_num) • Given a blk_num, it is easy to calculate cyld_num, head_num, sect_num: sectors = blk_num (#sects-per-blk) cyld_num = sectors (#sects-per-cyld) head_num =(sectors mod (#sects-per-cyld)) (#sects-per-track) sect_num = sectors mod (#sects-per-track) 0 3 4 5 232 1 2 ●●●●●●●●●●●●
Internal File Structure • Each file has an i-node: file attributes and data index: File attributes: • owner, access permissions, access times, file size • 12 bytes Data index: • 13 indices: 10 direct indices, 1 indirect index, 1 double indirect index, 1 triple indirect index • 13 * 4 =52 bytes • The size of an inode = 64 bytes. • An inode is referenced by its inode #
Diagram of data index in inode 52bytes attrs 12bytes
Unix Directory File • Directory files are ordinary files consisting of entries mapping names to i-node #, e.g., directory file /etc • After BSD4.3, file names are of variable length (upto 255 bytes). Each entry has the entry-length, name & inode #.
Directory structure and pathname resolution • Directories are in a tree structure. • Resolve pathname recursively to i-node number, component by component from the root (or relative) directory, e.g. /home/lec/jia/unix-fs.doc a) Starting from inode # 3 of “/”, load inode of “/” b) Read content of directory file “/”: 1368 bin@ 1478 lib/ 233756 rpool/ 2484 boot/ 1486 mnt/ 1489 sbin/ 1369 dev/ 154559 net/ 1494 system/ 2818 devices/ 6 export/ 2429 platform/ 5 var/ 27376 home/ …………………. c) Map “home” inode # 27376 and load inode 27376 d) Read directory file “/home”: 94171 bsft08/ 93753 course/ 231 lec/ 94363 ms10/ 55531 bsft09/ 94125 cslab/ 94239 misc/ 91159 ms11/ …… e) Map “lec” inode # 231 and load inode 231 d) Repeat the above steps until map “unix-fs.doc” inode #
Super block • Each file system has a super block which contains: • The size of the file system • The number of free blocks in the system • An array of cached free block numbers • The index of the next free block number • A pointer to the start of i-nodes area • The number of free i-nodes in the system • A list of cached free i-node numbers • The index of the next free i-node numbers • The super block (usually one disk block) of the root file system must be loaded into memory when system is up.
Calculate inode-address from inode number blk_num = (inode_num1) #inodes-per-blk + st-addr-inodes byte_offset = ((inode_num1) mod (#inodes-per-blk))inode-size N.B. In UNIX, inode-size = 64, #inodes-per-blk = 16
Summary on address translations pathname inode # inode address (block # & offset) inode data block # disk address data
Pseudo-code for open operation int open (path-name, op) { i = resolve(path-name); if inode(i) in inode-table then inode-table(i).count++; else load inode(i) into inode-table; create an entry in file-table, file-entry(i); file-entry(i).count = 1; file-entry(i).op = op; file-entry(i).offset = 0; file-entry(i).inode-ptr = &(inode-table(i)); fd = get the next entry in file-descript-table, fdt; fdt[fd] = &(file-entry(i)); return fd; }
Pseudo-code for read operation Steps of reading a file data: read (fp, n, buf) fp pointer to the entry in file-table, getting offset pointer to the entry in inode-table get the block # of the data convert the block # to head, cylinder, sector ask disk controller to read in data and copy the n bytes into buf
Global File Organization • Disk Partitions • disk units are partitioned into partitions (devices). • each device can be configured into a file system. • inode numbers and disk block numbers are valid within a file system.
Mount/umount operations mount(dev_name, dir_name, options); umount(dev_name) e.g., mount(“/dev/dsk1”, “/usr”, 0) /usr/src/uts
Mount table incore inode table mount table
Name resolution cross mount point • mount /dev/dsk1 /usr • cd /usr/src/uts • When the kernel parses the path name crossing a mount point, from the inode it knows this is a mount point. • It finds the mount table entry, which contains the addr of the super block and a pointer to the root inode (incore). • It then accesses the root inode of the mounted file system. The rest of the name resolution is inside the mounted fs.
Link files Link system call is link(sour_fname, dest_fname) e.g. link(“usr/src/uts/sys”, “/usr/include/sys”) • File system first finds the inode # of the source file. • It then searches for the parent directory of the dest_fname. • It adds an entry in the parent directory of the dest file), and fills in the pair of dest_fname and the inode #. • Notice: link cannot cross a file system.