1. Qué significa copiar al escribir
En el tema 33 estudiamos cómo un diario ayuda a recuperar cambios comprometidos. Otra técnica importante consiste en escribir una versión modificada en espacio nuevo antes de hacerla accesible desde los metadatos que la referencian.
Copy-on-write (COW): técnica que conserva una versión existente mientras prepara otra y cambia las referencias necesarias para publicar la modificación. Cuando varias versiones comparten datos, escribir en una de ellas debe preservar los bytes que todavía pertenecen a las demás.
Una analogía útil es corregir una página de un manual conservando la edición anterior: se prepara la página nueva y se actualiza el índice de la edición actual. Las páginas que no cambiaron pueden seguir siendo las mismas para ambas ediciones.
La frase «no sobrescribir nunca» resume una idea, pero no describe todas las escrituras de Btrfs o ZFS. Hay estructuras de control, reutilización de espacio y opciones particulares. En Btrfs, además, existen archivos con NOCOW. En este tema trabajaremos con archivos regulares en su configuración COW habitual, sin activar esas excepciones. Véase la introducción de Btrfs.
2. Bloques, árboles y publicación de una raíz
No basta con copiar un bloque de datos: también hay que registrar dónde está. Si la referencia reside en un nodo compartido del árbol de metadatos, actualizarla puede exigir una nueva versión de ese nodo y de sus antecesores. Al final, una raíz permite alcanzar el estado publicado.
La recuperación necesita distinguir raíces válidas y respetar el orden de persistencia. COW no permite publicar referencias a datos que todavía no se han escrito correctamente. Los detalles de transacciones, logs y confirmaciones son propios de cada implementación; el dibujo no sustituye ese protocolo.
3. Referencias compartidas y liberación
Actual: [A, B, C] 3 bloques únicos
snapshot: [A, B, C] siguen siendo 3 bloques de datos únicos
cambiar B en actual:
Actual: [A, D, C]
Snapshot: [A, B, C] ahora hay 4 bloques de datos únicos
borrar snapshot:
Actual: [A, D, C] B ya no tiene referencias; puede liberarseContar versiones no equivale a multiplicar el tamaño del archivo. Se cuenta la unión de los bloques alcanzables desde las referencias vivas. En el ejemplo, sumar tres bloques por versión daría seis, aunque solo existen cuatro bloques de datos distintos.
En un sistema real también consumen espacio los metadatos, las reservas y la redundancia. La retirada de referencias puede procesarse de forma diferida. «Ya no es necesario para esta versión» no significa necesariamente «el contador de espacio disponible cambió en este instante».
4. Qué conserva una instantánea
Una instantánea o snapshot permite acceder a un estado de una unidad del sistema de archivos en un momento determinado. No requiere recorrer y duplicar todos los bytes como una copia convencional; mantiene referencias a datos existentes y conserva los que dejan de pertenecer a la versión activa.
Imagina un proyecto con configuración, fuentes y resultados. Si capturas su subvolumen antes de una modificación, podrás leer la versión capturada aunque los nombres activos hayan cambiado. Eso no incluye automáticamente un directorio que sea otro subvolumen, otro dataset o un montaje ajeno.
La instantánea representa el estado del sistema de archivos dentro de su alcance. No captura por sí sola buffers privados de un proceso, una respuesta pendiente de un servidor ni un servicio remoto. Su utilidad depende tanto del momento elegido como de qué objetos incluye.
5. Hard link, copia, reflink y snapshot
| Operación | Identidad y alcance | Escritura posterior |
|---|---|---|
| Hard link | Otro nombre del mismo inodo. | Modificar el objeto se observa desde ambos nombres. |
| Copia de bytes | Archivo distinto con contenido copiado. | Las modificaciones son independientes; no exige compartir extents. |
| Reflink | Archivo distinto que comparte inicialmente extents de datos. | COW mantiene privados los cambios de cada archivo. |
| Snapshot | Estado de un subvolumen o dataset. | La versión capturada conserva sus datos frente a cambios de la activa. |
Dos hashes iguales solo prueban igualdad del contenido observado según ese hash; no demuestran que los archivos compartan almacenamiento. Tampoco dos valores iguales de st_blocks permiten deducirlo: el espacio compartido puede contabilizarse en más de un archivo.
$ cp --reflink=always -- original.bin clon.bin
$ cp --reflink=never -- original.bin copia.bin
$ ln -- original.bin enlace.binEstos nombres deben ser nuevos dentro del ensayo. Con always, un reflink no disponible debe producir error, en lugar de sustituirse silenciosamente por una copia de bytes. Un hard link se limita al mismo sistema de archivos; un reflink también tiene restricciones de soporte y ubicación. Consulta FICLONE(2const) para el contrato de Linux.
6. Btrfs: subvolúmenes y límites de la captura
Btrfs permite organizar jerarquías como subvolúmenes. Parecen directorios al recorrerlos, pero tienen operaciones e identidad propias. Un snapshot de Btrfs es otro subvolumen con contenido inicial derivado del origen; puede ser escribible o crearse de solo lectura con -r.
btrfs subvolume create PUNTO/activo
btrfs subvolume snapshot -r PUNTO/activo PUNTO/antes
btrfs subvolume show PUNTO/antesLa captura no es recursiva sobre subvolúmenes anidados: el contenido de un subvolumen hijo no queda incluido como si fuera un directorio ordinario. Hay que planificar su captura por separado; varias órdenes independientes tampoco forman automáticamente un único instante común.
Solo lectura protege esa vista de escrituras ordinarias, pero no la vuelve inmutable frente al administrador. El alcance y los atributos se documentan en btrfs-subvolume(8).
7. ZFS: pools, datasets, snapshots y clones
En ZFS, un pool aporta almacenamiento a datasets. Un dataset de tipo filesystem puede tener su propio punto de montaje y propiedades. Un snapshot es de solo lectura; un clone proporciona una rama escribible a partir de una instantánea. No debe confundirse ese clone de dataset con el ioctl FICLONE de Linux para archivos individuales.
Esta es una secuencia ilustrativa para un dataset de laboratorio ya preparado. labpool es un nombre de ejemplo: no se crea ni se altera un pool del equipo para seguir el laboratorio Btrfs de este tema.
$ zfs list labpool/curso34
$ sudo zfs snapshot labpool/curso34@antes
$ zfs list -t snapshot -o name,used,refer
$ sudo zfs clone labpool/curso34@antes labpool/rama34
$ zfs get origin labpool/rama34
$ zpool status labpoolLa rama depende de su instantánea de origen; esa relación importa al administrar su ciclo de vida. Véase zfsconcepts(7). Con zfs snapshot -r se pueden capturar de forma conjunta los datasets descendientes; es una diferencia respecto a las capturas independientes de subvolúmenes Btrfs. Véase zfs-snapshot(8).
Recuperar un archivo copiándolo desde una instantánea permite seleccionar qué se restaura. Un rollback cambia el estado activo de una unidad más amplia y puede descartar modificaciones posteriores; no es necesario para las prácticas de este tema.
8. Checksums: detectar no siempre es reparar
Una suma de verificación se calcula a partir de datos y se compara al comprobarlos. Si los bytes almacenados cambian de forma accidental, una discrepancia permite detectar que no coinciden con lo esperado. Hay una probabilidad de colisión; un checksum tampoco certifica por sí solo autenticidad frente a un atacante.
Esperado: checksum del bloque original
Lectura A: checksum distinto → copia no válida
Lectura B: checksum esperado → posible fuente de recuperación
Sin copia válida: detectar el daño no reconstruye los bytes perdidos.La referencia esperada también debe protegerse. Conservar un checksum junto a datos que se pueden alterar arbitrariamente no constituye un protocolo completo de integridad. Las estructuras del formato relacionan las referencias con las verificaciones.
Una instantánea y la versión activa pueden apuntar al mismo bloque físico dañado: dos nombres lógicos no aportan dos réplicas independientes. Además, si una aplicación escribe por error un valor válido, el sistema calcula el checksum de ese valor equivocado. No sabe cuál era la intención del usuario.
9. Scrub, revisión estructural y copias externas
Un scrub recorre datos almacenados para verificar su integridad sin esperar a que una aplicación lea cada archivo. La reparación requiere una fuente válida y las condiciones que admite la implementación. En Btrfs, los datos de archivos NOCOW no tienen la protección de checksums de datos habitual; sus metadatos son otro asunto. Véase btrfs-scrub(8).
En ZFS se consulta el resultado con zpool status; la redundancia puede permitir corregir daños detectados. Scrub y resilver tienen objetivos distintos: el segundo reconstruye lo que un dispositivo necesita poner al día. Véase zpool-scrub(8).
| Mecanismo | Pregunta que ayuda a resolver |
|---|---|
| Snapshot | ¿Cómo accedo a una versión anterior capturada? |
| Scrub | ¿Los bloques verificables siguen concordando con sus checksums? |
| Comprobador estructural | ¿Son coherentes las relaciones internas que examina? |
| Copia externa y restauración probada | ¿Puedo recuperar los datos si pierdo el almacenamiento original? |
Una instantánea local no resuelve la pérdida del dispositivo, del pool completo o de las credenciales que permiten borrar todas las versiones. Btrfs send/receive y ZFS send/receive permiten transferir estados a otro almacenamiento, pero necesitan una política de conservación y pruebas de restauración. Tener una herramienta de transferencia no asegura por sí solo una copia recuperable.
10. Consistencia de aplicación y persistencia
Supongamos que una aplicación actualiza inventario.txt y luego pedidos.txt. Una captura entre ambos cambios puede conservar un sistema de archivos correcto y una operación de negocio incompleta. Capturar todos los nombres de una unidad no convierte varias llamadas en una transacción de aplicación.
Para una base de datos se sigue su procedimiento de backup: puede requerir coordinación, un punto de control o recuperación mediante su propio log. Si los datos están repartidos entre unidades, además hay que coordinar el alcance temporal de las capturas.
Los programas siguen comprobando write, pwrite, fsync y close. COW no elimina los errores de E/S, el espacio insuficiente ni la diferencia entre memoria del proceso y datos entregados al kernel. La llamada fsync del ejemplo confirma el archivo según el contrato del sistema; no convierte varias modificaciones lógicas en una transacción conjunta.
El tema 35 construirá el protocolo para publicar una nueva versión de un archivo desde C mediante temporal, fsync, rename y sincronización del directorio. Un reflink exitoso por sí solo no sustituye ese protocolo.
11. Espacio retenido y coste de las modificaciones
Un snapshot puede ser barato al crearse y retener mucho espacio después. Si reemplazas un archivo de 10 GiB por otro de igual tamaño, la instantánea puede seguir necesitando los datos antiguos. Borrar el nombre activo tampoco libera los bloques que aún referencia otra versión.
Los informes de tamaño lógico, asignación y espacio exclusivo responden preguntas diferentes. No sumes du de todas las versiones para calcular el consumo físico único. En Btrfs se pueden consultar filesystem usage y filesystem du; el primero distingue asignación y uso, y el segundo ayuda a observar extents compartidos. Véase btrfs-filesystem(8).
$ sudo btrfs filesystem usage "$MNT34"
$ sudo btrfs filesystem du -s "$MNT34/activo" "$MNT34/antes"
$ df -B1 -- "$MNT34"Una escritura pequeña puede implicar nuevos extents y metadatos. Compresión, tamaño de registro, fragmentación y agrupación de operaciones cambian el coste real. No se deduce el número de bytes físicos escritos a partir de un pwrite de un byte. Conviene dejar margen de capacidad y definir cuánto tiempo se conservan las versiones.
12. Programa en C: solicitar un reflink
Guarda clonar-cow.c. El programa exige un destino nuevo y solicita FICLONE, sin recurrir a una copia convencional si falla. Es específico de Linux y requiere cabeceras y un sistema de archivos compatibles. No copia permisos, propietario, atributos extendidos ni fechas del origen.
#define _POSIX_C_SOURCE 200809L
#include <fcntl.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
static int confirmar(int fd)
{
int r;
do { r = fsync(fd); } while (r == -1 && errno == EINTR);
return r;
}
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "Uso: %s origen destino-nuevo\n", argv[0]);
return 2;
}
int origen = open(argv[1], O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
if (origen == -1) { perror("open origen"); return 1; }
struct stat st;
if (fstat(origen, &st) == -1) {
perror("fstat"); close(origen); return 1;
}
if (!S_ISREG(st.st_mode)) {
fprintf(stderr, "El origen debe ser regular.\n");
close(origen); return 1;
}
int destino = open(argv[2], O_WRONLY | O_CREAT | O_EXCL |
O_CLOEXEC | O_NOFOLLOW, 0600);
if (destino == -1) { perror("open destino"); close(origen); return 1; }
int estado = 0;
if (ioctl(destino, FICLONE, origen) == -1) {
perror("FICLONE (sin copia alternativa)"); estado = 1;
} else if (confirmar(destino) == -1) {
perror("fsync destino"); estado = 1;
}
if (close(destino) == -1) { perror("close destino"); estado = 1; }
if (close(origen) == -1) { perror("close origen"); estado = 1; }
if (estado) {
fprintf(stderr, "Destino conservado para inspeccion; no asumir copia valida.\n");
return 1;
}
puts("Reflink confirmado para el archivo; falta persistir el nombre del directorio.");
return 0;
}O_EXCL evita truncar un nombre existente; O_NOFOLLOW rechaza un enlace simbólico final del origen. El ensayo se ejecuta en un directorio propio, sin cambios concurrentes de rutas ni del contenido. Estas opciones no resuelven por sí solas todos los problemas de rutas no confiables.
El destino creado se conserva si falla la clonación; no se intenta borrarlo por una ruta que podría haber cambiado. Lee el mensaje y revisa ese archivo antes de repetir con otro nombre. EXDEV, EOPNOTSUPP o EINVAL pueden señalar restricciones diferentes; no todo fallo significa disco lleno.
13. Programa en C: modificar una posición
Guarda cambiar-byte.c. Cambia únicamente el primer byte de un regular no vacío por el carácter ASCII suministrado. No crea archivos, no los trunca y conserva el resto del contenido. Ejecutarlo sobre un hard link cambia el mismo objeto; sobre un reflink debe preservar la otra versión.
#define _POSIX_C_SOURCE 200809L
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc != 3 || strlen(argv[2]) != 1 ||
(unsigned char)argv[2][0] > 127) {
fprintf(stderr, "Uso: %s archivo caracter-ASCII\n", argv[0]);
return 2;
}
int fd = open(argv[1], O_RDWR | O_CLOEXEC | O_NOFOLLOW);
if (fd == -1) { perror("open"); return 1; }
struct stat st;
if (fstat(fd, &st) == -1) { perror("fstat"); close(fd); return 1; }
if (!S_ISREG(st.st_mode) || st.st_size < 1) {
fprintf(stderr, "Se requiere un regular no vacio.\n");
close(fd); return 1;
}
ssize_t n;
do { n = pwrite(fd, argv[2], 1, 0); } while (n == -1 && errno == EINTR);
int estado = 0;
if (n != 1) {
if (n == -1) perror("pwrite");
else fprintf(stderr, "pwrite no completo el byte.\n");
estado = 1;
} else {
int r;
do { r = fsync(fd); } while (r == -1 && errno == EINTR);
if (r == -1) { perror("fsync"); estado = 1; }
}
if (close(fd) == -1) { perror("close"); estado = 1; }
if (!estado) puts("Primer byte modificado y archivo sincronizado.");
return estado;
}Para un byte, un retorno positivo solo puede completar el byte solicitado; cero se trata como falta de progreso. El patrón general para buffers más grandes también debe avanzar por escrituras parciales. Véanse pread/pwrite(2) y fsync(2).
14. Laboratorio sobre una imagen Btrfs propia
Usa Linux con soporte Btrfs, btrfs-progs, GCC, Python 3 y autorización para montajes loop. Una VM sirve si dispone de esas capacidades. Trabaja en una misma sesión Bash y detén la secuencia si una orden falla. La imagen nueva tiene 512 MiB lógicos; comprueba antes el espacio del anfitrión y no uses un dispositivo real como destino de mkfs.
Preparar la imagen y las herramientas
$ cc -std=c11 -Wall -Wextra -Wpedantic -O2 clonar-cow.c -o clonar-cow
$ cc -std=c11 -Wall -Wextra -Wpedantic -O2 cambiar-byte.c -o cambiar-byte
$ BIN34="$PWD"
$ LAB34=$(mktemp -d "$HOME/cow34.XXXXXX")
$ IMG34="$LAB34/practica.img"
$ MNT34="$LAB34/mnt"
$ mkdir -- "$MNT34"
$ truncate -s 512M -- "$IMG34"
$ mkfs.btrfs -- "$IMG34"
$ sudo mount -o loop,nodev,nosuid,noexec "$IMG34" "$MNT34"
$ findmnt --mountpoint "$MNT34" --output TARGET,SOURCE,FSTYPE,OPTIONS
$ sudo btrfs subvolume create "$MNT34/activo"
$ sudo chown "$(id -u):$(id -g)" "$MNT34/activo"mktemp crea una ruta exclusiva y mkfs se aplica solo a su archivo nuevo. No se usa -f para forzar el formateo. Los ejecutables permanecen fuera del montaje noexec; si tu directorio de compilación tampoco permite ejecutar, usa una ubicación de práctica que sí lo permita.
Crear datos y capturar la versión inicial
$ python3 - "$MNT34/activo/original.bin" <<'PY'
import os
import sys
with open(sys.argv[1], 'xb') as f:
for _ in range(1024):
f.write(b'A' * 4096)
f.flush()
os.fsync(f.fileno())
PY
$ sudo btrfs subvolume snapshot -r "$MNT34/activo" "$MNT34/antes"
$ sudo btrfs subvolume show "$MNT34/antes"
$ "$BIN34/clonar-cow" "$MNT34/activo/original.bin" "$MNT34/activo/clon.bin"
$ cp --reflink=never -- "$MNT34/activo/original.bin" "$MNT34/activo/copia.bin"
$ ln -- "$MNT34/activo/original.bin" "$MNT34/activo/enlace.bin"
$ ls -li -- "$MNT34/activo/"*.bin
$ "$BIN34/cambiar-byte" "$MNT34/activo/clon.bin" X
$ "$BIN34/cambiar-byte" "$MNT34/activo/enlace.bin" YLa instantánea se tomó antes de crear los otros nombres. Por tanto, antes solo contiene original.bin. El hard link activo y original.bin deben mostrar el mismo inodo dentro del subvolumen activo; no uses números de inodo de subvolúmenes distintos como prueba de identidad global.
Consultar uso y comprobar integridad
$ sudo btrfs filesystem sync "$MNT34"
$ sudo btrfs filesystem usage "$MNT34"
$ sudo btrfs filesystem du -s "$MNT34/activo" "$MNT34/antes"
$ sudo btrfs scrub start -B -r "$MNT34"
$ sudo btrfs scrub status "$MNT34"-B espera el resultado del scrub y -r deshabilita su reparación. No se interpreta esa opción como garantía de cero escrituras sobre un montaje de lectura y escritura. El ensayo comprueba datos existentes; no daña la imagen para intentar demostrar una reparación.
15. Verificación reproducible y lectura de resultados
Ejecuta este verificador antes de desmontar. Comprueba todos los bytes, la independencia de las versiones y la identidad del hard link. Los ficheros son pequeños y propios del ensayo; no se aplica esta lectura completa indiscriminadamente a recursos especiales.
$ python3 - "$MNT34" <<'PY'
from pathlib import Path
import sys
base = Path(sys.argv[1])
inicial = b'A' * (4 * 1024 * 1024)
esperados = {
'antes/original.bin': inicial,
'activo/original.bin': b'Y' + inicial[1:],
'activo/enlace.bin': b'Y' + inicial[1:],
'activo/clon.bin': b'X' + inicial[1:],
'activo/copia.bin': inicial,
}
for nombre, esperado in esperados.items():
if (base / nombre).read_bytes() != esperado:
raise SystemExit('Contenido inesperado: ' + nombre)
print('OK', nombre)
original = (base / 'activo/original.bin').stat()
enlace = (base / 'activo/enlace.bin').stat()
clon = (base / 'activo/clon.bin').stat()
if (original.st_dev, original.st_ino) != (enlace.st_dev, enlace.st_ino):
raise SystemExit('El hard link no comparte identidad')
if (original.st_dev, original.st_ino) == (clon.st_dev, clon.st_ino):
raise SystemExit('El clon no es un archivo distinto')
if sorted(p.name for p in (base / 'antes').iterdir()) != ['original.bin']:
raise SystemExit('Contenido inesperado en el snapshot')
print('OK: aislamiento de versiones e identidad del hard link')
PYEl éxito de FICLONE acredita que se aceptó la operación de clonado; el verificador prueba el comportamiento del contenido. No mide el ahorro físico exacto. No esperes una diferencia de un byte en filesystem usage: la asignación trabaja con unidades mayores y también necesita metadatos.
$ cd -- "$LAB34"
$ sudo umount "$MNT34"
$ mountpoint -q "$MNT34" && printf 'El montaje sigue activo\n'
$ printf 'Imagen conservada: %s\n' "$IMG34"mountpoint devuelve un estado distinto de cero cuando el directorio ya no es un punto de montaje; en ese caso no imprime el aviso. Si umount informa ocupado, cierra los procesos que usan el ensayo y vuelve a desmontar normalmente. La imagen y los fuentes se conservan; no hace falta borrarlos para completar la observación.
16. Simuladores de referencias e integridad
Bloques compartidos y versiones retenidas
El modelo tiene cuatro posiciones y bloques de datos de 4 KiB. Cada modificación crea un bloque nuevo, incluso si se repite una posición. Crear una instantánea de solo lectura comparte las referencias actuales; solo se mantiene una instantánea cada vez. Se omiten metadatos, compresión, caché y liberación diferida: los resultados no predicen df de un sistema real.
Una versión activa y una instantánea
| Bloque vivo | Contenido | Referencias | Vistas que lo necesitan |
|---|
Captura, modifica la posición 1 y observa cinco bloques vivos. Modifica de nuevo la posición 1: el bloque intermedio ya no está referenciado, de modo que el total sigue siendo cinco. Elimina la instantánea: vuelven a quedar cuatro.
Detección, réplica y reparación
El checksum didáctico es la suma de cuatro bytes módulo 256. Es deliberadamente débil y no representa los algoritmos de Btrfs o ZFS. La referencia esperada permanece protegida en este modelo. La colisión altera dos bytes conservando la suma para mostrar el límite de la detección.
¿Hay una copia verificable para recuperar?
17. Diagnóstico y resumen
| Observación | Interpretación a comprobar |
|---|---|
| Borré un archivo, pero sigue ocupado el espacio. | Puede haber snapshots, reflinks o descriptores que retienen datos; también liberación pendiente. |
| Cambiar enlace.bin modifica original.bin. | Son nombres del mismo inodo, no versiones independientes. |
| FICLONE falla. | Revisar soporte, mismo sistema de archivos, opciones, permisos y errno. |
| El snapshot no contiene un subvolumen hijo. | La captura Btrfs no recorre automáticamente ese límite. |
| Scrub detectó daño, pero no pudo corregirlo. | Puede faltar una copia válida accesible para reparar. |
| Los checksums son correctos, pero el saldo es erróneo. | La integridad de bloques no valida la lógica de la aplicación. |
| Sumar tamaños de versiones supera el uso del volumen. | Puede haber almacenamiento compartido; distinguir tamaño lógico y consumo único. |
- COW permite preparar versiones nuevas conservando referencias a datos anteriores.
- Reflinks separan la identidad del archivo y comparten inicialmente extents; los hard links comparten el objeto.
- Una instantánea tiene alcance y momento definidos; no captura toda la actividad del equipo.
- Btrfs admite snapshots escribibles y de solo lectura; ZFS ofrece snapshots de solo lectura y clones escribibles.
- Checksum, redundancia, scrub y copia externa cumplen funciones distintas.
- Los datos retenidos por una versión pueden impedir que borrar otra libere espacio.
- La aplicación sigue necesitando protocolos de consistencia y confirmación de persistencia.
- Las pruebas deben observar contenido, identidad y asignación sin confundir sus conclusiones.
18. Preguntas de repaso y práctica
1. ¿Qué evita COW al modificar un bloque compartido?
Que los cambios de una versión alteren los bytes que todavía necesita otra.
2. ¿Solo hay que escribir el bloque de datos nuevo?
No. Puede ser necesario crear metadatos nuevos y publicar referencias válidas respetando la persistencia.
3. ¿Crear un snapshot duplica todos los bytes?
No. Puede compartir datos existentes, aunque su gestión tiene coste y las modificaciones posteriores pueden retener espacio adicional.
4. ¿Un hard link conserva la versión anterior del archivo?
No. Es otro nombre del mismo objeto; escribir mediante cualquiera modifica ese objeto.
5. ¿Un reflink tiene el mismo inodo que el origen?
No en este ensayo dentro del mismo subvolumen. Es otro archivo, aunque pueda compartir extents de datos.
6. ¿Dos hashes iguales demuestran un reflink?
No. No indican cómo se almacenan los datos.
7. ¿Por qué el ejemplo exige FICLONE?
Para informar si no se puede clonar, sin ocultar ese resultado mediante una copia convencional.
8. ¿El programa clona permisos y atributos extendidos?
No. Crea el destino con modo solicitado 0600 y clona sus datos; no implementa una copia completa de metadatos.
9. ¿Los snapshots de Btrfs son siempre de solo lectura?
No. El laboratorio usa -r para crearlos de solo lectura.
10. ¿Capturar el padre Btrfs incluye el contenido de subvolúmenes hijos?
No. Es necesario considerar esos límites y capturar las unidades pertinentes.
11. ¿Qué diferencia hay entre snapshot y clone en ZFS?
El snapshot es de solo lectura; el clone es una rama escribible derivada de una instantánea.
12. ¿Un snapshot local protege contra perder todo el pool?
No. Comparte el dominio de pérdida de ese almacenamiento.
13. ¿Por qué un checksum no siempre permite reparar?
Detectar una discrepancia no aporta los bytes originales; hace falta una fuente válida de recuperación.
14. ¿Una colisión significa que dos contenidos son iguales?
No. Significa que contenidos distintos produjeron el mismo valor de checksum.
15. ¿Scrub es lo mismo que fsck?
No. Verificación de bloques y coherencia estructural tienen alcances distintos.
16. ¿Un checksum correcto valida una operación bancaria?
No. Puede proteger perfectamente un valor que la aplicación calculó mal.
17. ¿Por qué borrar el original puede no liberar los datos?
Porque otra versión o referencia todavía los necesita.
18. ¿Cambiar un byte implica escribir un byte físico?
No. El sistema trabaja con unidades de datos y metadatos mayores y puede agrupar operaciones.
19. ¿Un snapshot sustituye el backup de una base de datos?
Solo puede formar parte de un procedimiento que coordine la base, su recuperación y el almacenamiento de la copia.
20. ¿El ejemplo C confirma también la persistencia del nombre nuevo?
No. Sincroniza el archivo; el protocolo completo también debe considerar el directorio.
Para practicar
- Dibuja las referencias después de crear dos snapshots y modificar posiciones diferentes.
- Calcula los bloques únicos del dibujo y compáralos con la suma de los tamaños de las versiones.
- Ejecuta los programas sobre el montaje de práctica y verifica que las advertencias del compilador están resueltas.
- Repite la clonación usando el mismo destino: comprueba que O_EXCL rechaza la operación sin truncarlo.
- Prueba un archivo vacío con cambiar-byte y explica por qué lo rechaza.
- Comprueba que antes solo contiene el nombre que existía en el momento de la captura.
- Relaciona los inodos de original.bin, enlace.bin y clon.bin dentro del subvolumen activo.
- Compara filesystem usage, filesystem du y df sin exigir que informen la misma magnitud.
- En el simulador, modifica dos veces una posición después de capturar y explica por qué no se retienen todas las versiones intermedias.
- Combina daño, ausencia de réplica y colisión en el segundo simulador.
- Diseña una política que conserve versiones locales y una copia en otro almacenamiento.
- Explica qué coordinación necesitaría una aplicación cuyos datos se reparten entre dos subvolúmenes.
En el tema 35 desarrollaremos actualizaciones atómicas desde C: crear un temporal, escribir y comprobar, sincronizar, publicar con rename y confirmar el directorio.