Selama Anda tidak memindahkan file melintasi batas sistem file, operasi harus aman. Ini karena mekanisme, bagaimana »bergerak« sebenarnya dilakukan.
Jika Anda mv
file pada sistem file yang sama, file tersebut tidak benar-benar disentuh, tetapi hanya entri sistem file yang diubah.
$ mv foo bar
sebenarnya melakukan sesuatu seperti
$ ln foo bar
$ rm foo
Ini akan membuat tautan keras (entri direktori kedua) untuk file (sebenarnya inode yang ditunjuk oleh entri sistem file) foo
bernama bar
dan menghapus foo
entri. Karena sekarang ketika menghapus foo
, ada entri sistem file kedua yang menunjuk ke foo
inode, menghapus entri lama foo
tidak benar-benar menghapus blok milik inode.
Program Anda akan dengan senang hati menambahkan file, karena file-handle yang terbuka menunjuk ke inode file, bukan entri sistem file.
Catatan: Jika program Anda menutup dan membuka kembali file di antara waktu menulis, Anda akhirnya akan membuat file baru dengan entri sistem file lama!
Pemindahan lintas sistem file:
Jika Anda memindahkan file melintasi batas sistem file, segalanya menjadi jelek. Dalam hal ini Anda tidak dapat menjamin agar file Anda tetap konsisten, karena mv
sebenarnya
- buat file baru di sistem file target
- salin isi dari file lama ke file baru
- hapus file lama
atau
$ cp /path/to/foo /path/to/bar
$ rm /path/to/foo
resp.
$ touch /path/to/bar
$ cat < /path/to/foo > /path/to/bar
$ rm /path/to/foo
Bergantung pada apakah penyalinan mencapai akhir file selama penulisan aplikasi Anda, bisa jadi Anda hanya memiliki setengah baris dalam file baru.
Selain itu, jika aplikasi Anda tidak menutup dan membuka kembali file lama, itu akan terus menulis ke file lama, bahkan jika itu tampaknya dihapus: kernel tahu file mana yang terbuka dan meskipun itu akan menghapus entri sistem file, itu tidak akan menghapus inode file lama dan blok terkait sampai aplikasi Anda menutup pegangan file yang terbuka.
rename()
panggilan sistem. Jadi versi asli darimv
panggilan sebenarnyalink()
untuk membuat tautan keras, diikuti olehunlink()
untuk menghapus nama asli.rename()
ditambahkan di FreeBSD, untuk mengimplementasikannya secara atomik di kernel.