[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: sigo con el "du"



Hola Jaime y Fernando,

  Antes de nada presentarme, es la primera vez que escrivo en la lista
aunque hace tiempo que la sigo como lector.

  Bueno a lo que iba. Que el du funciona bien en la version de potato,
no asi en la de slink como indica Fernando. Me explico. El du como su
nombre indica sirve para indicarnos el numeros de espacio ocupado en
disco por un fichero, esto en los sistemas de ficheros unix no tiene
porque coincidir con el tamaño del fichero en si, es decir un fichero
puede ser mucho mas grande de lo que realmente ocupa en disco. Y como
se hace esto? Pues basicamente las zonas del fichero sin informacion
(a zero) no ocupan ningun bloque, no es hasta que se ocupa con algo
de informacion que se ocupa ese bloque fisicamente en el disco. Os
recomiendo la lectura de algun libro que trate sobre el tema.

Para comprobarlo podeis usar el programita de ejemplo adjunto.
Basicamente lo que hace es crear un fichero de tamaño indicado
haciendo un lseek hasta la ultima posicion. Con esto se crea un
espacio en medio sin informacion que no se guarda en el disco.
Si ejecutais el programa vereis como funciona el du.

Se puede comprobar como du devuelve TODOS los bloques ocupados, no solo
por los datos del fichero sino tambien por posibles bloques de indice
de doble y triple indireccion del inode. Asi tenemos que hasta 12K
el fichero ocupa 1 bloque (el ultimo que es el que tiene la informacion),
a partir de 13K se usa una indireccion y por tanto se requiere un bloque
adicional para guardar el ultimo bloque del fichero, la doble indireccion
se alcanza en 13K + 1024/4 K = 269K y la triple en 13K + 256 * 256K =
64,269M.

Si no quieres probarlo tu mismo aqui tienes los resultados:
~% ./a.out p `expr 12 \* 1024`; du p
1       p
~% ./a.out p `expr 13 \* 1024`; du p
2       p
~% ./a.out p `expr 12 \* 1024 + 256 \* 1024`; du p
2       p
~% ./a.out p `expr 13 \* 1024 + 256 \* 1024`; du p
3       p
~% ./a.out p `expr 12 \* 1024 + 256 \* 1024 + 256 \* 256 \* 1024`; du p
3       p
~% ./a.out p `expr 13 \* 1024 + 256 \* 1024 + 256 \* 256 \* 1024`; du p
4       p


du no indica el bloque ocupado por el inodo primero porque esta compartido
con otros inodos y por otra parte ese espacio nunca puede ser utilizado por
datos de un fichero.

Por otra parte al usar cp el sistema copia los bloques de datos utilizados
mientras que con cat lo que se esta haciendo es leer todos los datos del
fichero original y escibiendolos de nuevo, en este caso los "agujeros" del
medio se consideran zeros que son grabados como informacion y por tanto ocupan
espacio en disco. Para eliminar este espacio se puede usar el programa perforate.

Finalmente sum y md5sum dan los mismos resultados ya que se basan en los
datos del fichero que son todos iguales ya que el kernel interpreta directamente
los bloques inexistentes como zeros. Por otra parte se ve como sum indica el
numero de bloques totales que ocupa el fichero no asi los fisicos.

Espero haber ayudado a entender el funcionamiento del sistema de ficheros
de unix y no haber liado mas.

Resumiendo, no hay que hacer ningun bug report del du.


On Fri, Nov 12, 1999 at 11:44:35AM +0000, Jaime E. Villate wrote:
> Fernando responde a mi respuesta:
> > Lo que no entiendo es como siendo lastlog = lastlog2
> > ( por que son iguales no ?  tienen el mismo sum y md5sum)
> > con uno funciona bien y con el otro no.
> 
> Buena pregunta; y no tengo ni idea de la respuesta. Pero sospecho que a
> pesar de ser identicos los dos ficheros están distribuídos de forma
> fisica diferente en el disco. Ya uno de los bugs de "du" decia que no
> funciona cuando el fichero tiene huecos. Eso explicaria porque al hacer
> "cat" ya funciona (se tapan los huecos), pero todavia no entiendo porque
> al hacer "cp" desde /var/log hacia ~ no ocurre lo mismo.

-- 
Ricard Sierra Rebull
e-mail: rsierra@mail.com
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
	      
int main(int a, char *v[])
{
  int fd;
  if (a!=3) return 1;
  if ((fd = creat(v[1],0666)) < 0)
    { perror("open()"); return 1; }
  if (lseek(fd,atol(v[2])-1,SEEK_END) < 0)
    { perror("lseek()"); return 1; }
  if (write(fd,v[1],1) < 0)
    { perror("lseek()"); return 1; }
  close(fd); 
  return 0;
}


Reply to: