File openings and shared memory on Linux?

Since I read a book on the Linux programming interface (read very well), I discovered files on Linux. Therefore, using Unix file formats such as Ext4, you can open a new file that writes 1000 bytes, look for the position of 1000.000.000, write another 1000 bytes, and depending on the size of the file format block, you end up with a file that consumes only 2048 bytes for size block 1024 or 512.

Thus, the file is created as a file of 1 GB + 1000 bytes in size, in which only two blocks of real space are used.

Is it possible to erase the middle of a file, causing the system to free these blocks on disk?

Is there an equivalent where I allocate (shared memory) with or without a file, where it also has holes that are just filled when writing memory pages?

It would be nice to allocate 1 GB of shared memory, but never use it completely until you need it, to avoid reassignment if the shared memory block needs to grow.

0
source share
1 answer

Is it possible to erase the middle of a file, causing the system to free these blocks on disk?

, Linux fallocate (2); , (, NFS, VFAT,...), . . lseek (2) SEEK_HOLE, posix_fadvise (2), madvise (2), memfd_create (2) ..

(, USB- SSD) ( mmap ). - .

1 ,

. , ( - , ). shm_overview (7), ( mmap (2)). , , paging, MMU, , , , mmap, , copy-on-write, , ELF, ... cat /proc/$$/maps (. proc (5)...).

, , . Linux mmap (2).

, mmap MAP_NORESERVE

size_t onegiga = 1L<<30;
void* startad = mmap(NULL, onegiga, PROT_NONE, 
                MAP_ANONYMOUS|MAP_NORESERVE|MAP_SHARED,
                -1, 0);
if (startad==MAP_FAILED) { perror("mmap MAP_NORESERVE"); exit(EXIT_FAILURE); }
void* endad = (char*)startad + onegiga;

MAP_NORESERVE (.. , , , ). , mmap ( MAP_FIXED) ( munmap ).

- ( 4 ), MAP_FIXED ,

size_t segoff = 1024*1024; // or something else such that ....
assert (segoff >=0  && segoff < onegiga && segoff % sysconf(_SC_PAGESIZE)==0);
size_t segsize = 65536; // or something else such that ....
assert (segsize > 0 && segsize % sysconf(_SC_PAGESIZE)==0 
        && startad + segoffset + segsize < endad);
void* segmentad = mmap(startad + segoffset, segsize,
                       PROT_READ|PROT_WRITE, 
                       MAP_FIXED | MAP_PRIVATE, 
                       -1, 0);
if (segmentad == MAP_FAILED) { perror("mmap MAP_FIXED"); exit(EXIT_FAILURE); }

MAP_FIXED (, ).

IIRC, SBCL .

Linux syscalls (2) .

. Linux, (, proc (5)).

BTW, ​​Linux . kernel.org . . , .

+3

Source: https://habr.com/ru/post/1598088/


All Articles