Do spisu tresci naszej grupy

6.3.2.2 Skomentowany kod funkcji systemowej load_inode_bitmap



/*
 * 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++;
		else 
Liczba 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;
}


Przygotował Adam Hlebowicz