- /* Disable nonlocked read DIO to avoid the end less truncate */- btrfs_inode_block_unlocked_dio(BTRFS_I(inode));+ /*+ * This code is very subtle. It is essentially a lock of its+ * own type. BTRFS allows multiple DIO readers to race with+ * writers so long as they don't read beyond EOF of an inode.+ * However, if we have a pending truncate we'd like to signal+ * DIO readers they should fall back to DIO_LOCKING semantics.+ * This ensures that multiple aggressive DIO readers cannot+ * starve the truncating thread.+ *+ * This semantics is achieved by the use of the below flag. If+ * new readers come after the flag has been cleared then the+ * state is still consistent, since the RELEASE semantics of+ * clear_bit_unlock ensure the truncate inode size will be+ * visible and DIO readers will bail out.+ *+ * The implied memory barrier by inode_dio_wait is paired with+ * smp_mb__before_atomic in btrfs_direct_IO.+ */+ set_bit(BTRFS_INODE_READDIO_NEED_LOCK, &inode->runtime_flags); inode_dio_wait(inode);- btrfs_inode_resume_unlocked_dio(BTRFS_I(inode));+ clear_bit_unlock(BTRFS_INODE_READDIO_NEED_LOCK,+ &inode->runtime_flags);