GNU/Linux >> Belajar Linux >  >> Linux

Linux – Bagaimana Linux Menetapkan Nomor Inode Pada Sistem File Tidak Berdasarkan Inode?

Ini adalah output dari ls -li perintah pada sistem file VFAT.

% ls -li
合計 736
1207 drwxr-xr-x 3 root root  16384  3月 10 10:42 efi
1208 -rwxr-xr-x 1 root root 721720  3月 22 14:15 kernel.bin

1207 dan 1208 adalah nomor inode direktori dan file. Namun, sistem file VFAT tidak memiliki konsep inode.

Bagaimana cara Linux menetapkan nomor inode untuk file pada sistem file yang tidak memiliki gagasan inode?

Jawaban yang Diterima:

tl; dr:Untuk sistem file virtual, volatil, atau inode-agnostik, nomor inode biasanya dihasilkan dari penghitung 32-bit yang meningkat secara monoton ketika inode dibuat. Sisa inode (mis. izin) dibangun dari data yang setara di sistem file yang mendasarinya, atau diganti dengan nilai yang ditetapkan pada waktu pemasangan (mis. {uid,gid}= ) jika tidak ada konsep seperti itu.

Untuk menjawab pertanyaan dalam judul (yaitu secara abstrak, bagaimana Linux mengalokasikan nomor inode untuk sistem file yang tidak memiliki konsep inode), itu tergantung pada sistem file. Untuk beberapa filesystem virtual atau inodeless, nomor inode diambil pada waktu instantiasi dari get_next_ino kolam. Ini memiliki sejumlah masalah, meskipun:

  1. get_next_ino() menggunakan nomor inode 32-bit bahkan pada kernel 64-bit, karena penanganan lama untuk wilayah pengguna 32-bit tanpa _FILE_OFFSET_BITS=64;
  2. get_next_ino() hanyalah penghitung peningkatan global yang digunakan oleh banyak sistem file, sehingga risiko luapan meningkat lebih jauh.

Masalah seperti ini adalah salah satu alasan saya memindahkan tmpfs dari inode yang didukung get_next_ino tahun lalu.

Untuk alasan ini, tmpfs khususnya merupakan pengecualian dari sebagian besar format sistem file yang mudah menguap atau "tanpa kode". Soket, pipa, ramf, dan sejenisnya masih menggunakan get_next_ino kumpulan mulai 5.11.

Adapun pertanyaan spesifik Anda tentang sistem file FAT:fs/fat/inode.c adalah tempat nomor inode dialokasikan untuk sistem file FAT. Jika kita melihat di sana, kita melihat fat_build_inode (sumber):

struct inode *fat_build_inode(struct super_block *sb,
                              struct msdos_dir_entry *de, loff_t i_pos)
{
        struct inode *inode;
        int err;

        fat_lock_build_inode(MSDOS_SB(sb));
        inode = fat_iget(sb, i_pos);
        if (inode)
                goto out;
        inode = new_inode(sb);
        if (!inode) {
                inode = ERR_PTR(-ENOMEM);
                goto out;
        }
        inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
        inode_set_iversion(inode, 1);
        err = fat_fill_inode(inode, de);
        if (err) {
                iput(inode);
                inode = ERR_PTR(err);
                goto out;
        }
        fat_attach(inode, i_pos);
        insert_inode_hash(inode);
out:
        fat_unlock_build_inode(MSDOS_SB(sb));
        return inode;
}

Apa yang pada dasarnya dikatakan adalah ini:

  1. Ambil kunci pembuatan inode FAT untuk superblok ini.
  2. Periksa apakah inode sudah ada pada posisi ini di superblok. Jika demikian, buka kunci dan kembalikan inode itu.
  3. Jika tidak, buat inode baru.
  4. Dapatkan nomor inode dari iunique(sb, MSDOS_ROOT_INO) (lebih lanjut tentang itu sebentar lagi).
  5. Isi sisa inode dari struktur data FAT yang setara.

inode->i_ino = iunique(sb, MSDOS_ROOT_INO); adalah di mana nomor inode diatur di sini. iunique (sumber) adalah fungsi agnostik fs yang menyediakan nomor inode unik untuk superblok tertentu. Ia melakukannya dengan menggunakan superblok + tabel hash berbasis inode, dengan penghitung yang meningkat secara monoton:

ino_t iunique(struct super_block *sb, ino_t max_reserved)
{
        static DEFINE_SPINLOCK(iunique_lock);
        static unsigned int counter;
        ino_t res;

        rcu_read_lock();
        spin_lock(&iunique_lock);
        do {
                if (counter <= max_reserved)
                        counter = max_reserved + 1;
                res = counter++;
        } while (!test_inode_iunique(sb, res)); /* nb: this checks the hash table */
        spin_unlock(&iunique_lock);
        rcu_read_unlock();

        return res;
}

Dalam hal itu, ini sangat mirip dengan get_next_ino yang disebutkan sebelumnya :hanya per-superblok alih-alih menjadi global (seperti untuk pipa, soket, atau sejenisnya), dan dengan beberapa perlindungan berbasis tabel hash yang belum sempurna terhadap tabrakan. Ia bahkan mewarisi get_next_ino perilaku menggunakan nomor inode 32-bit sebagai metode untuk mencoba dan menghindari EOVERFLOW pada aplikasi lama, jadi kemungkinan akan ada lebih banyak sistem file yang memerlukan perbaikan inode 64-bit (seperti inode64 saya yang disebutkan di atas implementasi untuk tmpfs) di masa mendatang.

Terkait:Linux – Bagaimana cara menambahkan file sebagai sudo?

Jadi kesimpulannya:

  1. Sebagian besar sistem file virtual atau inodeless menggunakan penghitung kenaikan monoton untuk nomor inode.
  2. Penghitung itu tidak stabil bahkan untuk sistem file tanpa kode pada disk*. Ini dapat berubah tanpa perubahan lain pada sistem file saat remount.
  3. Sebagian besar sistem file dalam keadaan ini (kecuali tmpfs dengan inode64 ) masih menggunakan penghitung 32-bit, jadi dengan penggunaan yang berat sangat mungkin penghitung akan meluap dan Anda mungkin berakhir dengan inode duplikat.

* …walaupun, agar adil, menurut kontrak ini berlaku bahkan untuk sistem file yang melakukannya memiliki konsep inode ketika i_generation perubahan — kemungkinan kecil terjadi dalam praktik karena sering kali nomor inode dikaitkan dengan posisi fisiknya, atau serupa.


Linux
  1. Inode dan sistem file Linux

  2. Linux – Bagaimana Kernel Linux Mengetahui Nomor Mayor dan Minor Perangkat?

  3. Linux Setuid Tidak Berfungsi?

  1. Cara Menetapkan Output dari Perintah Linux ke Variabel

  2. Cara Mengakses Sistem File Linux di Windows 10 dan WSL 2

  3. Linux – Bagaimana Cara Memeriksa Informasi Struktur Direktori File Unix/linux?

  1. Linux – Ldd Tidak Menemukan Path, Bagaimana Cara Menambahkannya?

  2. Linux bagaimana cara menyalin tetapi tidak menimpa?

  3. Bagaimana cara kerja debugger di Linux?