Teniendo que hacer un
mplayer -vo xv -ao alsa /descargas/Temp/014.part
resulta que hice un
rm /descargas/Temp/014.part
y como en la consola no hay papelera de reciclaje, pues… ¡cucú!
Así que me puse a buscar como loco y al final encontré este documento.
Hay que remarcar que tal fichero estaba abierto por el aMule mientras ocurría todo esto, y ha sido gracias a eso que lo he podido recuperar.
Abreviando, el método consiste en buscar qué PID tiene el programa que está tirando del fichero:
pablo@golgi:~$ ps aux | grep amule | grep -v grep
pablo 4165 1.6 3.6 114592 37976 ? Sl May25 214:10 amule
Y a continuación ir a su correspondiente entrada en /proc. Si el PID es el 4165, su entrada será /proc/4165/, y en /proc/4165/fd/ tendremos enlaces a los descriptores de fichero abiertos.
Con lsof +L1 podemos ver qué inodos carecen de referencias, y además qué descriptor de fichero tienen (si hay alguno). En este caso la columna correspondiente de la salida de lsof nos dice que tiene el descriptor 11, ¡¡así que en /proc/4165/fd/11 tenemos el fichero!! Ahora hacemos…
cp /proc/4165/fd/11 /descargas/Temp/014.part
Y todo como si nada (por cierto, el sistema de ficheros era ext3, pero eso debería de dar igual).
Ahora la explicación larga:
La información en el disco duro se almacena en sectores, y cada sector se identifica secuencialmente por un número.
Si queremos guardar un fichero, el sistema operativo busca una serie de sectores libres donde quepa el fichero y a continuación creará un inodo y copia el contenido del fichero a esos sectores libres. Ese inodo (nodo índice) es un índice de qué sectores ocupa el fichero, además de guardar qué permisos tiene el fichero, tamaño, tipo de fichero (enlace duro, enlace simbólico, fichero normal, directorio, etc.), propietarios, etc. Otro de los datos que guarda es un contador de referencias.
Un directorio es un fichero que guarda los nombres de los ficheros que hay dentro suyo y una referencia a sus respectivos inodos.
Cuando borramos un fichero lo primero que se hace es desvincular el nombre del fichero del inodo, es decir, borrar la entrada correspondiente del fichero de directorio. Así nadie podrá acceder a ese fichero, ya que cuando hacemos referencia al nombre del fichero, éste no aparece en el fichero de directorio. Además de borrar el nombre se disminuye en uno el contador de referencias del inodo.
Sin embargo, no sólo hay que desvincular el nombre, si no que también hay que borrar el inodo. Mientras el fichero está siendo usado por algún proceso el inodo permanecerá ahí, pero en el momento en que ese proceso cierre el fichero, el sistema operativo borrará el inodo por tener a cero el contador de referencias, y además todos los sectores usados por el contenido del fichero los marcará como libres.
En el caso anterior al haber hecho un rm teníamos el nombre desvinculado, pero como el proceso amule estaba tirando del fichero aún teníamos el inodo en disco y los sectores del fichero intactos.
Gracias a /proc y lsof pude localizar el descriptor de fichero que se refería a ese inodo, y al copiarlo lo que se hace es meterlo en sectores nuevos, indexados por un nuevo inodo, que tendrá su propia entrada en el fichero del directorio /descargas/Temp/ (i.e., un nombre).
Otra de las opciones que traté de hacer era, mediante debugfs, tratar de crear una entrada en el fichero de directorio hacia ese inodo, pero no conseguí que tragara con el número de inodo que le di (y que saqué mediante lsof)