Kenapa '.' tautan keras di Unix?

51

Saya telah melihat banyak penjelasan mengapa penghitungan tautan untuk direktori kosong di OS berbasis Unix adalah 2 bukannya 1. Mereka semua mengatakan bahwa itu karena '.' direktori, yang setiap direktori tunjuk kembali ke dirinya sendiri. Saya mengerti mengapa memiliki konsep '.' berguna untuk menentukan jalur relatif, tetapi apa yang diperoleh dengan mengimplementasikannya di tingkat filesystem? Mengapa tidak hanya memiliki cangkang atau sistem panggilan yang mengambil jalur tahu bagaimana menafsirkannya?

Itu '..' adalah tautan nyata yang jauh lebih masuk akal bagi saya - sistem file perlu menyimpan pointer kembali ke direktori induk untuk menavigasi ke sana. Tetapi saya tidak mengerti mengapa '.' menjadi tautan yang nyata diperlukan. Tampaknya juga mengarah ke kasus khusus yang jelek dalam implementasi - Anda akan berpikir Anda hanya bisa membebaskan ruang yang digunakan oleh inode yang memiliki jumlah tautan kurang dari 1, tetapi jika mereka direktori, Anda benar-benar perlu memeriksa untuk a tautan dihitung kurang dari 2. Mengapa inkonsistensi?

Joseph Garvin
sumber
1
Setelah Anda memiliki ..hardlinks, perangkat lunak tree walk Anda sudah perlu memiliki pengecualian "jangan ikuti siklus pada tautan direktori induk" , jadi ini sedikit menambah kerumitan selain .tautan.
dmckee

Jawaban:

37

Pertanyaan yang menarik. Sekilas saya melihat keuntungan-keuntungan berikut:

Pertama-tama Anda menyatakan bahwa menafsirkan " ." sebagai direktori saat ini dapat dilakukan oleh Shell atau dengan panggilan sistem. Tetapi memiliki entri-titik dalam direktori sebenarnya menghilangkan keharusan ini dan memaksa konsistensi bahkan pada tingkat yang lebih rendah.

Tapi saya tidak berpikir bahwa ini adalah ide dasar di balik keputusan desain ini.

Ketika file sedang dibuat atau dihapus dari direktori, cap waktu modifikasi direktori harus diperbarui juga. Stempel waktu ini disimpan dalam inode-nya. Nomor inode disimpan dalam entri direktori yang sesuai.

JIKA entri titik tidak akan ada di sana, rutinitas harus mencari nomor inode pada entri untuk direktori ini di direktori induk, yang akan menyebabkan pencarian direktori lagi.

TAPI untungnya ada titik entri di direktori saat ini. Rutin yang menambah atau menghapus file di direktori saat ini hanya harus melompat kembali ke entri pertama (di mana entri-titik biasanya berada) dan segera telah menemukan nomor inode untuk direktori saat ini.

Ada hal baik ketiga tentang entri titik:

Ketika fsckmemeriksa sistem file yang busuk dan harus berurusan dengan blok yang tidak terhubung yang juga tidak ada dalam daftar gratis, mudah untuk memverifikasi apakah blok data (ketika diartikan sebagai daftar direktori) memiliki entri titik yang menunjuk ke inode yang pada gilirannya menunjuk kembali ke blok data ini. Jika demikian, blok data ini dapat dianggap sebagai direktori yang hilang yang harus dihubungkan kembali.

ktf
sumber
Jawaban yang sangat berguna.
Navaneeth KN
6
Komentar tentang rutinitas mencari inode direktori adalah palsu. Rutin kernel tidak perlu mencari .di direktori saat ini. Kecuali Anda dapat menemukan kernel yang berfungsi seperti ini (saya ragu ...)
Dietrich Epp
1
Saya setuju dengan @DietrichEpp; agar sistem dapat melihat entri direktori di tempat pertama , ia harus sudah tahu tentang inode - karena begitulah cara masuk ke blok data yang berisi entri direktori.
Lqueryvg
10

(Hmm: berikut ini sekarang sedikit epik ...)

Desain direktori pada sistem file unix (yang, untuk menjadi bertele-tele, biasanya tetapi tidak harus terpasang pada OS unix) mewakili wawasan yang luar biasa, yang sebenarnya mengurangi jumlah kasus khusus yang diperlukan.

'Direktori' sebenarnya hanyalah sebuah file di sistem file. Semua konten aktual file dalam sistem file ada dalam inode (dari pertanyaan Anda, saya dapat melihat bahwa Anda sudah mengetahui beberapa hal ini). Tidak ada struktur ke inode pada disk - mereka hanya sekelompok besar byte byte, menyebar seperti selai kacang di atas disk. Ini tidak berguna, dan memang penolak bagi siapa pun dengan sedikit pun pikiran yang rapi.

Satu- satunya inode khusus adalah inode nomor 2 (bukan 0 atau 1, karena alasan Tradisi); inode 2 adalah file direktori: direktori root . Ketika sistem me-mount sistem file, ia 'tahu' ia harus membaca ind 2, untuk memulai sendiri.

File direktori hanyalah file, dengan struktur internal yang dimaksudkan untuk dibaca oleh opendir (3) dan teman-teman. Anda dapat melihat struktur internalnya didokumentasikan dalam dir (5) (tergantung pada OS Anda); jika Anda melihatnya, Anda akan melihat bahwa entri file direktori hampir tidak berisi informasi tentang file - itu semua ada di inode file. Salah satu dari beberapa hal yang istimewa tentang file ini adalah bahwa fungsi open (2) akan memberikan kesalahan jika Anda mencoba untuk membuka file direktori dengan mode yang memungkinkan penulisan. Berbagai perintah lain (untuk mengambil hanya satu contoh, hexdump) akan menolak untuk bertindak secara normal dengan file direktori, hanya karena itu mungkin bukan apa yang ingin Anda lakukan (tapi itu kasus khusus mereka, bukan sistem file).

Sebuah hard link tidak lebih dan tidak kurang dari entri dalam peta file direktori. Anda dapat memiliki dua (atau lebih) entri dalam peta seperti itu yang keduanya memetakan ke nomor inode yang sama: karena itu inode memiliki dua (atau lebih) tautan keras. Ini juga menjelaskan mengapa setiap file memiliki setidaknya satu 'tautan keras'. Inode memiliki jumlah referensi, yang mencatat berapa kali inode disebutkan dalam file direktori di suatu tempat di filesystem (ini adalah nomor yang Anda lihat ketika Anda melakukannya ls -l).

OK: kita langsung ke pokok permasalahan sekarang.

File direktori adalah peta string ('nama file') ke angka (nomor inode). Nomor-nomor inode itu adalah nomor-nomor inode dari file-file yang 'berada' dalam direktori itu. File-file yang 'di' direktori itu mungkin termasuk file direktori lain, sehingga nomor inode mereka akan berada di antara yang tercantum dalam direktori. Jadi, jika Anda memiliki file /tmp/foo/bar, maka file direktori foomenyertakan entri untuk bar, memetakan string itu ke inode untuk file itu. Ada juga entri di file direktori /tmp, untuk file direktori fooyang 'di' direktori /tmp.

Ketika Anda membuat direktori dengan mkdir (2), fungsi itu

  1. membuat file direktori (dengan beberapa nomor inode) dengan struktur internal yang benar,
  2. menambahkan entri ke direktori induk, memetakan nama direktori baru ke inode baru ini (yang menyumbang salah satu tautan),
  3. menambahkan entri ke direktori baru, memetakan string '.' ke inode yang sama (akun ini untuk tautan lain), dan
  4. menambahkan entri lain ke direktori baru, memetakan string '..' ke inode dari file direktori yang dimodifikasi pada langkah (2) (ini menyumbang lebih banyak tautan keras yang akan Anda lihat di file direktori yang berisi subdirektori ).

Hasil akhirnya adalah (hampir) satu-satunya kasus khusus adalah:

  • Fungsi terbuka (2) mencoba membuatnya lebih sulit untuk menembak diri sendiri, dengan mencegah Anda membuka file direktori untuk ditulis.
  • Fungsi mkdir (2) membuat semuanya menjadi menyenangkan dan mudah dengan menambahkan beberapa entri tambahan ('.' Dan '..') ke file direktori baru, murni untuk membuatnya nyaman untuk bergerak di sekitar sistem file. Saya menduga bahwa sistem file akan bekerja dengan baik tanpa '.' dan '..', tetapi akan sulit digunakan.
  • File direktori adalah salah satu dari beberapa jenis file yang ditandai sebagai 'spesial' - ini benar-benar memberi tahu hal-hal seperti open (2) untuk berperilaku sedikit berbeda. Lihat st_modepada stat (2).

(disalin dari pertanyaan asli stackoverflow, 2011-10-20)

Norman Gray
sumber
1
Anda membingungkan blok dengan inode. Sebagai kasus khusus, untuk file pendek, konten file mungkin ada di dalam inode, tetapi salah jika menyatakan bahwa inode tidak terstruktur. Mereka sangat terstruktur, mengandung hampir semua metadata file kecuali nama file tempat file tersebut ditemukan. Inode berisi pointer (langsung, tidak langsung, dua kali lipat tidak langsung, dll) ke blok pada disk, tempat konten file berada.
Phil P
1
Tidak, saya tidak membingungkan blok dengan inode. Inode adalah abstraksi yang berada di atas blok, dan inti dari postingan ini adalah untuk menggambarkan hubungan antara file dan direktori, dan kontennya: semua struktur sistem file berasal dari file direktori. Sudah cukup lama tanpa terjebak dalam implementasi inode! (yang mengatakan, saya mungkin bisa menulis beberapa paragraf pertama dengan lebih jelas). Juga, seperti yang Anda lihat, saya secara eksplisit menyatakan bahwa semua informasi tentang file (kecuali namanya) ada di inode, dan bukan di file direktori.
Norman Gray
@NormanGray: Bahkan saat Anda membela diri, Anda menembak diri sendiri. Anda berkata, "Semua konten aktual file dalam sistem file ada di inode ...." Itu salah.  Properti / atribut file (misalnya, pemilik, izin, waktu modifikasi, dll.) Disimpan dalam inode. The isi dari file biasa disimpan dalam blok data. Jika Anda tidak ingin terjebak dalam implementasi inode, maka jangan, tapi tolong jangan membuat penyederhanaan yang menyesatkan juga.
G-Man Mengatakan 'Reinstate Monica'