Acabei de comprar um SSD SATA e um adaptador USB-SATA. Escolhi um adaptador com suporte a UASP, pois achei que possibilitaria a execução de um comando TRIM/DISCARD, e acho importante para a vida útil do SSD.
Quando conecto o adaptador ao meu computador baseado em Debian, o kernel linux o detecta como esperado e habilita a comunicação com o protocolo UAS. Aqui está o que o kernel relata:
[23886.083296] usb 2-1: new SuperSpeed Gen 1 USB device number 6 using xhci_hcd
[23886.104497] usb 2-1: New USB device found, idVendor=174c, idProduct=55aa, bcdDevice= 1.00
[23886.104508] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=1
[23886.104513] usb 2-1: Product: 00SSD1
[23886.104518] usb 2-1: Manufacturer: CT500MX5
[23886.104522] usb 2-1: SerialNumber: 12345678D9DA
[23886.110042] scsi host1: uas
[23886.110883] scsi 1:0:0:0: Direct-Access CT500MX5 00SSD1 0 PQ: 0 ANSI: 6
[23886.111967] scsi 1:0:0:0: Attached scsi generic sg1 type 0
[23886.112698] sd 1:0:0:0: [sdb] 976773168 512-byte logical blocks: (500 GB/466 GiB)
[23886.112702] sd 1:0:0:0: [sdb] 4096-byte physical blocks
[23886.112841] sd 1:0:0:0: [sdb] Write Protect is off
[23886.112846] sd 1:0:0:0: [sdb] Mode Sense: 43 00 00 00
[23886.113013] sd 1:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[23886.113224] sd 1:0:0:0: [sdb] Optimal transfer size 33553920 bytes not a multiple of physical block size (4096 bytes)
lsusb
confirma que o uas
driver é usado:
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/7p, 5000M
|__ Port 1: Dev 6, If 0, Class=Mass Storage, Driver=uas, 5000M
Mas não consigo executar blkdiscard
neste dispositivo:
# blkdiscard -f /dev/sdb
blkdiscard: /dev/sdb contains existing partition (dos).
blkdiscard: Operation forced, data will be lost!
blkdiscard: /dev/sdb: BLKDISCARD ioctl failed: Operation not supported
lsblk
confirma que o dispositivo de bloco não suporta descarte:
# lsblk -D /dev/sdb
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sdb 0 0B 0B 0
`-sdb1 0 0B 0B 0
De onde vem o problema? Existe alguma esperança de que eu possa executar TRIM/DISCARD com esta configuração?
Depois de alguma leitura (obrigado harrymc pelo link no comentário), acho que agora posso entender muito melhor o que está acontecendo.
Em primeiro lugar, era ingênuo pensar que usar uma ponte USB-SATA habilitada para UASP com um SSD SATA recente (que suporta TRIMming) obviamente suportaria UNMAPping.
A realidade é que uma ponte USB-SATA habilitada para UASP tem duas funções principais:
O conjunto de comandos definidos pelo protocolo SCSI é bastante grande e nem todos os dispositivos SCSI suportam todos os comandos. Portanto, existem vários comandos que podem ser usados para UNMAP. Um tradutor SCSI-ATA pode suportar um deles, talvez vários, mas também pode não suportar nenhum. Neste último caso, não seria possível o bloco UNMAP do SSD. Felizmente, meu tradutor SCSI-ATA na minha ponte USB-SATA suporta o comando UNMAP.
Devido à riqueza do conjunto de comandos SCSI, um driver precisa saber quais recursos são suportados por um dispositivo. Isso é feito com algumas páginas de informações, chamadas de páginas VPD (Vital Product Data), fornecidas pelo dispositivo ao driver. A “primeira” página é a página “Páginas VPD suportadas” que lista as páginas que o dispositivo suporta.
Normalmente, o driver consulta a “primeira” página e, em seguida, consulta as páginas interessantes, se houver suporte. Quanto à capacidade de UNMAP, a página interessante é a página “Aprovisionamento de bloco lógico”.
Com o linux, pode-se consultar as páginas “Supported VPD pages” e “Logical block provisioning” como esta:
Aqui, pode-se ver que “my” SCSI-ATA tradutor suporta o comando unmap mas não suporta os comandos Write Same (16) ou Write Same (10) com unmap bit.
Normalmente, o driver leria essas páginas e configuraria o dispositivo de acordo. Infelizmente, aparentemente há um histórico de dispositivos USB quebrados que travam ou bloqueiam quando algumas páginas VPD são consultadas. Assim, os desenvolvedores do kernel linux decidiram por padrão não consultar páginas VPD para dispositivos SCSI conectados por USB e não configurar recursos avançados como o UNMAP.
A boa notícia é que ainda é possível configurar esses recursos a partir do userspace, usando o arquivo especial
/sys/block/sdb/device/scsi_disk/1:0:0:0/provisioning_mode
(o caminho pode variar). Quando conecto meu adaptador, ele lê “full”, mas posso configurá-lo como “unmap”, pois meu dispositivo suporta o comando unmap. Os outros valores suportados são “writesame_16”, “writesame_10”, “writesame_zero” e “disabled”.Pode-se ir além e configurar uma regra udev para configurar esse dispositivo automaticamente:
(o idVendor, idProduct e provisioning_mode dependem da ponte USB-SATA)
De qualquer forma, não posso recomendar isso, pois um erro pode bloquear seu dispositivo e até tentar ler as páginas do VPD com
sg_vpd
força.Também não sei o quão útil é configurar a
discard_max_bytes
configuração, conforme sugerido pelo ótimo Habilitando TRIM em um SSD externo em um artigo Raspberry Pi .Algumas boas notícias novamente, há um patch que ignora a restrição para dispositivos SCSI conectados por USB em alguns casos em que parece seguro fazê-lo, e acho que deve fazê-lo para as pontes USB-SATA habilitadas para UASP mais recentes. Eu (ainda) não tentei; aparentemente não chegou ao linux 6.0-rc4; Não sei se há planos para solicitar sua fusão em um futuro próximo.