¿Por qué el nivel de fragmentación es tan grande en los archivos que contienen otros sistemas de archivos?

8

Acabo de descubrir qué son los archivos dispersos y quería realizar algunos experimentos con ellos. En wiki puedes leer que los archivos pueden fragmentarse fácilmente. Quería comprobar qué tan malo es eso. Creé un archivo de la siguiente manera:

# truncate -s 10G sparse-file
# mkfs.ext4 -m 0 -L sparse ./sparse-file

Monté el archivo disperso y puse un archivo de 600M en él. El nivel de fragmentación se ve así:

# filefrag -v "/media/Grafi/sparse-file"
Filesystem type is: ef53
File size of /media/Grafi/sparse-file is 10737418240 (2621440 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..    1032:      36864..     37896:   1033:
   1:     1043..    1043:      37907..     37907:      1:
   2:     1059..    1059:      37923..     37923:      1:
   3:     9251..    9256:      46115..     46120:      6:
   4:    32768..   32770:      51200..     51202:      3:      69632:
   5:    34816..   55295:      77824..     98303:  20480:      53248:
   6:    55296..   57343:     114688..    116735:   2048:      98304:
   7:    57344..   69631:     120832..    133119:  12288:     116736:
   8:    69632..   81919:     102400..    114687:  12288:     133120:
   9:    81920..   98303:     135168..    151551:  16384:     114688:
  10:    98304..   98306:      57344..     57346:      3:     151552:
  11:   100352..  112639:     151552..    163839:  12288:      59392:
  12:   112640..  145407:     165888..    198655:  32768:     163840:
  13:   145408..  163839:     198656..    217087:  18432:
  14:   163840..  163842:      40960..     40962:      3:     217088:
  15:   165888..  178175:     217088..    229375:  12288:      43008:
  16:   178176..  202751:     231424..    255999:  24576:     229376:
  17:   202752..  206847:     258048..    262143:   4096:     256000:
  18:   206848..  216756:     276480..    286388:   9909:     262144:
  19:   229376..  229378:      43008..     43010:      3:     299008:
  20:   294912..  294914:      53248..     53250:      3:     108544:
  21:   524288..  524288:      55296..     55296:      1:     282624:
  22:   819200..  819202:      61440..     61442:      3:     350208:
  23:   884736..  884738:      63488..     63490:      3:     126976:
  24:  1048576.. 1048577:      67584..     67585:      2:     227328:
  25:  1081344.. 1081391:      69632..     69679:     48:     100352:
  26:  1572864.. 1572864:      71680..     71680:      1:     561152:
  27:  1605632.. 1605634:      73728..     73730:      3:     104448:
  28:  2097152.. 2097152:      75776..     75776:      1:     565248:
  29:  2097167.. 2097167:      75791..     75791:      1:             last
/media/Grafi/sparse-file: 25 extents found

Pensé que era debido a la función "dispersa", pero parece que todos los archivos que tienen otros sistemas de archivos se fragmentan de esta manera. Eche un vistazo al siguiente ejemplo:

Crea un archivo lleno de ceros:

# dd if=/dev/zero of=./zero bs=1M count=2048 

Verifique su nivel de fragmentación:

# filefrag -v /media/Grafi/zero
Filesystem type is: ef53
File size of /media/Grafi/zero is 2147483648 (524288 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..   32767:    6172672..   6205439:  32768:
   1:    32768..   65535:    6205440..   6238207:  32768:
   2:    65536..   98303:    6238208..   6270975:  32768:
   3:    98304..  118783:    6270976..   6291455:  20480:
   4:   118784..  151551:    6324224..   6356991:  32768:    6291456:
   5:   151552..  184319:    6356992..   6389759:  32768:
   6:   184320..  217087:    6389760..   6422527:  32768:
   7:   217088..  249855:    6422528..   6455295:  32768:
   8:   249856..  282623:    6455296..   6488063:  32768:
   9:   282624..  315391:    6488064..   6520831:  32768:
  10:   315392..  348159:    6520832..   6553599:  32768:
  11:   348160..  380927:    6553600..   6586367:  32768:
  12:   380928..  413695:    6586368..   6619135:  32768:
  13:   413696..  446463:    6619136..   6651903:  32768:
  14:   446464..  479231:    6651904..   6684671:  32768:
  15:   479232..  511999:    6684672..   6717439:  32768:
  16:   512000..  524287:    6717440..   6729727:  12288:             last,eof
/media/Grafi/zero: 2 extents found

Básicamente, este archivo tiene 17 extensiones, pero desde la perspectiva humana, el archivo tiene dos fragmentos

Ahora cree un sistema de archivos en este archivo:

# mkfs.ext4 -m 0 -L ext /media/Grafi/zero

Verifique su fragmentación nuevamente:

# filefrag -v /media/Grafi/zero

Filesystem type is: ef53
File size of /media/Grafi/zero is 2147483648 (524288 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..     257:    5505024..   5505281:    258:
   1:      265..     265:    5505289..   5505289:      1:
   2:      272..     273:    5505296..   5505297:      2:
   3:      289..     289:    5505313..   5505313:      1:
   4:     8481..    8486:    5507361..   5507366:      6:    5513505:
   5:    32768..   32769:    5509120..   5509121:      2:    5531648:
   6:    98304..   98305:    5511168..   5511169:      2:    5574656:
   7:   163840..  163841:    5513216..   5513217:      2:    5576704:
   8:   229376..  229377:    5515264..   5515265:      2:    5578752:
   9:   262144..  262144:    5517312..   5517312:      1:    5548032:
  10:   294912..  294913:    5519360..   5519361:      2:    5550080: last
/media/Grafi/zero: 8 extents found

¿Alguien sabe lo que realmente sucedió aquí? ¿Por qué el archivo se fragmentó al crear un sistema de archivos en él? ¿Qué pasó con el length?

Adicional:

El mkfs.ext4parámetro -Enodiscardno funciona. Con esta opción puedo ver la estructura del archivo en filefrag(los bloques puestos a cero). Pero después de crear el sistema de archivos de esta manera, el archivo se fragmenta por alguna razón, sin importar qué. Tal vez sea por los metadatos del sistema de archivos que están escritos, y hace algo al archivo puesto a cero. No lo sé. Pero cuando veo la salida de filefrag, puedo ver que siempre hay extensiones de +6 (en el caso del archivo 2G). ¿Quizás es por el superbloque y sus 5 copias? Pero esto todavía no explica por qué todo el archivo está fragmentado, sigue siendo el mismo archivo.

Hay otra cosa Cuando recrea el sistema de archivos en este archivo:

# mkfs.ext4 -Enodiscard /media/Grafi/zero
mke2fs 1.43 (17-May-2016)
/media/Grafi/zero contains a ext4 file system
        created on Thu Jun  2 13:02:28 2016
Proceed anyway? (y,n) y
Creating filesystem with 524288 4k blocks and 131072 inodes
Filesystem UUID: 6d58dddc-439b-4175-9af6-8628f0d2a278
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

Las extensiones agregadas desaparecen mágicamente.

Mikhail Morfikov
fuente

Respuestas:

2

Parece que esto fue un error mke2fsque causó su uso en fallocate(fd, PUNCH_HOLE, ...)lugar de fallocate(fd, DISCARD_ZERO, ...)al poner a cero el espacio en las tablas de inodo (incluso cuando -E nodiscardse usó).

Envié un informe de error a la [email protected]lista de correo ascendente después de verificar este comportamiento localmente, y obtuve un parche en una hora, asunto:

e2fprogs: block zero/discard cleanups

Deben incluirse en la versión e2fsprogs-1.45, y probablemente en la versión de mantenimiento 1.44.x. Si los quiere en una e2fsprogsversión de proveedor , le recomiendo parchear + construir sus e2fsprogs para verificar que esto funcione para usted, informar sobre el éxito para linux-ext4que los parches lleguen antes, luego enviar un informe de error a su distribución de elección para que puedan extraiga los parches aguas arriba en sus lanzamientos.

LustreOne
fuente
Estas hablando de esto? patchwork.ozlabs.org/cover/899596
Mikhail Morfikov
Ese es el ... Ted dijo que también se incluiría en la versión de mantenimiento 1.44.
LustreOne
0
$ /sbin/mkfs.ext4 test1
mke2fs 1.42.12 (29-Aug-2014)
Discarding device blocks: done
[...]

Ahora hay una pista. Veamos qué dice el manual:

-E extended-options
discard
  Attempt  to  discard blocks at mkfs time (discarding blocks initially is useful
  on solid state devices and sparse / thin-provisioned storage). When the  device
  advertises that discard also zeroes data (any subsequent read after the discard
  and before write returns zero), then mark all not-yet-zeroed  inode  tables  as
  zeroed.  This significantly speeds up filesystem initialization. This is set as
  default.

Entonces, básicamente, mkfs sabe que los datos antiguos en el almacenamiento subyacente ya no importan, por lo que pueden descartarse, y el almacenamiento subyacente podría tener una mejor manera de hacerlo, que simplemente sobrescribiendo con ceros. Lo que tiene, el sistema de archivos aquí puede olvidarse de los bloques de datos.

Después de eso, mkfs construye cualquier estructura de sistema de archivos que necesite, en un patrón de acceso algo aleatorio, lo que resulta en la asignación de nuevos bloques de datos. El archivo es escaso nuevamente y hay algo de fragmentación.

Con -Enodiscardel resultado quizás sea lo que esperabas:

$ /sbin/mkfs.ext4 -Enodiscard test2
$ /usr/sbin/filefrag test2
test2: 2 extents found
ilkkachu
fuente
Acabo de actualizar la pregunta, verla para obtener información.
Mikhail Morfikov