ďťż
Lemur zaprasza
Do spisu treści tematu 6.4.2 Algorytm iput Spis treści Wprowadzenie Skomentowany kod Funkcje pomocnicze Bibliografia Wprowadzenie Jeżeli proces zakończył operację z plikiem (a więc także z i węzłem ), musi on zwolnić kopię pamięciową i-węzła, aby inne procesy mogły pobrać wolny i-węzeł. Generalnie algorytm polega na zmniejszeniu licznika otwarć pliku(i_count), oraz wykonaniu specjalnych czynności w przypadku, gdy proces jest ostatnim zamykającym plik(i_count==0). Czynności te to: nagranie i-węzla, jeżeli kopia pamięciowa różni się od dyskowej(specjalna flaga) umieszczenie i-węzła na liście wolnych i-węzłów w razie potrzeby zwolnienie bloków dyskowych związanych z plikem lub zwolnienie i-węzła na dysku Algorytm ten w Linuxie 2.0.32 jest realizowany przez funkcję iput, znajdującą się w pliku inode.c. Skomentowany Kod void iput(struct inode * inode) { if (!inode) return; Wykonaj test blokady wait_on_inode(inode); Jeżeli licznik otwarć(i_count) = 0 wyjdź; if (!inode->i_count) { printk("VFS: iput: trying to free free inode\n"); printk("VFS: device %s, inode %lu, mode=0%07o\n", kdevname(inode->i_rdev), inode->i_ino, inode->i_mode); return; } Jeżeli inode jest typu PIPE, obudż wszystkie przerywalne procesy z kolejki PIPE_WAIT(*inode) if (inode->i_pipe) wake_up_interruptible(&PIPE_WAIT(*inode)); repeat: Jeżeli licznik otwarć jest > 1 to zmniejsz go o 1 i wyjdz; if (inode->i_count>1) { inode->i_count--; return; } Zwolnij procesy czekające na wolny i-węzel w kolejce inode_wait; wake_up(&inode_wait); Jeżeli inode byl typu PIPE, zwolnij związana z nim stronę pamięci if (inode->i_pipe) { unsigned long page = (unsigned long) PIPE_BASE(*inode); PIPE_BASE(*inode) = NULL; free_page(page); } Jeżeli wskaźniki do funkcji put_inode i pośrednie są OK if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) { wykonaj funkcje put_inode odpowiednią do systemu plików; inode->i_sb->s_op->put_inode(inode); jeżeli liczba dowiązań do pliku wynosi 0, wyjdź if (!inode->i_nlink) return; } Jeżeli i-węzel należy zaktualizować if (inode->i_dirt) { nagraj i-węzel write_inode(inode); /* we can sleep - so do again */ wykonaj test na blokadę wait_on_inode(inode); goto repeat; } Jeżeli i-węzel ma charakter nagrywalny(plik,katalog lub link) i są zdefiniowane operacje na quota if (IS_WRITABLE(inode)) { if (inode->i_sb && inode->i_sb->dq_op) { /* Here we can sleep also. Let's do it again * Dmitry Gorodchanin 02/11/96 */ zalóż blokadę na inode inode->i_lock = 1; uaktualnij quotę inode->i_sb->dq_op->drop(inode); zdejmij blokadę unlock_inode(inode); goto repeat; } } zmniejsz licznik otwarć pliku inode->i_count--; if (inode->i_count) /* * Huoh, we were supposed to be the last user, but someone has * grabbed it while we were sleeping. Dont destroy inode VM * mappings, it might cause a memory leak. */ return; if (inode->i_mmap) { printk("iput: inode %lu on device %s still has mappings.\n", inode->i_ino, kdevname(inode->i_dev)); inode->i_mmap = NULL; } zwiększ licznik wolnych i-węzlow nr_free_inodes++; return; } Funkcje pomocnicze wait_on_inode() jezeli flaga i_lock jest ustawiona zaśnij w kolejce zwiazanej z i-węzlem (wait_queue) write_inode() ( w ext2 - ext_write_inode ), drop_inode, put_inode (w ext2 ext2_put_inode), są to operacje wykonywane fizycznie na dysku, zależne od konkretnego systemu plikow, zazwyczaj wykonywane przez super block. Czasami znajdują sie w nich także uaktualnienia pól struktury inode, np. czasu zmian itp. Bibliografia 1.Pliki zrodlowe Linuxa: /include/linux/fs.h /fs/inode.c /include/linux/ext2_fs.h /fs/ext2/inode.c 2.Projekt Linux 3.Maurice J. Bach "Budowa systemu operacyjnego UNIX" - rozdzial 4 4. Linux Kernel Hackers Guide Autor: Tomasz Sawicki |