Algorytm zwalniania i-węzłów dyskowych w Linuxie zaimplementowany jest w funkcji ext2_free_inode.
/* * linux/fs/ext2/ialloc.c */ void ext2_free_inode (struct inode * inode) { struct super_block * sb; /* wskaźnik do bloku*/ /*identyfikacyjnego w pamięci*/ struct buffer_head * bh; /* wskaźnik do nagłówka bufora*/ /*z bitmapą i-węzłów */ struct buffer_head * bh2;/*wskaźnik do nagłówka bufora*/ /*z deskryptorem grupy */ unsigned long block_group;/* numer grupy w jakiej jest */ /* zwalniany i-węzeł */ unsigned long bit; /* numer i-węzła w grupie */ int bitmap_nr; /* numer bitmapy i-węzłów */ struct ext2_group_desc * gdp;/* wskaźnik do deskryptora grupy i-węzeła */ struct ext2_super_block * es;/* wskaźnik do bloku identyfikacyjnego */ /*** sprawdź czy można zwolnić i-węzeł *****/ if (!inode) /* brak i-węzła */ return; if (!inode->i_dev) { /* brak urządzenia */ printk ("ext2_free_inode: inode has no device\n"); return; } if (inode->i_count > 1) { /* nie tylko my używamy i-węzła */ printk ("ext2_free_inode: inode has count=%d\n", inode->i_count); return; } if (inode->i_nlink) { /* i-węzeł ma jeszcze jakieś dowiązania */ printk ("ext2_free_inode: inode has nlink=%d\n", inode->i_nlink); return; } if (!inode->i_sb) { /* brak wskaźnika do bloku identyfikacyjnego */ printk("ext2_free_inode: inode on nonexistent device\n"); return; } ext2_debug ("freeing inode %lu\n", inode->i_ino); sb = inode->i_sb; lock_super (sb); /* załóż blokadę na blok identyfikacyjny */ /**** sprawdź poprawność numeru i-węzła ****/ if (inode->i_ino < EXT2_FIRST_INO(sb) || inode->i_ino > sb->u.ext2_sb.s_es->s_inodes_count) { ext2_error (sb, "free_inode", "reserved inode or nonexistent inode"); unlock_super (sb); return; } /***** argumenty poprawne *****/ /***** zwalniamy i-węzeł *****/ es = sb->u.ext2_sb.s_es; /**** wylicz numer grupy, do której ****/ /**** należy i-węzeł i jego numer w grupie ****/ block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(sb); bit = (inode->i_ino - 1) % EXT2_INODES_PER_GROUP(sb); /**** wczytaj bitmapę i-węzłów do której należy zwalniany i-węzeł ****/ bitmap_nr = load_inode_bitmap (sb, block_group); bh = sb->u.ext2_sb.s_inode_bitmap[bitmap_nr]; /**** wyczyść bit odpowiadający naszemu i-węzłowi w bitmapie zajętości ****/ if (!clear_bit (bit, bh->b_data)) ext2_warning (sb, "ext2_free_inode", "bit already cleared for inode %lu", inode->i_ino); else { /* jeśli zmodyfikowałeś bitmapę */ /* pobierz deskryptor grupy i zaktualizuj go */ gdp = get_group_desc (sb, block_group, &bh2); /* zwiększając licznik wolnych i-węzłów w grupie*/ gdp->bg_free_inodes_count++; /* jeśli zwalniamy i-węzeł katalogu zmniejsz licznik */ if (S_ISDIR(inode->i_mode)) /* używanych katalogów w grupie */ gdp->bg_used_dirs_count--; /*** zaznacz aktualizowane struktury ***/ mark_buffer_dirty(bh2, 1); /* nagłówek bufora z deskryptorem*/ /* zwiększ licznik wolnych i-węzłów w bloku identyfikacyjnym */ es->s_free_inodes_count++; /* zaznacz bufor zawierający blok identyfikacyjny */ mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); inode->i_dirt = 0; } /* zaznacz nagłówek bufora z bitmapą zajętości i-węzłów */ mark_buffer_dirty(bh, 1); if (sb->s_flags & MS_SYNCHRONOUS) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } /* zwolnij i-węzeł w pamięci */ if (sb->dq_op) sb->dq_op->free_inode (inode, 1); sb->s_dirt = 1; clear_inode (inode); /* zdejmij blokadę z bloku identyfikacyjnego */ unlock_super (sb); }