algorytm przydzielania · pdf filealgorytm przydzielania bloku getblk( ) ... free disk blocks...
TRANSCRIPT
Algorytm przydzielania bloku
getblk( )input: file system number
block numberoutput: locked buffer that can now be used for block
{while (buffer not found)
{ if (block in hash queue){
if (buffer busy) /* scenario 5 */{ sleep (event buffer becomes free);
continue; /* back to while loop */}
lock buffer; /* scenario 1 */remove buffer from free list;return buffer;
}else /* block not on hash queue */
{ if (no free buffers) /* scenario 4 */{ sleep (event any buffer becomes free);
continue; /* back to white loop */}
remove buffer from free list;if (buffer marked for delayed write)
{ /* scenario 3 */asynchronous write buffer to disk;continue; /* back to while loop */
}/* scenario 2--found a free buffer */remove buffer from old hash queue;put buffer onto new hash queue;return buffer;
}}
}
Algorytm zwalniania bufora
brelse( )input: locked bufferoutput: none
{wakeup( all procs, waiting for any buffer to become free);wakeup( all procs, waiting for this buffer to become free);raise processor execution level to block interrupts;if (buffer contents valid && buffer not old)
enqueue buffer at end of free list;else
enqueue buffer at beginning of free list;lower processor execution level to allow interrupts;unlock(buffer);
}
Algorytmy czytania bloku
1. czytanie pojedynczego bloku
bread( )input: block numberoutput: buffer containing data
{getblk(block number);if (buffer data valid)
return buffer;initiate disk read; /*synchronous*/sleep(event disk read complete);return (buffer);
}
2. czytanie bloku z “look-ahead”
breada()input: block number for immediate read
block number for asynchronous readoutput: buffer containing data for immeciiate read
{if (first block not in cache)
{ getblk(first block);if (buffer data not valid)
initiate disk read; /*synchronous*/}
if (second block not in cache){ getbl k(second block);
if (buffer data valid)brelse(second block);
elseinitiate disk read; /*asynchronous*/
}if (first block was originally in cache)
{ bread (first block);return buffer;
}sleep (event first buffer contains valid data);return buffer;
}
Algorytm zapisu bloku
bwrite( )input: bufferoutput: none
{initiate disk write;if (l/O synchronous)
{ sleep(event I/O complete);brelse(buffer);
}else if (buffer marked for delayed write
mark buffer to put at head of free list;}
Algorytm czytania INODE
iget()input: file system inode numberoutput: locked inode
{while (not done)
{ if (inode in inode cache){ if (inode locked)
{ sleep (event inode becomes unlocked);continue; /* loop */
}/*tutaj ominiety kod dot. wej�� �� ������ �������if (inode on inode free list)
remove from free list;increment inode reference count;return (inode);
}/* inode not in inode cache */if (no inodes on free list) return(error);remove new inode from free list,reset inode number and file system;remove inode from old hash queue, place on new one;bread(inode block);initialize inode (reference count = 1);return (inode);
}}
Zwalnianie kopii INODE w pamieci
iput()input: pointer to in-core inodeoutput: none
{lock inode if not already locked;decrement inode reference count;if (reference count==0)
{ if(inode link count==0){
free disk blocks for file (algorithm free);set file type to 0;ifree(inode);
}if (file accessed or inode changed or file changed)
update disk inode;put inode on free list;
}release inode lock;
}
Algorytm przydzialu nowego INODE
ialloc()input: file systemoutput: locked inode
{while (not done)
{ if (superblock locked){ sleep (event superblock becomes free);
continue; /* loop */}
if (inode list in superblock is empty){ lock superblock;
get remembered inode for free inode search;search disk for free inodes until superblock full,
or no more free inodes (algorithms bread and brelse);unlock superblock;wakeup (event superblock becomes free);if (no free inodes found on disk) return (no inode);set remembered inode for next free inode search;
}/*there are inodes in superblock inode list */iget(inode number from superblock inode list);if (inode not free after all)
{ write inode to disk;iput(inode);continue; /* loop */
}/*inode is free */initialize inode;write inode to disk;decrement file system free inode count;return (inode);
}}
Algorytm zwalniania INODE
ifree( )input: file system inode numberoutput: none
{increment file system free inode count;if (superblock locked) return;if (inode list full)
{ if (inode number less than remembered inode for search)remembered inode for search = input inode number;
}else
store inode number in inode list;return;
}
Algorytm przydzialu bloku dyskowego
alloc()input: file system numberoutput: buffer for new block
{while (superblock locked)
sleep (event superblock not locked);remove block from superblock free list;if (removed last block from free list)
{ lock superblock;bread (block just taken from free list);copy block numbers in block into superblock;brelse(block buffer);unlock superblock;wakeup(event superblock not locked);
}getblk (block removed from superblock list);zero buffer contents;decrement total count of free blocks;mark superblock modified;return buffer;
}
�������� ���� ������� ����� ��� ���� � � �� �� ������ � ������
bmap ()input: inode byte offsetoutput: block number in file system
byte offset into block bytes of I/O in block read ahead block number
{calculate logical block number in file from byte offset;calculate start byte in block for I/O; /* output 2*/calculate number of bytes to copy to user; /* output 3 */check if read-ahead applicable, mark inode; /* output 4 */determine level of block indirection;while (not at necessary level of indirection)
{calculate index into inode or indirect block
from logical block number in file;get disk block number from inode or indirect block;brelse(buffer from previous disk read, if any);if (no more levels of indirection)
return (block number);bread (indirect block);adjust logical block number in file according to level of indirection;
}}
�������� ��� ��� �� ��� ������ �� � �� �� �����
namei( )input: path nameoutput: locked inode
{if (path name starts from root)
wd = iget(root);else
wd = iget(current directory inode);while (there is more path name)
{read next path name component from input;verify wd is a directory, access permissions OK;if (wd is root && component is "..")
continue; /* loop */read wd using algorithms bmap, bread and brelse;if (component matches an entry in wd)
{ get inode number for matched component;iput(wd);wd = iget(matched component);
}else /* component not in directory */ /
return (no inode);}
return (wd);}
Algorytm tworzenia nowego pliku
creat( )input: file name
permission settingsoutput: file descriptor
{namei(file name);if (file already exists)
{if (not permitted access)
{ iput(inode);return (error);
}} else /* file does not exist yet */{
ialloc();create new directory entry in parent directory;include new file name and newly assigned inode number;
}allocate file table entry for inode initialize count;if (file did exist at time of create)
free all file blocks (algorithm free);unlock (inode);return(user file descriptor);
}
Algorytm otwierania pliku
open()inputs: filename
type of openfile permissions (for creation type of open)
output: file handle{
namei(filename);if (file does not exist or not permitted access)
return(error);allocate file table entry for inode, initialize count, offset;allocate user file descriptor entry, set pointer to file table entry;if (type of open specifies truncate file)
free(all file blocks);unlock(inode); /* locked in namei */return(user file descriptor);
}
Algorytmy czvtania i zapisu do pliku
read/write()input: handle
addressnumber of bytes
output: number of bytes read/written{
get file table entry from user file descriptor;check file accessibility;set params in u-area: address, byte count, l/O direction;get inode from file table;lock inode;set byte offset in u-area from file table offset;while (count not satisfied)
{ disk block = bmap(file offset);calculate offset into block, number of bytes to read;
˝
/*==== read write differ in this part =====*//* version for read */if (number of bytes == 0)
break; /* end of file */bread(disk block) /*breada if with read ahead*/copy data to user address;/* version for write */if(new block)
{ alloc(); /*multiple allocations if indirect block*/ ’if (failure in allocation)
break; /*out of disk space*/}
else if(writing part of block)bread(disk block);
else getblk();copy data to buffer;mark buffer as updated;/*===== algorithms similar from this point ====*/
˝
update u-area fields: file byte offset, read count, user address;brelse(buffer); /* locked in bread */
}unlock(inode);update file table offset for next read;return (total number of bytes read/written);
}
Algorytm otwierania “pipe” bez nazwy
pipe( )input: noneoutput: read file descriptor
{write file descriptor;ialloc(new inode);allocate file table entry for reading, another for writing;initialize file table entries to point to new inode;allocate user file descriptor for reading;initialize to point to respective file table entries;set inode reference count to 2;initialize count of inode readers, writers to 1;
}
Algorytm tworzenia nowej pozycji katalogowej
mknod( )inputs: file name
file typepermissionsmajor, minor device no. (block or character special files)
output: none{
if (new node not named pipe and user not super user)return(error);
namei(file name);if (new node already exists)
{ iput(parent inode);return (error);
}ialloc();create new directory entry in parent directory:include new node name and newly assigned inode number;iput(parent inode);if (new node is block or character special file)write major, minor numbers into inode structure;iput(new node inode);
}
�������� ��� ����� � ������� � �!�
mount( )inputs: file name of block special file
directory name of mount pointoptions (read only)
output: none{
if (not super user)return(error);
get inode for block special file (algorithm namei);make legality checks;get inode for “mounted on” directory name (algorithm namei);if (not directory, or reference count > 1)
{release inodes (algorithm iput);return (error);
}find empty slot in mount table;invoke block device driver open routine;get free buffer from buffer cache;read superblock into free buffer;initialize superblock fields;get root inode of mounted device (algorithm iget), save in mount table;mark inode of “mounted on” directory as mount point;release special file inode (algorithm iput);unlock inode of mount point directory;
}
�������� �� ����� � ������� � �!�
umount()input: special file name of file system to be unmountedoutput: none
{if (not superuser)
return(error);get inode of special file (algorithm namei);extract major, minor number of device being unmounted;get mount table entry, based on major, minor number;release inode of special file (algorithm iput);remove shared text entries from region table for files
belonging to file system;update superblock, inodes, flush buffers;if (files from file system still in use)
return (error);get root inode of mounted file system from mount table;lock inode;release inode (algorithm iput); /* iget was in mount */invoke close routine for special device;invalidate buffers in pool from unmounted file system;get inode of mount point from mount table;lock inode;clear flag marking it as mount point;release inode (algorithm iput); /* iget in mount */free buffer used for superblock;free mount table slot;
}
Zmodyfikowany algorytm iget (dla wielu systemów plików)
iget( )input: file system inode numberoutput: locked inode
{while (not done)
{ if (inode in inode cache){
if (inode locked){
sleep (event inode becomes unlocked);continue; /* loop */
}/* special processing for mount points */if (inode a mount point)
{find mount table entry for mount point;get new file system number from mount table;use root inode number in search;continue; * loop again */
}if (inode on inode free list)
remove from free list;increment inode reference count;return (inode);
}/* inode not in inode cache */remove new inode from free list;reset inode number and file system;remove inode from old hash queue, place on new one;read inode from disk (algorithm bread);initialize inode (e.g. reference count to 1);return inode;
}}
Zmodyfikowany algorytm namei
int namei()input: path nameoutput: locked inode
{if (path name starts from root)
working inode = root inode (algorithm iget);else
working inode = current directory inode (algorithm iget);while (there is more path name)
{read next path name component from input;verify that inode is of directory, permissions;if (inode is of changed root and component is “..“)
continue; /* loop */component search:
read inode (directory) (algorithms bmap, bread, brelse);if (component matches a directory entry)
{get inode number for matched component;if (found inode of root and working inode is root and
and component name is “..“){
/* crossing mount point */get mount table entry for working inode;release working inode (algorithm iput);working inode = mounted on inode;lock mounted on inode;increment reference count of working inode;go to component search; /* for “..“ */
}iput (working inode);working inode = iget (new inode number);
}else /* component not in directory */
return (no inode);}
return (working inode);}
�������� ������� � ������ �� ����� �
link( )input: existing file name
new file nameoutput: none
{get inode for existing file name (algorith namei);if (too many links on file or linking directory without superuser
permission){
release inode (algorithm iput);return(error);
}increment link count on inode;update disk copy of inode;unlock inode;get parent inode for directory to contain new file name (algorith namei);if (new file name already exists or new file on different file system)
{undo update done above;return(error);
}create new directory entry in parent directory of new file name:include new file name, inode number of existing file name;release parent directory inode (algorith iput);release inode of existing file (algorith iput);
}
�������� ������� � �� ����� � ��" � ��
unlink( )input: file nameoutput: none
{get parent inode of file to be unlinked (algorithm namei);if (last component of file name is “.“)
increment inode reference count;else
get inode of file to be unlinked (algorithm iget);if (file is directory but user is not superuser)
{release inodes (algorithm iput) ;return(error);
}if (shared text file and link count currently 1)
remove from region table;write parent directory: zero inode number of unlinked file;release inode parent directory (algorithm iput);decrement file link count;release file inode (algorithm iput);/* iput checks if link count is 0: if so, * releases file blocks (algorithm free) and * frees inode (algorithm ifree); */
}