Skip to content

Commit 6c4c726

Browse files
eryugeybergwolf
authored andcommitted
passthroughfs: add config to control count mntid in altkey or not
In commit 095d821 ("passthrough: add mnt id as inode alt key") we added mntid as part of inode alt key, and use name_to_handle_at(2) to get mntid. And recent perf tests show that name_to_handle_at(2) is kind of expensive in lookup intensive workloads. So add a knob to control it, and default to false. Signed-off-by: Eryu Guan <[email protected]>
1 parent 1b528af commit 6c4c726

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

src/passthrough/async_io.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,21 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
114114
115115
let st = match &file_or_handle {
116116
FileOrHandle::File(f) => {
117-
// TODO: use statx(2) to query mntid when 5.8 kernel or later are widely used.
117+
// Count mount ID as part of alt key if use_mntid is true. Note that using
118+
// name_to_handle_at() to get mntid is kind of expensive in Lookup intensive
119+
// workloads, e.g. when cache is none and accessing lots of files.
118120
//
119121
// Some filesystems don't support file handle, for example overlayfs mounted
120122
// without index feature, if so just use mntid 0 in that case.
121-
let mnt_id = match FileHandle::from_name_at(dir_fd, name) {
122-
Ok(h) => h.mnt_id,
123-
Err(_) => 0,
123+
//
124+
// TODO: use statx(2) to query mntid when 5.8 kernel or later are widely used.
125+
let mnt_id = if self.cfg.enable_mntid {
126+
match FileHandle::from_name_at(dir_fd, name) {
127+
Ok(h) => h.mnt_id,
128+
Err(_) => 0,
129+
}
130+
} else {
131+
0
124132
};
125133
InodeStat {
126134
stat: self.async_stat(ctx, f, None).await?,

src/passthrough/mod.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,15 @@ pub struct Config {
464464
/// share memory file to attack the host.
465465
pub seal_size: bool,
466466

467+
/// Whether count mount ID or not when comparing two inodes. By default we think two inodes
468+
/// are same if their inode number and st_dev are the same. When `enable_mntid` is set as
469+
/// 'true', inode's mount ID will be taken into account as well. For example, bindmount the
470+
/// same file into virtiofs' source dir, the two bindmounted files will be identified as two
471+
/// different inodes when this option is true, so the don't share pagecache.
472+
///
473+
/// The default value for this option is `false`.
474+
pub enable_mntid: bool,
475+
467476
/// What size file supports dax
468477
/// * If dax_file_size == None, DAX will disable to all files.
469478
/// * If dax_file_size == 0, DAX will enable all files.
@@ -488,6 +497,7 @@ impl Default for Config {
488497
inode_file_handles: false,
489498
no_readdir: false,
490499
seal_size: false,
500+
enable_mntid: false,
491501
dax_file_size: None,
492502
}
493503
}
@@ -591,6 +601,7 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
591601

592602
let (file_or_handle, st, ids_altkey, handle_altkey) = Self::open_file_or_handle(
593603
self.cfg.inode_file_handles,
604+
self.cfg.enable_mntid,
594605
libc::AT_FDCWD,
595606
&root,
596607
&self.mount_fds,
@@ -775,6 +786,7 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
775786
/// Create a File or File Handle for `name` under directory `dir_fd` to support `lookup()`.
776787
fn open_file_or_handle<F>(
777788
use_handle: bool,
789+
use_mntid: bool,
778790
dir_fd: RawFd,
779791
name: &CStr,
780792
mount_fds: &MountFds,
@@ -805,13 +817,21 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
805817

806818
let inode_stat = match &file_or_handle {
807819
FileOrHandle::File(f) => {
808-
// TODO: use statx(2) to query mntid when 5.8 kernel or later are widely used.
820+
// Count mount ID as part of alt key if use_mntid is true. Note that using
821+
// name_to_handle_at() to get mntid is kind of expensive in Lookup intensive
822+
// workloads, e.g. when cache is none and accessing lots of files.
809823
//
810824
// Some filesystems don't support file handle, for example overlayfs mounted
811825
// without index feature, if so just use mntid 0 in that case.
812-
let mnt_id = match FileHandle::from_name_at(dir_fd, name) {
813-
Ok(h) => h.mnt_id,
814-
Err(_) => 0,
826+
//
827+
// TODO: use statx(2) to query mntid when 5.8 kernel or later are widely used.
828+
let mnt_id = if use_mntid {
829+
match FileHandle::from_name_at(dir_fd, name) {
830+
Ok(h) => h.mnt_id,
831+
Err(_) => 0,
832+
}
833+
} else {
834+
0
815835
};
816836
InodeStat {
817837
stat: Self::stat(f, None)?,
@@ -849,6 +869,7 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
849869
let dir_file = dir.get_file(&self.mount_fds)?;
850870
let (file_or_handle, st, ids_altkey, handle_altkey) = Self::open_file_or_handle(
851871
self.cfg.inode_file_handles,
872+
self.cfg.enable_mntid,
852873
dir_file.as_raw_fd(),
853874
name,
854875
&self.mount_fds,

0 commit comments

Comments
 (0)