/* * load_inode_bitmap loads the inode bitmap for a blocks group * * It maintains a cache for the last bitmaps loaded. This cache is managed * with a LRU algorithm. * * Notes: * 1/ There is one cache per mounted file system. * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups, * this function reads the bitmap without maintaining a LRU cache. * * Return the slot used to store the bitmap, or a -ve error code. */W pamieci może być jednocześnie załadowanych EXT2_MAX_GROUP_LOADED bitmap. W super blocku znajduje się tablica inode_bitmap[] o rozmiarze EXT2_MAX_GROUP_LOADED, w której znajdują się wskażniki do bitmap w pamięci. Jeżeli liczba grup jest mniejsza od tej stałej to nie ma problemu ( wszystkie bitmapy znajdują się w pamięci), wpp jeżeli nastąpi żądanie odczytania bitmapy, która nie znajduje się w pamięci, to zgodnie z algorytmen LRU wyrzuca się bitmapę najdłużej nieużywaną a na jej miejsce wczytuje się z dysku żądaną bitmapę.
static int load_inode_bitmap (struct super_block * sb, unsigned int block_group) { /* * sb - wskaźnik do Super Block w pamieci * block_group - numer grupy, której * bitmapa zajętości i-węzłów ma zostać * odczytana. * * Funkcja zwraca numer indeksu tablicy inode_bitmap[], pod którym znajduje się wskaźnik * do bitmapy zajętości i-węzłów grupy bloków o numerze block_group. */ int i, j, retval = 0; unsigned long inode_bitmap_number; struct buffer_head * inode_bitmap;Sprawdzenie poprawności wartości argumentów
if (block_group >= sb->u.ext2_sb.s_groups_count) ext2_panic (sb, "load_inode_bitmap", "block_group >= groups_count - " "block_group = %d, groups_count = %lu", block_group, sb->u.ext2_sb.s_groups_count); if (sb->u.ext2_sb.s_loaded_inode_bitmaps > 0 && sb->u.ext2_sb.s_inode_bitmap_number[0] == block_group) return 0; if (sb->u.ext2_sb.s_groups_count <= EXT2_MAX_GROUP_LOADED) {Liczba grup jest mniejsza od max. liczby bitmap w pamięci. Wówczas wskażnik do bitmapy i-tej grupy spodziewamy się znależć pod i-tym indeksem tablicy inode_bitmap[] w super bloku.
if (sb->u.ext2_sb.s_inode_bitmap[block_group]) {Wskaźnik do bitmapy istnieje - bitmapa jest w pamięci.
if (sb->u.ext2_sb.s_inode_bitmap_number[block_group] != block_group) ext2_panic (sb, "load_inode_bitmap", "block_group != inode_bitmap_number"); else return block_group; } else {Pod odpowiednim indeksem w tablicy inode_bitmap[] był NULL tzn. bitmapa niezostała jeszcze odczytana z dysku.
retval = read_inode_bitmap (sb, block_group, block_group);Bitmapa została odczytana z dysku
if (retval < 0) return retval; return block_group; } }Liczba grup jest większa od max. liczby bitmap w pamięci. Sprawdzenie czy wśród bitmap w pamięci jest bitmapa grupy o numerze block_group
for (i = 0; i < sb->u.ext2_sb.s_loaded_inode_bitmaps && sb->u.ext2_sb.s_inode_bitmap_number[i] != block_group; i++); if (i < sb->u.ext2_sb.s_loaded_inode_bitmaps && sb->u.ext2_sb.s_inode_bitmap_number[i] == block_group) {Szukana bitmapa jest w pamięci.
inode_bitmap_number = sb->u.ext2_sb.s_inode_bitmap_number[i]; inode_bitmap = sb->u.ext2_sb.s_inode_bitmap[i]; for (j = i; j > 0; j--) { sb->u.ext2_sb.s_inode_bitmap_number[j] = sb->u.ext2_sb.s_inode_bitmap_number[j - 1]; sb->u.ext2_sb.s_inode_bitmap[j] = sb->u.ext2_sb.s_inode_bitmap[j - 1]; }Włożenie znalezionej bitmapy na początek kolejki - alg. LRU.
sb->u.ext2_sb.s_inode_bitmap_number[0] = inode_bitmap_number; sb->u.ext2_sb.s_inode_bitmap[0] = inode_bitmap; /* * There's still one special case here --- if inode_bitmap == 0 * then our last attempt to read the bitmap failed and we have * just ended up caching that failure. Try again to read it. */ if (!inode_bitmap) retval = read_inode_bitmap (sb, block_group, 0); } else {Szukanej bitmapy nie było w pamięci.
if (sb->u.ext2_sb.s_loaded_inode_bitmaps < EXT2_MAX_GROUP_LOADED)Liczba załadowanych bitmap nie przekracza maksymalnej wartości.
sb->u.ext2_sb.s_loaded_inode_bitmaps++; elseLiczba załadowanych bitmap przekracza dopuszczalną wartość Najdłużej nieużywana bitmapa zostanie usunięta z pamięci.
brelse (sb->u.ext2_sb.s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1]); for (j = sb->u.ext2_sb.s_loaded_inode_bitmaps - 1; j > 0; j--) { sb->u.ext2_sb.s_inode_bitmap_number[j] = sb->u.ext2_sb.s_inode_bitmap_number[j - 1]; sb->u.ext2_sb.s_inode_bitmap[j] = sb->u.ext2_sb.s_inode_bitmap[j - 1]; }Odczytanie bitmapy z dysku i włożenie jej na początek kolejki jako bitmapę ostatnio używaną.
retval = read_inode_bitmap (sb, block_group, 0); } return retval; }