From 926a414b90b4a2912bd03488e9f088dd6bca4199 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Wed, 8 Apr 2020 11:23:02 +0200 Subject: [PATCH] vhost_user_fs: Add support for MAX_PAGES Add support for MAX_PAGES, corresonding to FUSE_MAX_PAGES introduced in FUSE 7.28. This allows us to negotiate with the kernel the maximum number of pages that we support to transfer in a single request. Signed-off-by: Sergio Lopez --- vhost_user_fs/src/fuse.rs | 15 ++++++++++++++- vhost_user_fs/src/server.rs | 8 +++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/vhost_user_fs/src/fuse.rs b/vhost_user_fs/src/fuse.rs index 98401b073..9e86fc325 100644 --- a/vhost_user_fs/src/fuse.rs +++ b/vhost_user_fs/src/fuse.rs @@ -137,6 +137,9 @@ const POSIX_ACL: u32 = 1_048_576; /// Reading the device after abort returns ECONNABORTED. const ABORT_ERROR: u32 = 2_097_152; +/// Init_out.max_pages contains the max number of req pages. +const MAX_PAGES: u32 = 4_194_304; + bitflags! { /// A bitfield passed in as a parameter to and returned from the `init` method of the /// `FileSystem` trait. @@ -309,6 +312,14 @@ bitflags! { /// /// This feature is not currently supported. const ABORT_ERROR = ABORT_ERROR; + + /// Indicates support for negotiating the maximum number of pages supported. + /// + /// If this feature is enabled, we can tell the kernel the maximum number of pages that we + /// support to transfer in a single request. + /// + /// This feature is enabled by default if supported by the kernel. + const MAX_PAGES = MAX_PAGES; } } @@ -848,7 +859,9 @@ pub struct InitOut { pub congestion_threshold: u16, pub max_write: u32, pub time_gran: u32, - pub unused: [u32; 9], + pub max_pages: u16, + pub padding: u16, + pub unused: [u32; 8], } unsafe impl ByteValued for InitOut {} diff --git a/vhost_user_fs/src/server.rs b/vhost_user_fs/src/server.rs index 4c2242140..2ac8f8f30 100644 --- a/vhost_user_fs/src/server.rs +++ b/vhost_user_fs/src/server.rs @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +use std::convert::TryInto; use std::ffi::CStr; use std::fs::File; use std::io::{self, Read, Write}; @@ -903,10 +904,14 @@ impl Server { | FsOptions::HANDLE_KILLPRIV | FsOptions::ASYNC_DIO | FsOptions::HAS_IOCTL_DIR - | FsOptions::ATOMIC_O_TRUNC; + | FsOptions::ATOMIC_O_TRUNC + | FsOptions::MAX_PAGES; let capable = FsOptions::from_bits_truncate(flags); + let page_size: u32 = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; + let max_pages = ((MAX_BUFFER_SIZE - 1) / page_size) + 1; + match self.fs.init(capable) { Ok(want) => { let enabled = capable & (want | supported); @@ -920,6 +925,7 @@ impl Server { congestion_threshold: (::std::u16::MAX / 4) * 3, max_write: MAX_BUFFER_SIZE, time_gran: 1, // nanoseconds + max_pages: max_pages.try_into().unwrap(), ..Default::default() };