Dlaczego nie ma wywołań wstawiania plików?

11

O ile mi wiadomo, do manipulowania plikami istnieje tylko sys_write syscall w Linuksie, który zastępuje zawartość pliku (lub rozszerza go, jeśli na końcu).

Dlaczego nie ma wywołań systemowych do wstawiania lub usuwania treści w plikach w systemie Linux?

Ponieważ wszystkie obecne systemy plików nie wymagają przechowywania pliku w ciągłym bloku pamięci, wydajna implementacja powinna być możliwa. (Pliki uległyby fragmentacji.)

W przypadku funkcji systemu plików, takich jak „kopiuj przy zapisie” lub „przezroczysta kompresja plików”, obecny sposób wstawiania zawartości wydaje się bardzo nieefektywny.

dercolamann
źródło
4
Podobnie jak w przypadku wszystkich fantazyjnych operacji na plikach, taka operacja jest znacznie mniej przydatna w praktyce, niż się wydaje. Głównym zastosowaniem takich rzeczy są bardzo wyspecjalizowane aplikacje, takie jak bazy danych, emulatory i tym podobne. Zazwyczaj „edytujesz” plik, tworząc nowy plik i wykonując operację „zapisz” przez użytkownika, zmienia nazwę nowego pliku na stary.
mosvy
3
@mosvy, ale czy użyto koncepcji „utwórz nowy plik, a następnie zmień nazwę”, ponieważ jest on sam w sobie dobry, czy właśnie dlatego, że system nie zapewnia lepszego sposobu? Zwłaszcza na plikach tekstowych operacje takie jak „modyfikuj tę linię (zmieniając długość)” lub „wstaw te linie tutaj” są dość powszechne, więc można założyć, że operacje systemu plików dla tych dokładnych funkcji byłyby wykorzystane, gdyby tam były. Oczywiście nie ich posiadania sprawia, że realizacja fs znacznie prostsze ...
ilkkachu
1
@meuh OpenVMS nadal działa poprzez RMS (Record Management Services).
RonJohn
1
UNIX rozpoczął odejście od udostępniania systemów zarządzania rekordami w systemie plików.
user207421,
1
@ilkkachu jest samo w sobie dobre, absolutnie bez wątpienia ;-) Co więcej, gdyby i-węzły były niezmienne, to sprawi, że implementacja współdzielenia bloków, wersjonowania i prawie wszystkiego będzie znacznie wydajniejsza (i o wiele prostsza do uzasadnienia). Pomyśl analogicznie, jak wszystkie języki skryptowe przełączyły się na niezmienne ciągi - ale skrócę to tutaj; trudno mówić o mankietach na temat systemów plików i nie zabrzmieć jak
kwak

Odpowiedzi:

22

W najnowszych systemach Linux jest to faktycznie możliwe, ale z blokiem (przez większość czasu 4096), bez ziarnistości bajtów i tylko w niektórych systemach plików (ext4 i xfs).

Cytowanie ze strony fallocate(2)man:

int fallocate(int fd, int mode, off_t offset, off_t len);

[...]

Zwijanie przestrzeni plików

Określenie FALLOC_FL_COLLAPSE_RANGEflagi (dostępnej od Linuksa 3.15) modeusuwa zakres bajtów z pliku, nie pozostawiając dziury. Zakres bajtów do zwinięcia zaczyna się od offseti trwa dla len bajtów. Po zakończeniu operacji zawartość pliku rozpoczynającego się w lokalizacji offset+lenzostanie do niej dołączona offset, a plik będzie lenmniej bajtów.

[...]

Zwiększanie przestrzeni plików

Określenie FALLOC_FL_INSERT_RANGEflagi (dostępnej od Linuksa 4.1) w modezwiększa przestrzeń plików poprzez wstawienie dziury w rozmiarze pliku bez nadpisywania istniejących danych. Dziura rozpocznie się od offseti będzie kontynuowana przez lenbajty. Podczas wstawiania dziury do pliku zawartość pliku rozpoczynająca się od offsetzostanie przesunięta w górę (tj. Do większego przesunięcia pliku) o lenbajty. Wstawienie dziury do pliku zwiększa rozmiar pliku o lenbajty.

mosvy
źródło
1
„ale z blokiem (4096), bez ziarnistości bajtów” - bloki 4KiB są bardzo częste w ext4, ale nie jest to gwarantowane. Ext4 obsługuje rozmiary bloków 1KiB, 2KiB i 4KiB ; i pamiętam z ostatnich 2 dni, że na procesorach Alpha obsługiwane było również 8KiB. Obawiam się, że nie można po prostu założyć, że bloki to 4KiB.
marcelm
1
4k (która jest domyślna) to wielokrotność 1k i 2k, więc nie ma problemu z założeniem 4k z ext4. Podczas gdy xfs również domyślnie ma wartość 4k, ma on obsługiwać bs większy niż 4k - do 64k, ale udało mi się stworzyć taki fs - montaż nie powiedzie się bez ENOSYS. W każdym razie nie możesz niczego zakładać - ta funkcja nie jest obsługiwana na wszystkich fs, więc lepiej jest powiedzieć blok = 4096, więc czytelnik ma pewne poczucie proporcji, zamiast pozwolić, by się unosił i pozwalał ludziom być czymkolwiek, lub gorzej, że ma 512 bajtów lub jest w jakiś sposób związany z rozmiarem strony vm.
mosvy
Po zakończeniu edycji (gdzie mówisz, że zwykle jest to 4KiB), w pełni się zgadzam! Mój problem polegał na tym, że wcześniej był łatwo odczytywany jako „bloki są zawsze 4KiB” , co może powodować, że ludzie przyjmują takie założenie i piszą błędny kod.
marcelm
9

Ponieważ wszystkie obecne systemy plików nie wymagają przechowywania pliku w ciągłym bloku pamięci,

Systemy plików mogą nie wymagać przechowywania plików w ciągłym obszarze (i byłoby to rzeczywiście bardzo mało elastyczne), ale zwykle pliki są przechowywane w blokach o stałej wielkości (lub sekwencjach ciągłych bloków). Wykonanie tego w ten sposób upraszcza implementację, a bloki są zwykle wielokrotnościami wielkości bloku urządzenia bazowego.

Tak więc implementacja wstawek bloków o dowolnej długości spowodowałaby, że format i implementacja systemu plików byłaby bardziej złożona lub wymagałaby przenoszenia potencjalnie dużych ilości danych. Żadne z nich nie jest naprawdę dobre, a złożone struktury danych można budować w przestrzeni użytkownika na interfejsie API systemu plików.

ilkkachu
źródło