Las profundidades de la E/S de Windows (parte 5) — Estructura interna de NTFS: comprender el sistema de archivos a partir de la MFT
· Actualizado el: · Go Komura · Windows, NTFS, I/O, Sistema de archivos, MFT, Núcleo, .NET, Investigación de fallos
En las cuatro entregas anteriores hemos visto cómo fluye una solicitud de E/S (partes 1 a 3) y cómo la recibe la caché (parte 4). Al final, la solicitud llega al sistema de archivos. Le toca el turno a su representante por excelencia: NTFS.
El punto de vista cambia. Hasta ahora hablábamos del «flujo de la solicitud», un tema dinámico. Esta vez hablamos de una estructura estática: cómo se colocan los datos sobre el disco. La verdadera identidad de ese invisible «Zone.Identifier» que se adjunta a los archivos descargados. La razón por la que copiar diez mil archivos pequeños es mucho más lento que copiar un único archivo del mismo tamaño total. Hasta qué punto es cierto eso de «NTFS es tranquilizador porque usa journaling»: todo se explica a partir de esta estructura.
Esta es la quinta entrega de la serie «Las profundidades de la E/S de Windows».
Requisito previo para esta entrega: resulta más fácil de leer si ya conoce los conceptos básicos de IRP y de la pila de dispositivos vistos en la parte 1. Aun así, para que pueda leerla de forma independiente sin problemas, a continuación definimos los términos de entregas anteriores que aparecen en el texto.
| Término | En una línea | Más detalles |
|---|---|---|
| IRP (I/O Request Packet) | El «albarán de la solicitud de E/S» al que se convierte, dentro del núcleo, una llamada a una API como ReadFile. El controlador recibe este albarán y lo procesa |
Parte 1 |
| El administrador de E/S y la pila de dispositivos | El componente del núcleo que crea el IRP y lo va entregando, uno tras otro, a la pila de controladores apilados hasta llegar al dispositivo de destino, junto con esa propia pila | Parte 1 |
| El administrador de caché | El componente que mantiene el contenido de un archivo en memoria y que, más tarde, escribe de golpe en el disco el contenido de WriteFile. El origen del hecho de que «no es seguro que lo escrito llegue al disco justo después de escribirlo» |
Parte 4 |
Tabla 1: Términos de entregas anteriores que se dan por conocidos en esta entrega
Además, las dos fases tratadas en la parte 1 —cleanup (cuando se cierra el último identificador) y close (cuando desaparecen todas las referencias internas del núcleo)— también se usan en la explicación de la eliminación de archivos del capítulo 4.
1. La conclusión, antes que nada
- El centro de NTFS es la MFT (Master File Table, tabla maestra de archivos). Todos los archivos se gestionan como un libro mayor de registros dentro de la MFT, y toda la información relativa a un archivo está «dentro de la entrada de la MFT» o en «la zona fuera de la MFT a la que apunta la entrada» (capítulo 2). 1
- El contenido real de un archivo es un «conjunto de atributos». Los archivos pequeños caben, contenido incluido, dentro del registro de la MFT (residentes), mientras que los archivos grandes solo tienen una referencia a una secuencia de clústeres (no residentes). La lentitud del procesamiento masivo de archivos pequeños se explica a partir de aquí (capítulo 2). 1
- Un archivo puede tener varios flujos de datos (streams). El dato habitual es el «flujo sin nombre», y se pueden añadir flujos adicionales con la forma
file.txt:nombre. Esta es la verdadera identidad de Zone.Identifier (Mark of the Web) (capítulo 3). 2 - El nombre también es un atributo. Un enlace físico (hard link) consiste en asignar varios nombres al mismo registro. El nombre corto 8.3 también convive como «otro nombre más» (capítulo 4). 34
- El punto de análisis (reparse point) es el mecanismo oficial de «al abrirlo, se va a otro sitio». Los enlaces simbólicos, las junctions y los archivos a petición de OneDrive son todos aplicaciones de estos datos etiquetados (capítulo 5). 56
- Hay dos diarios (journals).
$LogFilesirve para recuperar la coherencia de los metadatos (un registro de anticipación para no corromperse), y el diario USN sirve para registrar el historial de cambios (un libro mayor de qué ha cambiado). Sus funciones son completamente distintas (capítulo 6). 78 - El «tamaño» y el «tamaño en disco» son cosas distintas. Los archivos dispersos (sparse) y la compresión generan esta divergencia. Aquí también está el trasfondo de aquello que vimos en la parte 2: «los archivos comprimidos no se vuelven asíncronos» (capítulo 7). 910
2. Todo es, en el fondo, un registro de la MFT
2.1. El libro mayor del volumen
Al formatear un volumen NTFS se crean la MFT (master file table) y una serie de archivos de metadatos que comienzan por $. La MFT contiene al menos una entrada por cada archivo del volumen, y eso incluye una entrada para la propia MFT. 1
flowchart TB
accTitle: Estructura de un volumen NTFS
accDescr: Diagrama de los archivos de metadatos de un volumen NTFS ($MFT, $LogFile, $Bitmap y otros) y su relación con el área de datos de usuario
subgraph VOL["Volumen NTFS"]
MFT["$MFT -- tabla maestra de archivos (incluye su propio registro)"]
LOG["$LogFile -- registro de transacciones de metadatos (cap. 6)"]
BITMAP["$Bitmap -- uso de clústeres"]
OTH["$Boot / $Secure / $UpCase y otros metadatos"]
DATA["Área de datos de usuario (no residentes)"]
end
MFT -->|"el registro indica la posición"| DATA
Figura 1: Estructura de un volumen NTFS. El diseño de NTFS consiste en que la propia información de gestión del sistema de archivos también se guarda como archivos
La información relativa a un archivo —tamaño, marcas de tiempo, permisos de acceso e incluso el contenido de los datos— se almacena dentro de la entrada de la MFT o en una zona fuera de la MFT cuya posición describe la entrada. 1 Al eliminar un archivo, la entrada se marca como «libre» y se reutiliza, pero la propia MFT no se reduce. Además, para mantener la MFT contigua se reserva una zona llamada zona de la MFT, y la documentación oficial llega a explicar todo el ciclo de vida: a medida que el volumen se llena, comienza la fragmentación de la MFT. 1
2.2. Un archivo es un conjunto de atributos: residente y no residente
El contenido de un registro de archivo es una lista de atributos: información estándar (marcas de tiempo, etc.), nombre de archivo, seguridad y datos. Aquí aparece una bifurcación importante.
flowchart TB
accTitle: Atributos residentes y no residentes
accDescr: Diagrama de un registro de archivo MFT con sus atributos y la decisión de residencia según el tamaño de los datos
subgraph REC["Registro de archivo MFT (el libro de un archivo)"]
STD["Atributo de información estándar: marcas de tiempo, indicadores"]
FN["Atributo de nombre de archivo (puede haber varios, cap. 4)"]
DATA["Atributo de datos"]
end
Q{"¿Los datos son pequeños?"}
RES["Residente: el contenido cabe en el registro; basta con acceder a la MFT"]
NONRES["No residente: el registro solo referencia clústeres; los datos están en el área de usuario"]
DATA --> Q
Q -->|"hasta unos cientos de bytes"| RES
Q -->|"más que eso"| NONRES
Figura 2: El registro de archivo es un conjunto de atributos. Si los datos son pequeños, quedan «residentes» dentro del registro
Resulta más claro ver, uno junto al otro, cómo cambia el contenido del mismo registro entre el caso residente y el no residente.
flowchart LR
accTitle: Comparación entre residente y no residente
accDescr: Diagrama que compara el contenido del registro MFT y su relación con el área de datos, entre un archivo pequeño residente y un archivo grande no residente
subgraph RES2["Residente -- archivo pequeño"]
RA["Registro MFT (tamaño fijo): estándar/nombre/seguridad + datos = contenido directo"]
RB["Sin otro lugar en disco; leer = acceder a la MFT"]
RA --> RB
end
subgraph NON2["No residente -- archivo grande"]
NA["Registro MFT (tamaño fijo): estándar/nombre/seguridad + datos = tabla de data runs"]
NB["Área de usuario: run 1 (clústeres contiguos)"]
NC["Área de usuario: run 2 (otro tramo contiguo)"]
NA -->|"indica la posición"| NB
NA -->|"indica la posición"| NC
end
Figura 3: Comparación entre residente y no residente. En el caso no residente, el registro solo contiene la tabla (data runs) de dónde y cuántos datos reales hay
Cuantas más data runs haya, más zonas dispersas hay que recorrer para leer un solo archivo. Esta es la verdadera identidad de la fragmentación que se explica a continuación.
A partir de esta estructura se pueden explicar varios fenómenos que se encuentran en la práctica.
- La razón por la que copiar diez mil archivos pequeños es lento. Por cada archivo se producen operaciones de metadatos: creación del registro MFT, registro del nombre, configuración de seguridad. El trabajo de «llevar el libro mayor» acaba dominando sobre la propia transferencia de datos (y, además, cada una de esas operaciones también es objeto de inspección por los filtros que veremos en la parte 6).
- La verdadera identidad de la fragmentación. Los datos no residentes se registran como «una secuencia de tramos contiguos de clústeres (runs)». Si no se puede conseguir una zona contigua, aumenta el número de runs y, con ello, las búsquedas (seeks) necesarias para leer: esto es la fragmentación. Puede consultar la disposición real de los runs con
fsutil file layout. - Una «carpeta» tampoco es nada especial. Un directorio es «un archivo que tiene un índice del nombre de archivo al número de registro de la MFT». Desde el punto de vista del libro mayor, todo descansa sobre el mismo mecanismo.
3. Los datos no son más que uno de los «flujos»
3.1. Un archivo, varias secuencias de bytes
En NTFS, un mismo archivo puede tener varios flujos de datos. Lo que normalmente se lee y se escribe con ReadFile/WriteFile es el flujo predeterminado sin nombre, y con la sintaxis nombre_de_archivo:nombre_de_flujo se pueden crear flujos de datos alternativos (ADS). 2
flowchart LR
accTitle: Flujos de datos múltiples en un archivo
accDescr: Diagrama que muestra el archivo report.docx como un único registro MFT con un flujo predeterminado y dos flujos de datos alternativos adicionales
subgraph F["El archivo report.docx (un único registro MFT)"]
D0["Flujo predeterminado (sin nombre): el contenido habitual"]
D1[":Zone.Identifier -- información de origen (Mark of the Web)"]
D2[":nombre arbitrario -- datos adicionales propios de la app"]
end
Figura 4: Flujos de datos múltiples. En el tamaño que muestra el Explorador solo aparece el flujo predeterminado
El ADS más cercano al día a día es Zone.Identifier. En los archivos descargados con el navegador, este flujo registra el origen (por ejemplo, que procede de internet), y sirve como criterio para el aviso de SmartScreen «Windows protegió su PC» o para la vista protegida de Office. La cara visible de este mecanismo la tratamos en «Por qué aparece en Windows el mensaje “Windows protegió su PC”»; la verdadera identidad de la cara oculta resulta ser, simplemente, un flujo de NTFS.
3.2. Trampas en las que caen los desarrolladores
- Es invisible. No aparece ni en el tamaño del Explorador ni en el listado de
dir. Se puede comprobar condir /ro constreamsde Sysinternals. 11 - No se transporta. Como el ADS es una característica de NTFS, tiende a perderse al copiar a una memoria USB con FAT o a través de almacenamiento en la nube. Esta es la causa de que «el aviso de descarga desapareciera al copiar el archivo».
- También se puede abrir desde su propia aplicación. Basta con incluir dos puntos en la ruta, como en
CreateFile("data.txt:meta", ...), para leer y escribir en él. 2 Es conveniente, pero al usarlo también hereda la característica de «no se transporta» del punto anterior, por lo que no es un lugar adecuado para guardar el contenido principal de los datos de negocio.
4. El nombre también es un atributo: enlaces físicos y nombres 8.3
4.1. Enlaces físicos: varios nombres para el mismo registro
En la figura 2 dijimos que «el atributo de nombre de archivo puede tener varios valores». Que varias rutas, dentro del mismo volumen, hagan referencia a un único archivo: esto es un enlace físico (hard link) (CreateHardLink / mklink /H). 3
flowchart TB
accTitle: Enlace físico a un mismo registro MFT
accDescr: Diagrama que muestra dos índices de directorio distintos apuntando al mismo registro MFT, ilustrando que un enlace físico añade un nombre adicional a un archivo existente
subgraph DIR1["Índice de C:\app\"]
E1["config.json → registro #1234"]
end
subgraph DIR2["Índice de C:\backup\"]
E2["config-link.json → registro #1234"]
end
REC["Registro MFT #1234: contenido (o referencia a runs); número de enlaces: 2"]
E1 --> REC
E2 --> REC
Figura 5: Enlace físico. Los índices de los directorios simplemente apuntan al mismo registro MFT, y ambos son igual de «reales»
Como se trata del mismo archivo sin importar desde qué nombre se modifique, el contenido coincide de inmediato. 3 Y el significado de «eliminar» cambia: DeleteFile significa «quitar un nombre», y el contenido real solo desaparece cuando se ha quitado el último nombre, se han cerrado los identificadores abiertos y, además, han desaparecido todas las referencias internas del núcleo, como las secciones de mapas de memoria. Las dos fases que vimos en la parte 1 —cleanup (el último identificador) y close (la última referencia)— siguen operando tal cual en el ciclo de vida de la eliminación. Además, la visualización de los atributos tiene una peculiaridad conocida: la documentación oficial señala que, aunque se cambien atributos a través de un enlace, la visualización aparente de otro enlace puede quedar desactualizada. 3
4.2. El nombre 8.3: otro nombre oculto
Por compatibilidad histórica, NTFS puede generar automáticamente, para los nombres de archivo largos, un nombre corto en formato 8.3 como REPORT~1.DOC. Este también convive en el registro como «otro nombre más». En carpetas con una gran cantidad de archivos, generar el nombre corto y evitar colisiones supone un coste, por lo que fsutil 8dot3name permite deshabilitar la generación o eliminar los nombres cortos existentes (si hay aplicaciones antiguas que guardan rutas del registro con el nombre corto, esto puede romperlas, así que resulta muy práctico que exista una función de comprobación antes de hacer el strip). 4
Aquí conviene tener presente que la existencia o no del nombre corto depende del entorno. El comportamiento predeterminado lo determina el valor de registro NtfsDisable8dot3NameCreation, que admite cuatro valores: 0 (generarlo en todos los volúmenes), 1 (no generarlo en ningún volumen), 2 (configurarlo por volumen) y 3 (no generarlo salvo en el volumen del sistema). 4 Si se elige 2, se puede alternar por volumen, así que no siempre es cierto que «en Windows siempre exista un nombre corto como PROGRA~1». Antes de escribir código o procedimientos que dependan del nombre corto, compruebe el estado actual con fsutil 8dot3name query C: (si se omite el volumen, se muestra la configuración predeterminada común a todos los volúmenes).
Las trampas relacionadas con las rutas y los nombres (MAX_PATH, nombres reservados, punto final) se tratan en detalle en «MAX_PATH y las trampas de rutas y nombres de archivo en Windows». Si se combina la resolución de nombres de la parte 1 (el administrador de objetos) con este capítulo (los nombres dentro del sistema de archivos), se obtiene el panorama completo de los «nombres» en Windows.
5. Puntos de análisis: el mecanismo de «al abrirlo, va a otro sitio»
A los archivos y directorios se les puede asignar un punto de análisis (reparse point). En esencia es un atributo compuesto por «una etiqueta + datos definidos por el usuario». Cuando el sistema de archivos abre un archivo con un punto de análisis, el procesamiento se desvía según la etiqueta: un controlador de filtro que entienda la etiqueta se hace cargo del procesamiento, o bien, si la etiqueta es del tipo de redirección de nombre, la resolución se reintenta con la ruta de destino. 5
sequenceDiagram
accTitle: Resolución de un punto de análisis
accDescr: Diagrama de secuencia que muestra cómo NTFS detecta un punto de análisis al abrir un archivo y cómo, según la etiqueta, reintenta la resolución con otra ruta o cede el control a un filtro
participant App as Aplicación
participant IOM as Administrador de E/S
participant FS as NTFS
App->>IOM: CreateFile("C:\data\link.txt")
IOM->>FS: IRP_MJ_CREATE (el mundo de la parte 1)
Note over FS: Se detecta un punto de análisis<br/>se devuelven la etiqueta y los datos
alt Enlace simbólico o junction (redirección de nombre)
FS-->>IOM: "La ubicación real es esta"
IOM->>FS: Se reintenta la resolución con la ruta de destino
else Etiqueta gestionada por un filtro (archivo en la nube, etc.)
Note over FS: Un filtro que entiende la etiqueta se encarga del proceso (parte 6)
end
Figura 6: Resolución de un punto de análisis. Es el gancho oficial que intercepta la operación de «abrir»
Sobre este único mecanismo se apoyan varias funciones conocidas.
- Enlace simbólico (
mklink): un indicador que conserva la ruta de destino. Puede apuntar a otro volumen o a una ruta UNC. 6 - Junction/punto de montaje: un mecanismo veterano que conecta un directorio con una ubicación de otro volumen local. 3
- Archivos a petición de OneDrive: representa mediante un punto de análisis los archivos cuyos datos reales no están disponibles localmente, y en el instante en que se abren, un filtro los descarga y entrega el contenido. Esta es la verdadera identidad de «se ve en el Explorador, pero al abrirlo se produce tráfico de red» (el mecanismo del filtro en sí se verá en la parte 6).
Hay una sola precaución práctica: «el destino de la ruta no siempre está realmente en esa ubicación local». Una herramienta que recorre un árbol de forma recursiva puede entrar en bucle con una junction, el cálculo del tamaño puede duplicarse, o una copia de seguridad puede provocar la materialización masiva de archivos en la nube: el código que no conoce la existencia de los puntos de análisis cae en estas trampas. Comprobar el atributo FILE_ATTRIBUTE_REPARSE_POINT de la familia FindFirstFile es el punto de partida para evitarlas. 5
6. Los dos diarios: $LogFile y USN
Se suele decir que «NTFS es un sistema de archivos con journaling», pero NTFS tiene dos diarios con funciones distintas. Si se confunden, se malinterpreta lo que realmente garantizan.
flowchart TB
accTitle: Los dos diarios de NTFS
accDescr: Diagrama que compara el $LogFile, un registro de anticipación para no corromperse, con el diario USN, un historial de cambios para saber qué se modificó
subgraph J1["$LogFile -- registro de anticipación (para no corromperse)"]
A1["Las operaciones de metadatos (actualización de registros, cambios de nombre, etc.) se registran en el log antes de ejecutarse"]
A2["Tras un fallo del sistema, en el siguiente arranque se reproduce el log para recuperar la coherencia de la estructura"]
A1 --> A2
end
subgraph J2["Diario USN -- historial de cambios (para saber qué cambió)"]
B1["Cada vez que se modifica un archivo o directorio, se registra el contenido del cambio y el nombre"]
B2["Las copias de seguridad, los índices de búsqueda y las herramientas de sincronización averiguan 'qué cambió desde la última vez' sin recorrer todo el volumen"]
B1 --> B2
end
Figura 7: Los dos diarios. $LogFile existe para «no corromperse», y USN para «conocer los cambios»
Las diferencias, en forma de tabla, quedan así:
| Aspecto | $LogFile (registro de transacciones) |
Diario USN (change journal) |
|---|---|---|
| Objetivo | Devolver la estructura del sistema de archivos a un estado coherente tras un fallo 7 | Saber más tarde «qué cambió desde la última vez» 8 |
| Qué registra | Registro de anticipación de operaciones de metadatos (actualización de registros, cambios de nombre, etc.). El contenido de los archivos queda fuera | En cada cambio, el contenido del cambio y el nombre del archivo o directorio afectado 8 |
| Quién lo usa | El propio NTFS. Se usa para la recuperación automática al volver a montar | Aplicaciones como copias de seguridad, índices de búsqueda y herramientas de sincronización |
| Hasta dónde se puede retroceder | Solo hasta donde hace falta para recuperarse. Al reutilizar un tamaño fijo, no sirve para consultar historial antiguo | Al superar el tamaño máximo objetivo (MaximumSize), los registros antiguos se truncan en el punto de control. El alcance depende del tamaño configurado y del volumen de actualizaciones 12 |
| Cómo consultarlo | No existe un medio oficial para leer su contenido (el tamaño se puede comprobar con chkdsk /L) |
El estado con fsutil usn queryjournal, el contenido con fsutil usn readjournal. Desde código, FSCTL_QUERY_USN_JOURNAL / FSCTL_READ_USN_JOURNAL 12 |
| ¿Se puede detener? | No se puede detener (forma parte de NTFS) | Un administrador puede eliminarlo o deshabilitarlo. Pero eso obliga a un recorrido completo a los servicios que lo usan, así que el impacto es grande 12 |
Tabla 2: Comparación de los dos diarios
$LogFile(el registro de transacciones) es el registro de anticipación de las operaciones de metadatos. Aunque se produzca un fallo del sistema, en el siguiente arranque NTFS recupera automáticamente la coherencia del sistema de archivos a partir de este registro y de la información de puntos de control. 7 Lo que se protege aquí es la estructura. Como vimos en la parte 4, el contenido de los datos sucio que está en la caché puede perderse con un corte de energía: la lectura correcta es «el volumen no se corrompe, pero la última escritura puede perderse».- El diario USN (change journal) es un libro mayor que registra, cada vez que se produce un cambio en un archivo o directorio del volumen, el contenido del cambio y el nombre del objeto afectado. 8 Es el mecanismo que permite a las copias de seguridad y a los indexadores recoger «solo lo que cambió desde la última vez» sin tener que recorrer todo el volumen, y también se usa para evitar reconstruir el índice tras un fallo. 8 En la práctica conviene recordar que
fsutil usn readjournalpuede usarse en investigaciones como un libro mayor de contraste para compensar los eventos perdidos deFileSystemWatcher(véase la «Guía práctica de FileSystemWatcher»).
7. Archivos dispersos y compresión: la historia de las dos «tamaños»
En NTFS, la longitud lógica de un archivo y el espacio realmente asignado se gestionan por separado. Son el «Tamaño» y el «Tamaño en el disco» que se ven en la pantalla de propiedades. Hay dos causas principales que generan esta divergencia.
Un archivo disperso (sparse) no asigna espacio real a los tramos que son ceros seguidos, sino que los gestiona como «huecos». 9 Es habitual que un archivo de disco virtual con un tamaño lógico de 42 GB ocupe solo 500 MB en el disco. Leer un hueco devuelve ceros, y escribir en él asigna espacio en esa medida.
flowchart LR
accTitle: Archivo disperso y sus huecos
accDescr: Diagrama de un archivo lógico de 1 GB con tramos de datos y huecos de ceros, mostrando que en el disco solo se asigna espacio para los tramos con datos reales
subgraph L["Archivo lógico (tamaño: 1 GB)"]
R1["Datos: 10 MB"]
H1["Hueco (ceros): 500 MB"]
R2["Datos: 5 MB"]
H2["Hueco (ceros): el resto"]
end
subgraph P["Asignación en disco (15 MB + metadatos)"]
A1["Run: contenido real de R1"]
A2["Run: contenido real de R2"]
end
R1 --> A1
R2 --> A2
Figura 8: Archivo disperso. Los «huecos» no tienen asignación, por lo que el tamaño lógico y el tamaño en disco divergen
La compresión de NTFS comprime y almacena los datos por unidades de compresión. 10 Es transparente y cómoda, pero el coste no lo es tanto: cada lectura o escritura implica descomprimir y volver a comprimir, y también favorece la fragmentación. Y, como vimos en el capítulo 5 de la parte 2, el acceso a un archivo comprimido no se vuelve asíncrono (el sistema de archivos lo convierte a síncrono). Es uno de los lugares que conviene sospechar cuando «hay un archivo que no se acelera aunque se haya puesto en E/S asíncrona».
El tamaño real basado en la asignación se puede obtener con GetCompressedFileSize. En las investigaciones donde «la suma de los tamaños de archivo» y «el uso de disco» no coinciden, la práctica estándar es sospechar, en orden, de estos cuatro factores: archivos dispersos, compresión, ADS (capítulo 3) y el redondeo por clúster.
8. Compruébelo usted mismo
Al igual que en entregas anteriores, todo esto se puede observar en un Windows a mano (algunas partes requieren privilegios de administrador). Para que pueda juzgar usted mismo si el resultado es correcto, junto a cada comando añadimos qué se aprende mirando qué parte.
:: Ver las secuencias de datos alternativas
dir /r C:\Users\%USERNAME%\Downloads
Fíjese aquí: debajo de la línea normal del archivo aparecen, sangradas, líneas con la forma nombre_de_archivo:Zone.Identifier:$DATA junto con su longitud. Si aparece esta línea, significa que ese archivo tiene el Mark of the Web (capítulo 3). Los archivos descargados con el navegador lo tienen; los que usted mismo crea, no. Si ejecuta el comando en ambos lugares y compara, la presencia o ausencia del ADS queda muy clara.
:: Ver la disposición (runs) y los atributos del archivo en la MFT
fsutil file layout C:\path\to\file.dat
:: Ver solo los extents (subcomando documentado oficialmente)
fsutil file queryextents C:\path\to\file.dat
Fíjese aquí: layout muestra, para cada flujo, el tamaño y el tamaño asignado, y, si es no residente, la lista de extents (tríos de VCN, LCN y número de clústeres). Un archivo muy pequeño para el que no aparece ninguna línea de extent es residente (apartado 2.2); si aparece dividido en varias líneas, está fragmentado. Ejecutarlo con un archivo de texto de pocos bytes y con uno de varios cientos de MB y comparar es la forma más rápida de sentir en carne propia la diferencia entre residente y no residente.
:: Configuración de generación de nombres cortos 8.3 y los nombres cortos existentes
fsutil 8dot3name query C:
dir /x
Fíjese aquí: query devuelve si la generación de nombres cortos está habilitada o deshabilitada en ese volumen (si se omite el volumen, muestra la configuración predeterminada común a todos los volúmenes). 4 dir /x muestra la columna del nombre corto junto al nombre largo, así que si la columna aparece vacía, significa que no se generó el nombre corto. Así puede comprobar en su propio entorno lo dicho en el apartado 4.2: «no siempre hay un nombre corto».
:: Estado del diario USN
fsutil usn queryjournal C:
Fíjese aquí: se muestran el ID del diario, el rango de USN válido (First USN / Next USN), el tamaño máximo objetivo (MaximumSize) y la unidad de asignación (AllocationDelta). 12 Si crea algún archivo y vuelve a ejecutar el comando, Next USN debería haber avanzado, lo cual confirma que «los cambios se están registrando». MaximumSize es el indicador de «hasta dónde se puede retroceder» que mencionamos en el capítulo 6. En un volumen con el diario deshabilitado, el comando dará error.
:: Comprobar puntos de análisis (destino del enlace y etiqueta)
dir /aL C:\Users\%USERNAME%
fsutil reparsepoint query "C:\Users\%USERNAME%\OneDrive"
Fíjese aquí: lo que aparece con dir /aL son los puntos de análisis (aquellos con el atributo FILE_ATTRIBUTE_REPARSE_POINT activado). Los enlaces simbólicos y las junctions se muestran con un tipo como <SYMLINKD> o <JUNCTION>. fsutil reparsepoint query muestra el valor de la etiqueta de reanálisis y, si es del tipo de redirección de nombre, la ruta de destino. Si se especifica un objeto que no es un punto de análisis, el comando da error, así que el propio hecho de que dé error confirma que “esto es una carpeta normal”.
Si sigue las operaciones de archivo con Procmon, verá desfilar con su nombre real a los protagonistas de esta entrega (escrituras en $LogFile, rutas con nombre de flujo, procesamiento de reanálisis). Para saber cómo usarlo, consulte la «Guía práctica de Process Monitor (ProcMon)».
9. Resumen
- El centro de NTFS es la MFT. Todos los archivos son registros de un libro mayor, y la información está «dentro del registro» o en «la zona externa a la que apunta el registro». Los datos pequeños son residentes y los grandes usan referencias a runs; la lentitud al procesar muchos archivos pequeños y la fragmentación son consecuencia de esta estructura. 1
- Un archivo puede tener varios flujos de datos. Zone.Identifier (Mark of the Web) no es más que un ADS: se ve con
dir /ry no se transporta fuera de NTFS. 211 - El nombre es un atributo y puede haber varios. Un enlace físico es un nombre en pie de igualdad hacia el mismo registro; el nombre 8.3 es otro nombre más para compatibilidad. «Eliminar» significa «quitar un nombre», y el contenido real desaparece cuando ya no queda ni el último nombre, ni el último identificador, ni ninguna referencia interna del núcleo (secciones mapeadas, etc.). 34
- El punto de análisis es el gancho oficial de la operación «abrir», y tanto los enlaces simbólicos como las junctions y los archivos a petición son aplicaciones de este mecanismo. El código que recorre árboles de directorios debe tener presente
FILE_ATTRIBUTE_REPARSE_POINT. 56 - Hay dos diarios.
$LogFilerecupera la coherencia de la estructura (no se corrompe), y USN registra el historial de cambios (qué cambió). No es cierto que «por ser journaling, los datos también estén a salvo»: la durabilidad de los datos se construye con las herramientas de la parte 4. 78 - El tamaño lógico y la asignación son cosas distintas. Los archivos dispersos, la compresión, el ADS y el redondeo por clúster son las cuatro grandes causas de que «el tamaño no cuadre». Esto, junto con el hecho de que los archivos comprimidos no se vuelven asíncronos, es un recurso útil para las investigaciones de rendimiento. 910
La continuación es la entrega final, la parte 6: «Controladores de filtro y minifiltros: por qué Procmon y el antivirus pueden interceptar la E/S». Cómo interceptan la E/S esos «intermediarios» —antivirus, Procmon, OneDrive, cifrado— que han ido apareciendo de vez en cuando desde la parte 1. Como colofón de la serie, revelaremos la verdadera identidad de los habitantes que se instalan en los huecos de la pila de dispositivos.
Artículos relacionados
- Las profundidades de la E/S de Windows (parte 1) — Toda lectura y escritura se convierte en un IRP: panorama general del sistema de E/S
- Las profundidades de la E/S de Windows (parte 2) — E/S síncrona y asíncrona: el verdadero significado de OVERLAPPED
- Las profundidades de la E/S de Windows (parte 4) — El administrador de caché: ¿cuándo llega su WriteFile al disco?
- Por qué aparece en Windows el mensaje «Windows protegió su PC»
- MAX_PATH y las trampas de rutas y nombres de archivo en Windows — el límite de 260 caracteres, nombres reservados, el punto final y mayúsculas/minúsculas
- Guía práctica de FileSystemWatcher: medidas contra eventos perdidos y duplicados
- Trampas de las unidades de red y las rutas UNC — la práctica de trabajar con servidores de archivos (carpetas compartidas) en aplicaciones de negocio
- Guía práctica de Process Monitor (ProcMon) — identifique en 10 minutos «no se lee la configuración» o «ACCESS DENIED»
Áreas de consultoría relacionadas
En KomuraSoft LLC nos ocupamos del diseño y la investigación de aplicaciones de negocio de Windows que tienen su raíz en el funcionamiento de NTFS: comportamientos inexplicables en el tamaño de archivos o el rendimiento de las copias, fallos relacionados con enlaces y flujos, y otros problemas similares.
- Desarrollo de aplicaciones Windows
- Investigación de fallos y análisis de causas
- Aprovechamiento de activos existentes y apoyo a la migración
- Contacto
Referencias
-
Microsoft Learn, Master File Table. Sobre que la MFT contiene al menos una entrada por cada archivo de un volumen NTFS, incluida una entrada para la propia MFT; que toda la información —tamaño, marcas de tiempo, permisos de acceso y contenido de los datos— se almacena dentro de la entrada de la MFT o en una zona fuera de la MFT cuya posición describe la entrada; que al eliminar un archivo la entrada se marca como libre y se reutiliza, pero el tamaño de la MFT no se reduce; que se reserva una zona de la MFT para mantenerla contigua; y que el avance de la asignación provoca la fragmentación de la MFT. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, File Streams. Sobre que los datos de un archivo NTFS se almacenan como uno o más flujos; que existe un flujo de datos predeterminado (sin nombre) y flujos de datos alternativos con nombre; y que se puede especificar un flujo con la forma «nombre_de_archivo:nombre_de_flujo» y abrirlo con CreateFile. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Hard links and junctions. Sobre que un enlace físico es la representación, a nivel de sistema de archivos, de que varias rutas dentro del mismo volumen hacen referencia a un único archivo; que se crea con CreateHardLink; que un cambio a través de cualquiera de los enlaces se ve de inmediato desde los demás; que hay una peculiaridad de visualización según la cual los cambios de atributos se propagan a todos los enlaces físicos, pero la visualización en la entrada de directorio solo se actualiza en el enlace desde el que se hizo el cambio; y sobre las junctions (el mecanismo que conecta un directorio con la ubicación de otro volumen local). ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, fsutil 8dot3name. Sobre que NTFS puede generar nombres cortos en formato 8.3 para los nombres de archivo largos; y que con fsutil 8dot3name se puede consultar y configurar la habilitación o deshabilitación de la generación de nombres cortos, eliminar (strip) los nombres cortos existentes, y examinar las referencias del registro afectadas al hacer la eliminación. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Reparse points. Sobre que un punto de análisis es un conjunto de datos definidos por el usuario junto con una etiqueta de reanálisis que identifica de forma única el formato de esos datos; que al abrir un archivo con un punto de análisis, el sistema de archivos intenta el procesamiento correspondiente a la etiqueta (procesamiento por un filtro de sistema de archivos que interpreta la etiqueta); que se usa en la implementación de enlaces del sistema de archivos de NTFS y del almacenamiento remoto (almacenamiento jerárquico); y que su existencia se puede confirmar con el atributo FILE_ATTRIBUTE_REPARSE_POINT. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Symbolic links. Sobre que un enlace simbólico es un objeto del sistema de archivos que apunta a otro archivo o directorio y funciona como una redirección transparente hacia el destino; y que existen enlaces absolutos y relativos, y que pueden hacer referencia a través de volúmenes o a rutas remotas. ↩ ↩2 ↩3
-
Microsoft Learn, NTFS overview. Sobre que NTFS usa el archivo de registro y la información de puntos de control para, tras un fallo del sistema, reproducir automáticamente el registro de transacciones en el siguiente arranque y recuperar la coherencia del sistema de archivos; y sobre el remapeo dinámico de sectores defectuosos y el NTFS de autorreparación (self-healing), que corrige daños menores en segundo plano. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Change Journals. Sobre que, cada vez que se modifica un archivo o directorio de un volumen, se registra en el diario de cambios USN de ese volumen el contenido del cambio y el nombre del archivo o directorio afectado; que se mantiene un diario por volumen; y que se puede usar para recuperar el índice del sistema de archivos tras un fallo, evitando reindexar todo el volumen. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, Sparse Files. Sobre que, en un archivo disperso, no se asigna espacio físico en disco a los rangos extensos formados por ceros, y solo se asigna espacio a las partes que contienen datos; y que leer un rango sin asignación devuelve ceros. ↩ ↩2 ↩3
-
Microsoft Learn, File Compression and Decompression. Sobre que la compresión de archivos de NTFS se realiza de forma transparente, comprimiendo y almacenando los datos por unidad de compresión; que GetCompressedFileSize permite obtener el tamaño tras la compresión (la asignación real); y que la lectura y escritura de archivos comprimidos conlleva el coste de descomprimir y volver a comprimir. ↩ ↩2 ↩3
-
Microsoft Learn, Streams - Sysinternals. Sobre que la utilidad streams de Sysinternals permite enumerar y eliminar flujos de datos alternativos de archivos NTFS. ↩ ↩2
-
Microsoft Learn, Creating, Modifying, and Deleting a Change Journal y fsutil usn. Sobre que MaximumSize del diario de cambios es un valor objetivo, y que cuando el tamaño supera la suma de MaximumSize y AllocationDelta, se trunca en el siguiente punto de control de NTFS; que AllocationDelta es la unidad con la que se añade al final del diario y se elimina desde el principio; que fsutil usn queryjournal muestra el estado y la capacidad del diario, y readjournal su contenido; que desde código se usan FSCTL_CREATE_USN_JOURNAL / FSCTL_QUERY_USN_JOURNAL / FSCTL_READ_USN_JOURNAL / FSCTL_DELETE_USN_JOURNAL; y que eliminar o deshabilitar un diario activo implica un recorrido de toda la MFT y obliga a los servicios que lo usan a volver a examinar el volumen. ↩ ↩2 ↩3 ↩4
Artículos relacionados
Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.
Las profundidades de la E/S de Windows (parte 4) — El administrador de caché: ¿cuándo llega su WriteFile al disco?
Cuarta entrega de la serie que explica con diagramas el administrador de caché de Windows: la caché implementada como asignación de archi...
Las profundidades de la E/S de Windows (parte 1) — Toda lectura y escritura se convierte en un IRP: panorama general del sistema de E/S
Primera entrega de la serie que explica desde la base el sistema de E/S de Windows: el espacio de nombres del Administrador de objetos, l...
Las profundidades del I/O en Windows (6.ª entrega, final) ── Controladores de filtro y minifiltros: por qué Procmon y el análisis antivirus pueden interceptar el I/O
Última entrega de la serie sobre controladores de filtro y minifiltros de Windows: el Filter Manager, las altitudes, los callbacks pre/po...
Las profundidades de la E/S de Windows (Parte 2) ── E/S síncrona y E/S asíncrona: el verdadero significado de OVERLAPPED
Segunda entrega de la serie que explica con diagramas la E/S síncrona y la E/S asíncrona (E/S superpuesta) de Windows: el significado de ...
OneDrive «Archivos bajo demanda» y las aplicaciones empresariales — las suposiciones que rompen los marcadores de posición, y cómo abordarlas
¿Un CSV del escritorio no se puede leer, o el proceso de importación falla con «Archivo no encontrado»? La causa puede ser el KFM y los A...
Temas relacionados
Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.
Temas técnicos de Windows
Portal sobre desarrollo de Windows, investigación de fallos y aprovechamiento de activos existentes.
Investigación de fallos y problemas prolongados
Fallos intermitentes, diagnóstico de comunicaciones, bloqueos prolongados y pruebas de rutas de error.
Servicios relacionados con este tema
El artículo está directamente relacionado con los siguientes servicios.
Desarrollo de aplicaciones para Windows
Aplicaciones empresariales, integración de dispositivos y herramientas de comunicación, de los requisitos al desarrollo.
Preguntas frecuentes
Preguntas habituales en las consultas sobre el tema del artículo.
- ¿Qué es la MFT (Master File Table, tabla maestra de archivos)?
- Es la estructura de datos que constituye el corazón de un volumen NTFS: un libro mayor que contiene al menos una entrada (registro de archivo) para cada archivo del volumen, incluida una entrada para la propia MFT. Toda la información relativa a un archivo —su tamaño, las marcas de tiempo, los permisos de acceso e incluso el contenido de los datos— se almacena dentro de la entrada de la MFT o en una zona fuera de la MFT a la que la entrada apunta. Si el archivo es pequeño, todo el contenido cabe dentro de la propia entrada de la MFT (residente); si es grande, la entrada solo registra una referencia al lugar donde están los datos (la secuencia de clústeres), es decir, es no residente. Al eliminar un archivo, la entrada se marca como libre y se reutiliza, pero el tamaño de la propia MFT no se reduce.
- ¿Qué es ese dato invisible llamado «Zone.Identifier» que aparece adjunto a los archivos?
- Es uno de los flujos de datos múltiples de NTFS (un flujo de datos alternativo). En NTFS, un mismo archivo puede tener varias secuencias de bytes (flujos), y lo que normalmente se lee y se escribe es el flujo predeterminado sin nombre. En un flujo adicional que se especifica con dos puntos, como en «file.txt:Zone.Identifier», Windows registra el origen del archivo (por ejemplo, que se descargó de internet). Esto es el llamado «Mark of the Web», y sirve como criterio para el aviso de SmartScreen o la vista protegida de Office. El flujo alternativo no aparece en el tamaño que muestra el Explorador, pero se puede comprobar con el comando dir /r o con la herramienta streams de Sysinternals. También conviene tener en cuenta que no se conserva al copiar a un sistema de archivos distinto de NTFS, como FAT.
- ¿En qué se diferencian un enlace físico y un enlace simbólico?
- Un enlace físico (hard link) consiste en «añadir un nombre más, en pie de igualdad, que apunta al mismo contenido real del archivo (el mismo registro MFT)». Solo se puede crear dentro del mismo volumen, se accede al mismo archivo sin importar desde qué nombre, y si se elimina uno de los nombres, el archivo no desaparece mientras queden otros nombres. El enlace simbólico es «un indicador que dirige hacia otra ruta», y se implementa como un punto de análisis. Como solo conserva la cadena de la ruta de destino, puede apuntar a otro volumen o a un recurso remoto, pero si el destino desaparece, el enlace queda en un callejón sin salida. En la práctica, la distinción básica es: el enlace físico para compartir el contenido real (lo que cambia el significado de «eliminar»), y el enlace simbólico para redirigir rutas (traslados o redirecciones).
- Como NTFS es un sistema de archivos con journaling, ¿los datos no se pierden ni siquiera con un corte de energía?
- Hay que entender con precisión hasta dónde llega la protección. Lo que protege el registro de transacciones de NTFS ($LogFile) es la coherencia de la estructura (los metadatos) del sistema de archivos. Aunque se produzca un fallo del sistema, en el siguiente arranque se usa el registro para recuperar automáticamente la coherencia y evitar que «el volumen quede corrupto e ilegible». Sin embargo, esto no significa que se restaure el propio contenido de los datos de un archivo que se estaba escribiendo. Como vimos en la parte 4 de la serie, los datos sucios que están en la caché se pierden con un corte de energía. Es decir, la comprensión correcta es que «el volumen no se corrompe, pero el contenido de la última escritura puede perderse»; si se necesita durabilidad para los propios datos, hay que construirla con FlushFileBuffers, WRITE_THROUGH, o con un diseño de escritura en la propia aplicación (archivo temporal + renombrado, etc.).
- ¿Por qué el «Tamaño» de un archivo y su «Tamaño en el disco» son diferentes?
- Porque en NTFS la longitud lógica de un archivo y el espacio de disco realmente asignado se gestionan por separado. Incluso en un archivo normal aparece una diferencia porque la asignación se redondea por unidad de clúster (4 KB de forma predeterminada), pero la divergencia se vuelve grande en los archivos dispersos y en los archivos comprimidos. En un archivo disperso, no se asigna espacio real a los tramos que son ceros seguidos, sino que se gestionan como «huecos», por lo que puede ocurrir que un tamaño lógico de varios GB ocupe solo unos pocos MB en el disco. En un archivo comprimido, solo se asigna el tamaño tras la compresión. A la inversa, cuando el «Tamaño en el disco» parece mayor, la causa puede ser el redondeo por clúster o los flujos de datos alternativos.
Perfil del autor
Página de presentación del autor del artículo.
Go Komura
Representante de KomuraSoft LLC
Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.