Anàlisi d'ext2

De Jose Castillo Aliaga
Ir a la navegación Ir a la búsqueda

Ext2 és un dels sistemes d'arxius més utilitzats en Linux. Ha sigut extés per Ext3 i Ext4, però són ampliacions que milloren algunes coses sobre la base de Etx2. Per tant, resulta interesant parlar d'aquest sistema per a entendre millor cóm funciona el sistema de fitxers en Linux.

I-nodes

L'i-node (node índex) és un concepte fonamental en el sistema d'arxius de Linux i UNIX. Cada objecte en el sistema de fitxers està representat per un node-i.

Totes i tots els arxius sota Linux (i UNIX) té els següents atributs:

  • Tipus de fitxers (executables, especial, de blocs...)
  • Permisos (llegir, escriure...)
  • Propietari
  • Grup
  • Mida del fitxer
  • Temps d'accés de l'arxiu, el canvi i la modificació (UNIX o Linux mai emmagatzema el temps de creació de l'arxiu, això és pregunta favorita preguntar en UNIX/Linux en una entrevista de treball)
  • Temps d'eliminació del Arxiu
  • Nombre d'enllaços (soft / hard)
  • Atribut estès com només-afegir o no es pot eliminar el fitxer com a usuari root (irrevocabilitat)
  • Llista de control d'Accés (ACL)

Cal recordar que un i-node:

  • No conté el nom del fitxer. El nom el guarda el directori que el conté.
  • Els directoris són uns fitxers especials que contenen una llista de noms de fitxers i els seus inodes.

Podem fer les següents comande per vorer el i-node de l'arxiu:

$ ls -i /etc/passwd
$ stat /etc/passwd

Amb aquestes premises, es pot aconseguir:

  • Un fitxer pot tindre molts enllaços. Sols cal apuntar al mateix inode. (Hard Links)
  • Un nom de fitxer pot tindre enllaços que l'apunten. (Soft Links)
  • Un inode pot no tindre enllaços. Al esborrar un arxiu s'intenten alliberar els recursos. Però el sistema espera a que tots els processos lliberen l'inode.
  • Un inode permaneix encara que moguem el fitxer a un altre directori o es defragmente el disc.

Estructura d'un inode

Ext2-inode.gif

Els inodes tenen 15 punters:

  • Dotze punters que assenyalen directament als blocs de dades de l'arxiu (punters directes)
  • Un indicador indirecte per separat (un punter que apunta a un bloc de punters que apunten a continuació als blocs de dades de l'arxiu)
  • Un punter doblement indirectes (un punter que apunta a un bloc de punters que apunten a altres blocs de punters que apunten a continuació als blocs de dades de l'arxiu)
  • Un punter triplement indirecte (un punter que apunta a un bloc de punters que apunten a altres blocs de punters que apunten a altres blocs de punters que apunten a continuació als blocs de dades de l'arxiu)

Aquesta organització permet:

  • Una mida fixa de cada bloc. Pot ser es necessita sols un inode o més, però tots ocupen en mateix.
  • Facilitat per trobar les dades. No cal recorrer tot el fitxer, es pto trobar el bloc concret mirant el inode.
  • Els blocs indirectes poden estar en qualsevol part del sistema.

Etx2

El sistema de fitxers EXT2 es construeix amb la premissa que les dades contingudes en els fitxers es guardin en Blocs de Dades. Aquests blocs de dades són tots de la mateixa longitud i, si bé aquesta longitud pot variar entre diferents sistemes de fitxers EXT2 la mida dels blocs d'un sistema de fitxers EXT2 en particular es decideix quan es crea (usant mke2fs). La mida de cada fitxer s'arrodoneix fins a un nombre sencer de blocs. Si la mida de bloc és 1024 bytes, llavors un fitxer de 1025 bytes ocuparà dos blocs de 1024 bytes.

No tots els blocs del sistema de fitxers contenen dades, alguns s'han d'utilitzar per mantenir la informació que descriu l'estructura del sistema de fitxers. EXT2 defineix la topologia del sistema de fitxers descrivint cadascun d'ells amb una estructura de dades inode. Els inodes del sistema de fitxers s'emmagatzemen junts en Taules de inodes.

Els directoris EXT2 són simplement fitxers especials (ells mateixos descrits per inodes) que contenen punters als inodes de les seves entrades de directori.

Sist arch ext2.jpg

A la figura anterior es mostra la disposició del sistema de fitxers EXT2 ocupant una sèrie de blocs en un dispositiu estructurat bloc. Per la part que li toca a cada sistema de fitxers, els dispositius de bloc són només una sèrie de blocs que es poden llegir i escriure. Un sistema de fitxers no s'ha de preocupar on s'ha de posar un bloc en el medi físic, això és feina del controlador del dispositiu. Sempre que un sistema de fitxers necessita llegir informació o dades del dispositiu de bloc que els conté, demana que el controlador de dispositiu llegeixi un nombre sencer de blocs.

El sistema de fitxers EXT2 divideix les particions lògiques que ocupa en Grups de Bloc (Block Groups), en els quals cada grup duplica informació crítica per a la integritat del sistema de fitxers ja sigui valent-se de fitxers i directoris de blocs d'informació i dades. Aquesta duplicació és necessària per si ocorregués un desastre i el sistema de fitxers necessités recuperar-se.

Estructura en el disc

Ext2grups.png

Els primers 1024 bytes mai són manejat pel sistema de fitxers Ext2, ja que está reservat per al sector d'arrencada. La resta de la partició Ext2 es divideix en grups de blocs, redueixen la fragmentació, perquè el nucli intenta mantenir els blocs de dades d'un arxiu en el mateix grup de blocs, si és possible.

Cada bloc en el grup conté algunes de les peces d'informació:

  • Una còpia del superbloc del sistema de fitxers.
  • Una còpia del grup de descriptors de grups de blocs.
  • Un mapa de bits de bloc.
  • Un grup d'inodes.
  • Un mapa de bits d'inodes.
  • Un tros de dades pertanyents a arxiu, és a dir, blocs de dades (si un bloc no conté cap informació útil, es diu que aquesta lliure).

Tant el superbloc com els descriptors de grup estan duplicats en cada grup de blocs. Només el superbloc i els descriptors de grups inclosos en el grup de blocs 0 són utilitzats pel nucli, mentre que les altres còpies es deixen sense modificar, de fet, mai les mira.

Quan el programa /sbin/e2fsck realitza una comprovació de consistència, referència el superbloc i els descriptors de grups de blocs de grup 0 copiant a la resta de grups de blocs. Si es produeix una corrupció de dades, i el superbloc i els descriptors de grups del grup 0 es fan invàlids, l'administrador pot indicar a /sbin/e2fsck que faci referències a les velles còpies d'altres grups diferents de 0.

Usualment, les còpies redundants tenen prou informació per permetre al programa retornar la partició a un estat consistent.

El nombre de grups de blocs depèn tant de la mida de la partició com de la grandària de bloc. La principal restricció es deu al fet que el mapa de bits de bloc, que s'utilitza per identificar els blocs dins d'un grup que estan en ús o lliures, s'ha d'emmagatzemar en un únic bloc. Per tant, cada grup de blocs ha de tenir com a màxim 8 * b blocs, on b és la mida de bloc en bytes. Així, el nombre total de grups de blocs és aproximadament s / (8 * b), on s és la mida de la partició en blocs.

Com a exemple, considerem una partició Ext2 de 8 GB amb blocs de 4 KB de mida. En aquest cas, cada mapa de bits de blocs de 4KB descriu 32 KB de blocs de dades, és a dir, 128 MB. Per tant, com a màxim es necessiten 64 grups de blocs.

Clarament, a menor mida de bloc, major nombre de grups de blocs.

Si s'utlitzen blocs de 1KB el superbloc és el 1 i si són més grans és considera el 0. Cal recordar que el superbloc sempre utilitza 1kb independenment de la mida dels blocs.

En revisions posteriors, el superbloc no es guarda en tots els grups de blocs per no perdre espai.

El bloc de bitmap i de inodes está llimitat a 1 bloc, per tant, cada grup de blocs té un nombre llimitat de blocs.


Sample Floppy Disk Layout, 1KiB blocks

Block Offset Length Description
byte 0 512 bytes boot record (if present)
byte 512 512 bytes additional boot record data (if present)
-- block group 0, blocks 1 to 1439 --
byte 1024 1024 bytes superblock
block 2 1 block block group descriptor table
block 3 1 block block bitmap
block 4 1 block inode bitmap
block 5 23 blocks inode table
block 28 1412 blocks data blocks

Sample 20mb Partition Layout

Block Offset Length Description
byte 0 512 bytes boot record (if present)
byte 512 512 bytes additional boot record data (if present)
-- block group 0, blocks 1 to 8192 --
byte 1024 1024 bytes

superblock

block 2 1 block

block group descriptor table

block 3 1 block

block bitmap

block 4 1 block

inode bitmap

block 5 214 blocks

inode table

block 219 7974 blocks data blocks
-- block group 1, blocks 8193 to 16384 --
block 8193 1 block

superblock backup

block 8194 1 block

block group descriptor table backup

block 8195 1 block

block bitmap

block 8196 1 block

inode bitmap

block 8197 214 blocks

inode table

block 8408 7974 blocks data blocks
-- block group 2, blocks 16385 to 24576 --
block 16385 1 block

block bitmap

block 16386 1 block

inode bitmap

block 16387 214 blocks 1 block

block bitmap

block 16386 1 block

inode bitmap

block 16387 214 blocks

inode table

block 16601 3879 blocks data blocks


Superblock Structure

Offset (bytes) Size (bytes) Description
0 4

s_inodes_count

4 4

s_blocks_count

8 4

s_r_blocks_count

12 4

s_free_blocks_count

16 4

s_free_inodes_count

20 4

s_first_data_block

24 4

s_log_block_size

28 4

s_log_frag_size

32 4

s_blocks_per_group

36 4

s_frags_per_group

40Comença en el byte 1024 i pot tindre copies de seguretat en altre grups de blocs. 4

s_inodes_per_group

44 4

s_mtime

48 4

s_wtime

52 2

s_mnt_count

54 2

s_max_mnt_count

56 2

s_magic

58 2

s_state

60 2

s_errors

62 2

s_minor_rev_level

64 4

s_lastcheck

68 4

s_checkinterval

72 4

s_creator_os

76 4

s_rev_level

80 2

s_def_resuid

82 2

s_def_resgid

-- EXT2_DYNAMIC_REV Specific --
84 4

s_first_ino

88 2

s_inode_size

90 2

s_block_group_nr

92 4

s_feature_compat

96 4

s_feature_incompat

100 4

s_feature_ro_compat

104 16

s_uuid

120 16

s_volume_name

136 64

s_last_mounted

200 4

s_algo_bitmap

-- Performance Hints --
204 1

s_prealloc_blocks

205 1

s_prealloc_dir_blocks

206 2 (alignment)
-- Journaling Support --
208 16

s_journal_uuid

224 4

s_journal_inum

228 4

s_journal_dev

232 4

s_last_orphan

-- Directory Indexing Support --
236 4 x 4

s_hash_seed

252 1

s_def_hash_version

253 3 padding - reserved for future expansion
-- Other options --
256 4

s_default_mount_options

260 4

s_first_meta_bg

264 760 Unused - reserved for future revisions

Estudi d'un cas real

Primer generem una imatge virtual del sistema de fitxers:

$ dd if=/dev/zero of=disc.img bs=512 count=2048
$ mkfs.ext2 disc.img

Ara podem muntar la imatge i crear directoris o fitxers dins:

$ sudo mount -o loop disc.img ./mount
$ cd mount
$ mkdir prova1
$ dd if=/dev/urandom of=prova2 bs=512 count=5
...

Ara podem desmuntar-la i analitzar-la amb un lector hexadecimal:

$ xxd disc.img | less
$ xxd disc.img | grep 'prova2'
...

Superbloc

Comença en el byte 1024 i pot tindre copies de seguretat en altre grups de blocs. Anem a observar alguns extractes del fitxer. El primer el superbloc:

0000400: 8000 0000 0004 0000 3300 0000 d603 0000  ........3.......
0000410: 7300 0000 0100 0000 0000 0000 0000 0000  s...............
0000420: 0020 0000 0020 0000 8000 0000 9b19 af51  . ... .........Q
0000430: c819 af51 0100 2000 53ef 0100 0100 0000  ...Q.. .S.......
0000440: 8419 af51 004e ed00 0000 0000 0100 0000  ...Q.N..........
0000450: 0000 0000 0b00 0000 8000 0000 3800 0000  ............8...
0000460: 0200 0000 0100 0000 6e65 7464 8e4e 45ab  ........netd.NE.
0000470: b5c1 5cab a451 8906 0000 0000 0000 0000  ..\..Q..........
0000480: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000490: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00004a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00004b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00004c0: 0000 0000 0000 0000 0000 0000 0000 0300  ................
00004d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00004e0: 0000 0000 0000 0000 0000 0000 b694 08c3  ................
00004f0: 6467 44e9 b223 66bf cf72 6f50 0100 0000  dgD..#f..roP....
0000500: 0000 0000 0000 0000 8419 af51 0000 0000  ...........Q....
0000510: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000520: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000530: 0000 0000 0000 0000 0000 0000 0000 0000  ................

El primer que vegem és que comença en el 0x400, és a dir, el 1024. Cal dir que els valors estan en Little Endian.

  • 8000 0000: s_inodes_count Valor de 32 bits que indica la quantitat de inodes del sistema de fitxers. Deuría ser igual o menor que s_inodes_per_group*número de grups.
  • 0004 0000: s_blocks_count Valor de 32 bits que indica la quantitat de blocs en el sistema de fitxers. Vol dir que hi ha 0x00000400 o 1024 blocs en el sistema. Com que és una imatge de 1MB, cada bloc ocupa 1KB.
  • 3300 0000: s_r_blocks_count Blocs reservats per al superusuari per a que ningú puga omplir totalment el sistema de fitxers. 0x33 = 51 blocs reservats.
  • d603 0000: s_free_blocks_count Blocs lliures. 0x03d6 = 982
  • 7300 0000: s_free_inodes_count Inodes lliures.
  • 0100 0000: s_first_data_block Indica el bloc que té el superbloc. Si la mida del bloc és 1KB sempre és 1 i si és més, sempre és 0.
  • 0000 0000: s_log_block_size La mida del bloc. Però la manera de calcular-la és diguen la quantitat de bits que has de moure cap a l'esquerra el número 1024. Per exemple: si la mida fora 4KB, i 1024 en bits és 10000000000, tenim que moure 2 bits cap a l'esquerra per tindre: 1000000000000 = 4KB.
  • 0000 0000: s_log_frag_size Mida del fragment. Es calcula igual. El fragment és una manera de subdividir el bloc. Però aquesta funció pareix que no està suportada pel kernel.
  • 0020 0000: s_blocks_per_group Quantitat de blocs que té cada grup. 0x00002000 = 8192
  • 0020 0000: s_frags_per_group Fragments per cada grup.
  • 8000 0000: s_inodes_per_group Quantitat de inodes per grup. S'utilitza per a saber la mida del mapa de bits de inodes. 0x80 = 128
  • 9b19 af51: s_mtime La última vegada que va ser muntat. 0x51af199b = 1370429851
$ date -d '@1370429851'
mié jun  5 12:57:31 CEST 2013
  • c819 af51: s_wtime L'últim accés d'escriptura.
  • 0100: s_mnt_count Les vegades que ha sigut muntat deprés de l'última verificació.
  • 2000: s_max_mnt_count Les máximes vegades que pot ser muntat sense verificació.
  • 53ef: s_magic Indica que és un ext2. Sempre és 0xef53
  • 0100: s_state Indica l'estat del sistema de fitxers. Si el sistema està muntat, l'estat és 2 (EXT2_ERROR_FS). Si está ben desmuntat és 1 (EXT2_VALID_FS). Si al muntar el sistema es veu que no estava ben desmuntat és típic que s'execute el fsck.
  • 0100: s_errors Valor de 16 bits que diu el que deu fer el driver quant trobe un error. Si 1 Ha de continuar com si no passara res. Si 2 Té que muntar sols com a lectura i si 3 Ha de forçar un Kernel Panic.
  • 0000: s_minor_rev_level Indentifica el nivell de revisió menor.
  • 8419 af51: s_lastcheck Temps POSIX de l'ultima revisió del sistema de arxius.
  • 004e ed00: s_checkinterval Temps POSIX permés entre revisions del sistema de arxius.
  • 0000 0000: s_creator_os. Identifica el sistema operatiu que ha creat el sistema de fitxers. 0 Linux, 1 GNU HURD, 2 MASIX, 3 FreeBSD, 4 Lites.
  • 0100 0000: s_rev_level Valor del nivell de revisió.
  • 0000: s_def_resuid Valor per defecte del id d'usuari per als blocs reservats. En Linux és per defecte 0.
  • 0000: s_def_resgid Valor per defecte per als id del grup per als blocs reservats.
  • 0b00 0000: s_first_ino Index del primer inode usable per fitxers normals. El valor típic és 11.
  • 8000: s_inode_size Mida de l'estructura de cada inode. Per defecte és 128. Però pot ser una potència de 2 sempre que siga menor o igual que la mida del bloc.
  • 0000: s_block_group_nr El número del grup de blocs que té aquest superbloc.
  • 3800 0000: s_feature_compat Máscara de bits de característiques compatibles. 0x01 Permet reservar blocs per a nous directoris. 0x02 Magic inodes, 0x04 permet journaling [1] per a restablir les dades en cas de no poder fer una transacció. 0x08 Atributs extesos. 0x10 Inodes no estandar. 0x20 HTree. En aquest cas si passem a bits 0x38 = 111000 . És a dir. 0x20, 0x10 i 0x8
  • 0200 0000: s_feature_incompat Característiques no compatibles.
  • 0100 0000: s_feature_ro_compat Característiques per les quals el sistema deuria ser muntat en mode read-only.
  • 6e65: s_uuid128 bits per al identificador del volumen.
  • 7464 s_volume_name Nom del volumen. No s'utlitza generalment.
  • 8e4e 45ab b5c1 5cab: s_last_mounted Directori on va ser muntada per última vegada.
  • a451 8906: s_algo_bitmap Valor de 32 bits utilitzat per algoritmes de compressió.
  • 00: s_prealloc_blocks Representa el número de bloc que s'han de reservar per defecte quant es crea un fitxer
  • 00: s_prealloc_dir_blocks Representa el número de bloc que s'han de reservar per defecte quant es crea un directori
  • 0000 0000 0000 0000 0000 0000 0000: Reservats per al journaling de ETX3.
  • 0000 0000 0000 0000 0000 0000 0000 0000 s_hash_seed Llavors per al algoritme de hash per a l'indexació de directoris.
  • 00: s_def_hash_version Versió del hash
  • 0000 0000: s_default_mount_options Opcions de muntatge per al sistema de fitxers.

Struct del superbloc

struct ext2_super_block {
        __u32   s_inodes_count;         /* Inodes count */
        __u32   s_blocks_count;         /* Blocks count */
        __u32   s_r_blocks_count;       /* Reserved blocks count */
        __u32   s_free_blocks_count;    /* Free blocks count */
        __u32   s_free_inodes_count;    /* Free inodes count */
        __u32   s_first_data_block;     /* First Data Block */
        __u32   s_log_block_size;       /* Block size */
        __s32   s_log_frag_size;        /* Fragment size */
        __u32   s_blocks_per_group;     /* # Blocks per group */
        __u32   s_frags_per_group;      /* # Fragments per group */
        __u32   s_inodes_per_group;     /* # Inodes per group */
        __u32   s_mtime;                /* Mount time */
        __u32   s_wtime;                /* Write time */
        __u16   s_mnt_count;            /* Mount count */
        __s16   s_max_mnt_count;        /* Maximal mount count */
        __u16   s_magic;                /* Magic signature */
        __u16   s_state;                /* File system state */
        __u16   s_errors;               /* Behaviour when detecting errors */
        __u16   s_pad;
        __u32   s_lastcheck;            /* time of last check */
        __u32   s_checkinterval;        /* max. time between checks */
        __u32   s_creator_os;           /* OS */
        __u32   s_rev_level;            /* Revision level */
        __u16   s_def_resuid;           /* Default uid for reserved blocks */
        __u16   s_def_resgid;           /* Default gid for reserved blocks */
        __u32   s_reserved[235];        /* Padding to the end of the block */
};

Taula descriptora del grup de blocs

En el següent bloc darrere del superblock, trobem la taula descriptora del grup de blocs. Per aixó está en la direcció 2048, que és la del principi del tercer bloc.

0000800: 0600 0000 0700 0000 0800 0000 d603 7300  ..............s.
0000810: 0300 0400 0000 0000 0000 0000 0000 0000  ................
0000820: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000830: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000840: 0000 0000 0000 0000 0000 0000 0000 0000  ................
  • 0600 0000: bg_block_bitmap 32 bits per al id del primer bloc del mapa de bits de blocs per a aquest grup.
  • 0700 0000: bg_inode_bitmap id del primer bloc per al mapa de bits de inodes per a a quest grup.
  • 0800 0000: bg_inode_table id del primer bloc de la taula de inodes.
  • d603: bg_free_blocks_count Número de bloc lliures en aquest grup. 0x03d6 = 982
  • 7300: bg_free_inodes_count Número de inodes lliures en aquest grup 0x73 = 115
  • 0300: bg_used_dirs_count Número de inodes utilitzats per a directoris en aquest grup.
  • 0400: bg_pad Relleno per a omplir 32 bits
  • 0000 0000 0000 0000 0000 0000 Reservat per a futures ampliacions.

Mapa de bits de blocs

A continuació, anem a observar el mapa de bits de blocs. En sistemes de fitxers menuts es troba en el primer bloc o en el segon si hi ha un superbloc en el grup. En tot cas, es deu mirar el bg_block_bitmap. Este en diu que està en la posició 6. Per tant, como que cada bloc ocupa 1024 bytes, está en la 1024*6=6144 = 0x1800

0001800: ffff ffff ff01 0000 0000 0000 0000 0000  ................
0001810: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0001820: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Cada bit representa si un bloc està utilitzat (1) o lliure (0). Cal recordar que està en Little endian. Per tant, un bloc de 4 bytes com, per exemple: fffe ff01= 11111111 11111110 11111111 00000001 Quedaria transformat en: 11111111 011111111 11111111 10000000

Mapa d'inodes

Observem el mapa d'inodes. Com que el bg_inode_bitmap indica que està en el bloc 7 anem a mirar en 7*0x400=1C00

0001c00: ff1f 0000 0000 0000 0000 0000 0000 0000  ................
0001c10: ffff ffff ffff ffff ffff ffff ffff ffff  ................

Els primers 11 inodes queden marcats com a reservats.


Taula d'inodes

En aquest exemple, està situada en el bloc 8 que està en la posició de memòria 0x2000. Però els primers 11 inodes estan reservats per al sistema. Per tant, anem a estudiar un inode d'un fitxer normal.

Si fem:

$ xxd disc.img | grep -3 prova
0006000: 0200 0000 0c00 0102 2e00 0000 0200 0000  ................
0006010: 0c00 0202 2e2e 0000 0b00 0000 1400 0a02  ................
0006020: 6c6f 7374 2b66 6f75 6e64 0000 0c00 0000  lost+found......
0006030: 1000 0602 7072 6f76 6131 0000 0d00 0000  ....prova1......
0006040: c403 0601 7072 6f76 6132 0000 0000 0000  ....prova2......
0006050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0006060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0006070: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Ens diu que, per exemple, prova2, está en el inode 0x0d = 13. Com que cada inode ocupa 128 bytes, tenim que buscar la posició 12*128+0x2000=0x2600

0002600: a481 0000 000a 0000 5a76 af51 5a76 af51  ........Zv.QZv.Q
0002610: 5a76 af51 0000 0000 0000 0100 0600 0000  Zv.Q............
0002620: 0000 0000 0000 0000 2700 0000 2800 0000  ........'...(...
0002630: 2900 0000 0000 0000 0000 0000 0000 0000  )...............
0002640: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0002650: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0002660: 0000 0000 059e 00ec 0000 0000 0000 0000  ................
0002670: 0000 0000 0000 0000 0000 0000 0000 0000  ................


  • a481: i_mode: En 16 bits indica el format i els drets d'accés. Hi ha múltiples máscares que es poden aplicar de moltes maneres. Més informació: [2][3]. És més fàcil treballar en ell en octal. Queda de la següent manera: 0x81a4 = 100644. Els 3 últims dígits són els permissos. El bit 9 és VTX, 10 és Setgid i 11 setuid. Els últims dígits signifiquen 10 que és un fitxer regular.
  • 0000: i_uid UID del propietari (0=root).
  • 000a 0000: i_size Mida del fitxer. En posteriors revisions, si la mida és més gran, els altres 32 bits es guarden en el camp i_dir_acl
  • 5a76 af51: i_atime Segons des de 1/1/1970 que s'ha accedit a l'inode.
  • 5a76 af51: i_ctime Data en que s'ha creat.
  • 5a76 af51: i_mtime Data en que s'ha modificat.
  • 0000 0000: i_dtime Data en que s'ha esborrat.
  • 0000: i_gid GID. (0=root)
  • 0100: i_links_count Número de hard links que té el fitxer.
  • 0600 0000</span: i_blocks Número de blocs que ocupa.
  • 0000 0000: i_flags Indica aspectes del comportament quant s'accedeix a aquest fitxer. No tots els bits estan definits. Aquest són alguns dels més importants:
   bit 0 - Secure deletion. When this bit is on, the file's blocks are zeroed when the file is deleted. With this bit off, they will just be left with their original data when the inode is deallocated.
   bit 1 - Undelete. This bit is not supported yet. It will be used to provide an undelete feature in future Ext2fs developments.
   bit 2 - Compress file. This bit is also not supported. The plan is to offer "compression on the fly" in future releases.
   bit 3 - Synchronous updates. With this bit on, the meta-data will be written synchronously to the disk, as if the filesystem was mounted with the "sync" mount option.
   bit 4 - Immutable file. When this bit is on, the file will stay as it is - Can not be changed, deleted, renamed, no hard links, etc, before the bit is cleared.
   bit 5 - Append only file. With this option active, data will only be appended to the file.
   bit 6 - Do not dump this file. I think that this bit is used by the port of dump to linux (ported by Remy Card) to check if the file should not be dumped.
  • 0000 0000: i_osd1 Bits reservats per al sistema operatiu.
  • 2700 0000 2800 0000 2900 0000 0000 0000 ... : i_block Array de 15x32 bits. Els primers 12 són directes. El 13 és per al bloc indirecte. Com que cada bloc té 1024, les direccions dels blocs 13 a 268. El 14 és per al doble indirecte. Com que té 1024, pot apuntat a 256 blocs indirectes de 256 direccions de bloc possibles. Per tant, 65536 blocs. El 15 és per al triple indirecte, que pot direccionar fins a 16777216 blocs.
  • 059e 00ec: i_generation Indica la versió del fitxer. Utilitzat per NFS.
  • 0000 0000: i_file_acl ACL del fitxer.
  • 0000 0000: i_dir_acl ACL del directori. Aquest camp i el anterior poden contindre el bloc on es guarden atributs extesos.
  • 0000 0000: i_faddr Localització del fragment. En ETX4 ha quedat obsolet.
  • 0000 0000 0000 0000 0000 0000: Inode i_osd2 Structure 96 bits que depenen del sistema operatiu. En Linux hi ha informació sobre fragments, encara que no està suportada. També estan els 16 bits més significatius del UID o el GID en cas que siga necessari.


Struct d'un inode:

struct ext2_inode {
        __u16   i_mode;         /* File mode */
        __u16   i_uid;          /* Owner Uid */
        __u32   i_size;         /* Size in bytes */
        __u32   i_atime;        /* Access time */
        __u32   i_ctime;        /* Creation time */
        __u32   i_mtime;        /* Modification time */
        __u32   i_dtime;        /* Deletion Time */
        __u16   i_gid;          /* Group Id */
        __u16   i_links_count;  /* Links count */
        __u32   i_blocks;       /* Blocks count */
        __u32   i_flags;        /* File flags */
        union {
                struct {
                        __u32  l_i_reserved1;
                } linux1;
                struct {
                        __u32  h_i_translator;
                } hurd1;
                struct {
                        __u32  m_i_reserved1;
                } masix1;
        } osd1;                         /* OS dependent 1 */
        __u32   i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
        __u32   i_version;      /* File version (for NFS) */
        __u32   i_file_acl;     /* File ACL */
        __u32   i_dir_acl;      /* Directory ACL */
        __u32   i_faddr;        /* Fragment address */
        union {
                struct {
                        __u8    l_i_frag;       /* Fragment number */
                        __u8    l_i_fsize;      /* Fragment size */
                        __u16   i_pad1;
                        __u32   l_i_reserved2[2];
                } linux2;
                struct {
                        __u8    h_i_frag;       /* Fragment number */
                        __u8    h_i_fsize;      /* Fragment size */
                        __u16   h_i_mode_high;
                        __u16   h_i_uid_high;
                        __u16   h_i_gid_high;
                        __u32   h_i_author;
                } hurd2;
                struct {
                        __u8    m_i_frag;       /* Fragment number */
                        __u8    m_i_fsize;      /* Fragment size */
                        __u16   m_pad1;
                        __u32   m_i_reserved2[2];
                } masix2;
        } osd2;                         /* OS dependent 2 */
};


Localitzant un inode

Els inodes estan ordenats numéricament en la taula d'inodes. La mida d'aquesta taula es fixa quant se formata el sistema d'arxius. Aquesta taula está dividida en parts iguals entre tots els grups de blocs. La variable s_inodes_per_group en el superbloc, indica els inodes que trobarem en cada grup.

Podem calcular on trobarem el inode amb la fórmula:

grup de blocs = (inode - 1)/s_inodes_per_group

Una vegada hem detectat el bloc, podem calcular el índex dins de la taula d'inodes local amb:

local inode index = (inode - 1)%s_inodes_per_group

Directoris

Per trobar el directori arrel, hem fet ús del grep.

$ xxd disc.img | grep -3 prova
0006000: 0200 0000 0c00 0102 2e00 0000 0200 0000  ................
0006010: 0c00 0202 2e2e 0000 0b00 0000 1400 0a02  ................
0006020: 6c6f 7374 2b66 6f75 6e64 0000 0c00 0000  lost+found......
0006030: 1000 0602 7072 6f76 6131 0000 0d00 0000  ....prova1......
0006040: c403 0601 7072 6f76 6132 0000 0000 0000  ....prova2......
0006050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0006060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0006070: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Anem a observar cóm està formada cada entrada en el directori.

Els directoris poden ser llistes enllaçades o indexats. Els indexats són compatibles amb les llistes enllaçades. Aquest exemple utilitza llistes enllaçades. Però quant augmenta la mida d'un directori, pot utilitzar índex.

Respecte a l'entrada del fitxer prova2:

  • 0d00 0000: inode Aquest és el 0x0d, és a dir, 13.
  • c403: rec_len Desplaçament fins a la següent entrada del directori. Com que és el últim element. 0x03c4 = 964, indica el final del bloc d'aquest directori. El fitxer anterior té com a valor 0x0010 = 16, que és el desplaçament des del principi de prova1 fins al principi de prova2. Les entrades han de tindre una mida múltiple de 4bytes. Per plenar, utilitza 0s.
  • 06: namelen Longitud en bytes del nom del fitxer. Com que té 6 caracters, són 6 bytes. Observem que dona un llimit de 255 bytes al nom d'un fitxer.
  • 01: file_type Indica el tipus de fitxer. 01 significa un fitxer regular, 02 un directori.
  • 7072 6f76 6132: name El nom en ISO-Latin-1. Aquest camp té la longitud que indica namelen


Struct d'un directori:

struct ext2_dir_entry {
        __u32   inode;                  /* Inode number */
        __u16   rec_len;                /* Directory entry length */
        __u16   name_len;               /* Name length */
        char    name[EXT2_NAME_LEN];    /* File name */
};

Enllaços

http://www.barnech.com/uai-sistemas/arq_so/Linux/sistema_de_archivos_ext2.htm

http://en.wikipedia.org/wiki/Inode

http://acacha.org/mediawiki/index.php/Sistemes_de_fitxers#Sistemes_de_fitxers_Unix

http://www.nongnu.org/ext2-doc/ext2.html