Filesystems

inode->i_rwsem 和 i_flctx 有什麼不同?

  • December 6, 2021

當我在呼叫時跟踪函式圖時write(),我發現在函式內它在開始時通過呼叫ext4_file_write_iter()鎖定了。之後呼叫將數據寫入文件。並解鎖到底。inode->i_rwsem``inode_lock(inode)``__generic_file_write_iter()``inode

那麼它是否inode->i_rwsem用於保護對同一文件的並發寫入?

但是我編寫了一個程序,它同時將數據寫入文件的同一區域 ( pwrite(fd,buf,SIZE,0)),結果顯示寫入未序列化。而且我發現它必須使用flock/fcntl來序列化在inode->i_flctx.

我想問的是inode->i_rwsem.

inode->i_rwsem之間有什麼不同?inode->i_flctx``inode->i_lock

謝謝。

inode->i_rwsem由核心在內部使用,以確保核心本身不會同時讀取或寫入文件,以避免任何損壞或競爭條件。它不影響使用者空間;您仍然可以同時打開文件以供多個程序讀取/寫入。但是,如果多個程序嘗試同時讀取/寫入文件,核心實際上會在幕後連續執行。

在您的情況下,如果有兩個程序嘗試使用 寫入同一區域pwrite(fd,buf,SIZE,0),而沒有內部鎖定機制(例如用於什麼i_rwsem),核心可能會開始從第一個程序寫入一些數據,同時time 開始從第二個程序寫入數據,而第一個程序的寫操作沒有完成。它會影響整個文件系統的完整性,甚至可能導致核心由於競態條件而崩潰。

核心中的內部鎖定防止了這些情況。第一個程序的第一次寫入將完成,然後才會執行第二次寫入(如果它們都寫入文件中完全相同的區域,則可能會覆蓋第一個程序的“寫入”)。

inode->i_flctx,正如您已經發現的那樣,當程序本身想要限制可以同時打開文件的程序數時,它由來自使用者空間的flock/呼叫控制。fcntl例如,一個程序可以鎖定文件以進行寫入,如果另一個程序想在另一個釋放文件之前鎖定同一個文件,它將被拒絕或阻塞。

讓我們以兩個程序寫入同一個文件並執行不同的寫入為例。每個程序都可以覆蓋其他程序寫入的數據。為了避免在使用者空間中出現這種情況,應用程序本身可以使用flock/fcntl來防止兩個程序打開同一個文件。

這是另一個例子:

  • 一個程序寫入文件,第二個程序從同一個文件中讀取。
  • 第二個程序可以讀取部分數據,因為第一個程序尚未完成寫入。

在這種情況下,為了防止這種情況:

  1. 第一個程序必須獲取文件鎖以防止其他程序在完成寫入之前打開它。
  2. 第二個程序將嘗試獲取同一個文件的鎖定,並且將被阻止(或失敗,取決於它如何嘗試鎖定文件),因為它已經被另一個程序鎖定。
  3. 第一個程序完成寫入,釋放鎖(再次,通過呼叫提到的系統呼叫之一在使用者空間中顯式)
  4. 只有這樣,第二個程序才能鎖定文件以供讀取。
  5. 當第二個程序正在讀取文件時,其他試圖獲取文件鎖定的程序將再次被阻塞,直到:
  6. 閱讀過程完成閱讀。

因此,使用flock/fcntl您可以在應用程序的原始碼中以程式方式處理這些情況,並且核心使用i_flctx來了解某個程序是否獲得了對該文件的鎖定,並防止其他程序獲得另一個鎖定,直到第一個程序釋放它。

inode->i_lock,就像inode->i_rwsem,僅由核心使用,以在處理核心中的 inode 狀態時保護核心免受競爭條件的影響。i_rwsem用於保護寫入,i_lock用於保護inode狀態的變化。

換句話說,除非您是核心開發人員,否則您不必擔心inode->i_lockor inode->i_rwsem,它們只是核心對 inode 的實現機制的inode->i_flctx一部分,以及哪個是核心從使用者空間鎖定文件的內部實現機制的一部分.

引用自:https://unix.stackexchange.com/questions/680200