Programación del sistema Linux 20 Sistema de archivos: análisis de archivos huecos st_size, st_blksize, st_blocks

分析 off_t st_size 、 blksize_t st_blksize , blkcnt_t st_blocks;

 struct stat {
           dev_t     st_dev;         /* ID of device containing file */文件所在设备的ID
           ino_t     st_ino;         /* inode number */节点号
           mode_t    st_mode;        /* protection */文件的类型和存取的权限
           nlink_t   st_nlink;       /* number of hard links */链向此文件的连接数(硬连接)
           uid_t     st_uid;         /* user ID of owner */
           gid_t     st_gid;         /* group ID of owner */
           dev_t     st_rdev;        /* device ID (if special file) */设备ID号,针对设备文件
           off_t     st_size;        /* total size, in bytes */文件大小,字节为单位
           blksize_t st_blksize;     /* blocksize for filesystem I/O */系统块的大小
           blkcnt_t  st_blocks;      /* number of 512B blocks allocated */文件所占块数

           /* Since Linux 2.6, the kernel supports nanosecond
              precision for the following timestamp fields.
              For the details before Linux 2.6, see NOTES. */

           struct timespec st_atim;  /* time of last access */最近存取时间
           struct timespec st_mtim;  /* time of last modification */最近修改时间
           struct timespec st_ctim;  /* time of last status change */

       #define st_atime st_atim.tv_sec      /* Backward compatibility */
       #define st_mtime st_mtim.tv_sec
       #define st_ctime st_ctim.tv_sec
       };

off_t st_size; / * tamaño total, en bytes /
tamaño de archivo , en bytes blksize_t st_blksize; / blocksize para E / S del sistema de archivos / tamaño de bloque del sistema
blkcnt_t st_blocks; /
número de 512B bloques asignados * / número de bloques asignados por el archivo

Mucha gente piensa

st_size = st_blocks * st_blksize

Sin embargo, es incorrecto. Esta es la idea del sistema Windows. En Windows, el tamaño de un archivo es en realidad el tamaño de un archivo en el disco. Pero este no es el caso en el sistema UNIX. Esta diferencia está relacionada con el sistema de archivos. En el sistema UNIX, el valor st_size es solo un atributo de un archivo, y st_blksize * st_blocks realmente determina el tamaño del espacio en disco ocupado por el archivo.

Experimento 1. El archivo vacío demuestra que el tamaño del archivo en el sistema UNIX no es igual al espacio en disco ocupado por el archivo.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
	int fd;

	if(argc < 2)
	{
		fprintf(stderr,"Usage......\n");
		exit(1);
	}
	
	fd = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0600);
	if(fd < 0)
	{
		perror("open()");
		exit(1);
	}	
	//生成空洞文件 5G
	lseek(fd, 5* 1024 *1024 *1024-1, SEEK_SET);
	write(fd,"",1);//执行一次系统调用 尾部写0,不然当前文件不占空间
	close(fd);

	exit(0);
}

mhr@ubuntu:~/work/linux/wenjianxitong/20$ gcc big.c 
big.c: In function ‘main’:
big.c:25:26: warning: integer overflow in expression [-Woverflow]
  lseek(fd, 5* 1024 *1024 *1024-1, SEEK_SET);
                          ^
mhr@ubuntu:~/work/linux/wenjianxitong/20$ 
mhr@ubuntu:~/work/linux/wenjianxitong/20$ 
mhr@ubuntu:~/work/linux/wenjianxitong/20$ ./a.out bigfile
mhr@ubuntu:~/work/linux/wenjianxitong/20$ 
mhr@ubuntu:~/work/linux/wenjianxitong/20$ stat bigfile 
  File: 'bigfile'
  Size: 1073741824	Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d	Inode: 12849444    Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/     mhr)   Gid: ( 1000/     mhr)
Access: 2020-05-04 08:58:16.199732985 -0700
Modify: 2020-05-04 08:58:35.151295622 -0700
Change: 2020-05-04 08:58:35.151295622 -0700
 Birth: -
mhr@ubuntu:~/work/linux/wenjianxitong/20$ 

Se encuentra que el tamaño no es 5G, lo que indica que efectivamente se ha producido el desbordamiento "desbordamiento de enteros" en la advertencia. El motivo del desbordamiento de enteros es que en el programa es igual que en materias como matemáticas y física. Los valores numéricos sin unidades no tienen sentido, por lo que el código

lseek(fd, 5* 1024 *1024 *1024-1, SEEK_SET);

El valor en, debido a que no hay una unidad marcada, el sistema lo considerará como un entero con signo por defecto, por lo que los datos se desbordarán aquí, por lo que necesitamos ampliar el tipo de datos aquí,

cambio:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
	int fd;

	if(argc < 2)
	{
		fprintf(stderr,"Usage......\n");
		exit(1);
	}
	
	fd = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0600);
	if(fd < 0)
	{
		perror("open()");
		exit(1);
	}	
	//生成空洞文件 5G
	lseek(fd, 5LL* 1024LL *1024LL *1024LL-1LL, SEEK_SET);
	write(fd,"",1);
	close(fd);

	exit(0);
}

mhr@ubuntu:~/work/linux/wenjianxitong/20$ 
mhr@ubuntu:~/work/linux/wenjianxitong/20$ gcc big.c 
mhr@ubuntu:~/work/linux/wenjianxitong/20$ ./a.out bigfile
mhr@ubuntu:~/work/linux/wenjianxitong/20$ stat bigfile 
  File: 'bigfile'
  Size: 5368709120	Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d	Inode: 12849444    Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/     mhr)   Gid: ( 1000/     mhr)
Access: 2020-05-04 08:58:16.199732985 -0700
Modify: 2020-05-04 09:04:27.883813275 -0700
Change: 2020-05-04 09:04:27.883813275 -0700
 Birth: -
mhr@ubuntu:~/work/linux/wenjianxitong/20$ 

El tamaño del tamaño aquí es correcto, Tamaño: 5368709120, y se encuentra que el espacio en disco ocupado por este archivo de tamaño 5G en el entorno actual es 8 * 512 4k. Esto muestra que el tamaño del archivo en el sistema UNIX y el espacio en disco ocupado por el archivo no son iguales.

Inode: 12849443 es la identificación única de un archivo, equivalente al número de identificación

Supongo que te gusta

Origin blog.csdn.net/LinuxArmbiggod/article/details/105925175
Recomendado
Clasificación