Do spisu tresci



6.3.2.4 Skomentowany kod procedury zwalniania i-węzłów dyskowych.


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);




}


Bibliografia

  1. Plik źródłowy Linuxa:


Autor: Maciej Zarzycki