Surpreendentemente grande sobrecarga ao criar pequeno volume ubifs

4

Em uma partição mtd com 39 blocos de apagamento (= 4,9 MiB), tentei formatar um ubifs. O sistema de arquivos resultante possui espaço livre de dados não compactados de 2,2 M quando os blocos reservados são reduzidos ao mínimo 1 bloco possível (sei que isso não é bom). Isso significa que apenas 45% do espaço é utilizável para dados.

A mesma área formatada com jffs2 me permite gravar 4,6 MB de dados que são 93% ou mais do que o dobro do tamanho em uma configuração ubifs.

O problema é que eu não posso usar o jffs2 porque meu tamanho OOB de 64 bytes não fornece espaço suficiente para os dados BCH8 e JFFS2 OBB, como descrito em um Aviso de TI .

Eu já li os capítulos das perguntas frequentes Por que meu volume UBIFS tem capacidade significativamente menor do que meu volume JFFS2 equivalente? e Por que o df reporta pouco espaço livre? mas ainda não consigo acreditar que a sobrecarga é tão grande.

Existe algo que eu possa fazer para aumentar o espaço livre do meu volume ubifs (gravável)?

Economizo espaço quando mesclo ubi0 e ubi1? (mais que os blocos reservados?)

Esta é minha configuração:

$ mtdinfo -a

mtd10
Name:                           NAND.userdata
Type:                           nand
Eraseblock size:                131072 bytes, 128.0 KiB
Amount of eraseblocks:          39 (5111808 bytes, 4.9 MiB)
Minimum input/output unit size: 2048 bytes
Sub-page size:                  512 bytes
OOB size:                       64 bytes
Character device major/minor:   90:20
Bad blocks are allowed:         true
Device is writable:             true

$ ubinfo -a

ubi1
Volumes count:                           1
Logical eraseblock size:                 129024 bytes, 126.0 KiB
Total amount of logical eraseblocks:     39 (5031936 bytes, 4.8 MiB)
Amount of available logical eraseblocks: 0 (0 bytes)
Maximum count of volumes                 128
Count of bad physical eraseblocks:       0
Count of reserved physical eraseblocks:  1
Current maximum erase counter value:     2
Minimum input/output unit size:          2048 bytes
Character device major/minor:            249:0
Present volumes:                         0

Volume ID:   0 (on ubi1)
Type:        dynamic
Alignment:   1
Size:        34 LEBs (4386816 bytes, 4.2 MiB)
State:       OK
Name:        userdata
Character device major/minor: 249:1

dmesg:
[    1.340937] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1
[    1.347903] nand: Micron MT29F1G08ABADAH4
[    1.352108] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    1.359782] nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme

uname -a:
Linux 4.1.18-g543c284-dirty #3 PREEMPT Mon Jun 27 17:02:46 CEST 2016 armv7l GNU/Linux

Crie & teste ubifs:

# flash_erase /dev/mtd10 0 0
Erasing 128 Kibyte @ 4c0000 -- 100 % complete 
# ubiformat /dev/mtd10 -s 512 -O 512
ubiformat: mtd10 (nand), size 5111808 bytes (4.9 MiB), 39 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 38 -- 100 % complete  
ubiformat: 39 eraseblocks are supposedly empty
ubiformat: formatting eraseblock 38 -- 100 % complete  
# ubiattach -d1 -m10 -b 1
UBI device number 1, total 39 LEBs (5031936 bytes, 4.8 MiB), available 34 LEBs (4386816 bytes, 4.2 MiB), LEB size 129024 bytes (126.0 KiB)
# ubimkvol /dev/ubi1 -N userdata -m
Set volume size to 4386816
Volume ID 0, size 34 LEBs (4386816 bytes, 4.2 MiB), LEB size 129024 bytes (126.0 KiB), dynamic, name "userdata", alignment 1
# mount -t ubifs ubi1:userdata /tmp/1
# df -h /tmp/1
Filesystem      Size  Used Avail Use% Mounted on
-               2.1M   20K  2.0M   2% /tmp/1
# dd if=/dev/urandom of=/tmp/1/bigfile bs=4096
dd: error writing '/tmp/1/bigfile': No space left on device
550+0 records in
549+0 records out
2248704 bytes (2.2 MB) copied, 1.66865 s, 1.3 MB/s
# ls -l /tmp/1/bigfile
-rw-r--r-- 1 root root 2248704 Jan  1 00:07 /tmp/1/bigfile
# sync
# df -h /tmp/1
Filesystem      Size  Used Avail Use% Mounted on
-               2.1M  2.1M     0 100% /tmp/1

Crie & teste jffs2:

# mkdir /tmp/empty.d
# mkfs.jffs2 -s 2048 -r /tmp/empty.d -o /tmp/empty.jffs2
# flash_erase /dev/mtd10 0 0
Erasing 128 Kibyte @ 4c0000 -- 100 % complete 
# nandwrite /dev/mtd10 /tmp/empty.jffs2
Writing data to block 0 at offset 0x0
# mount -t jffs2 /dev/mtdblock10 /tmp/1
# df -h /tmp/1
Filesystem      Size  Used Avail Use% Mounted on
-               4.9M  384K  4.5M   8% /tmp/1
# dd if=/dev/urandom of=/tmp/1/bigfile bs=4096
dd: error writing '/tmp/1/bigfile': No space left on device
1129+0 records in
1128+0 records out
4620288 bytes (4.6 MB) copied, 4.54715 s, 1.0 MB/s
# ls -l /tmp/1/bigfile
-rw-r--r-- 1 root root 4620288 Jan  1 00:20 /tmp/1/bigfile
# sync
# df -h /tmp/1
Filesystem      Size  Used Avail Use% Mounted on
-               4.9M  4.9M     0 100% /tmp/1

Atualização:

Eu fiz algumas medições de massa que resultaram no seguinte gráfico:

Paraqueeupossaformularminhaperguntadeformamaisespecíficaagora:

A"fórmula" parece ser usable_size_mb = (raw_size_mb - 2.3831) * 0.89423077

Em outras palavras: não importa o tamanho do meu mtd, sempre há 2.38 MB perdidos, não importa o tamanho do nosso volume. Esse é o tamanho de 19 blocos de apagamento . O resto é uma sobrecarga do sistema de arquivos de 10,6% dos dados do usuário, que é um valor alto, mas não inesperado para ubifs.

Entre. Ao fazer os testes, recebi avisos do kernel de que pelo menos 17 blocos de apagamento são necessários (= 2.176 MB). Mas o menor mtd que passou com sucesso pelo teste teve 22 blocos (2.816 MB).

    
por Daniel Alder 08.07.2016 / 15:17

1 resposta

2

Por que os números não correspondem

O aviso "pelo menos 17 blocos de apagamento" conta os blocos necessários ao próprio sistema de arquivos UBIFS. Desses 17 blocos de apagamento, 14 são a sobrecarga de UBIFS e 3 são utilizáveis no espaço do sistema de arquivos. A camada UBI subjacente abaixo também usa 5 blocos de exclusão de sobrecarga.

Obtendo mais espaço

Não há como uma única partição UBI com um único sistema de arquivos UBIFS usar menos sobrecarga.

No entanto, se você tiver mais de uma partição UBI no mesmo dispositivo MTD, recomendo mesclá-las. Não só liberará 5 blocos de apagamento, mas também melhorará o nivelamento de desgaste e o manuseio de blocos defeituosos, pois o UBI terá mais opções para mapear blocos de apagamento físico para blocos de apagamentos lógicos, conforme necessário.

(Ignorando a sobrecarga, imagine duas partições de dois blocos cada, uma das quais é ruim. Agora uma partição só tem um bloco sobrando, e é impossível usar o nivelamento. Mas se você mesclar os dois, então você tem três bons blocos deixados para compartilhar entre os dois sistemas de arquivos conforme necessário.)

Para mesclar duas partições UBI adjacentes:

  • Atualize sua tabela de partições MTD, substituindo as duas partições por uma maior.
  • Execute ubiformat nessa única partição grande.
  • Execute ubimkvol duas vezes, fornecendo nomes de partições apropriados e especificando os tamanhos manualmente com -s ou -S .

Uma contabilização da sobrecarga UBI + UBIFS

Primeiro, a camada UBI leva 5 blocos de exclusão de sobrecarga:

  • 2 para a tabela de volumes
  • 1 reservado para o algoritmo de nivelamento de desgaste
  • 1 reservado para o recurso "mudança de LEB atômica", que permite atualizações in-loco confiáveis de um bloco de apagamento lógico
  • 1 (idealmente mais, como você mencionou) reservado para o manuseio de bloqueios físicos incorretos.

Em seguida, a camada UBIFS tem um número mínimo de blocos de apagamento para os metadados do sistema de arquivos:

  • 1 para o superbloco do sistema de arquivos, que identifica o volume como um UBIFS válido e armazena os parâmetros do sistema de arquivos
  • 2 para a área do nó mestre (cópias redundantes), que são as raízes da árvore usada para pesquisas no sistema de arquivos
  • 2 ou mais para a área de registro (que conta para o espaço utilizável)
  • 2 para a árvore de propriedades do LEB, que controla como cada bloco de apagamento lógico é usado
  • 1 ou mais para a área órfã (para rastrear arquivos excluídos, para que eles sejam limpos corretamente após uma desmontagem não limpa)
  • 8 reservados para metadados do sistema de arquivos (coleta de lixo, exclusões, brotos, índice)
  • 1 ou mais para dados confirmados que não estão no log (espaço utilizável).

Referências

Para a sobrecarga de UBI, o site linux-mtd tem uma descrição direta .

Para a sobrecarga de UBIFS, eu tive que fazer um pouco mais de escavação. O código-fonte do mtd-utils conta o número mínimo absoluto de blocos de apagamento e menciona para que serve cada bloco. Para entender, o whitepaper da UBIFS é útil.

    
por 10.07.2018 / 22:12