Skip to content

Commit 763ac0f

Browse files
mansi153Mansi Pandeypassaro
authored
Update Mountpoint's semantics to enable opening a new file handle on an inode if all the existing open handles have been flushed (#1704)
Update Mountpoint's semantics to enable opening a new file handle on an inode if **all** the existing open handles have been flushed. This allows for the filesystem to not depend on a `release` request to complete pending (delayed) upload and cleanup the internal state of the inode within Mountpoint; alleviating situations where an `open` request made immediately after a close(`flush`) request leads to a race condition between the `release` following the close and the new `open`, which is sometimes an issue when the upload to S3 has been delayed until `release`. ### Does this change impact existing behavior? The semantics continue to allow **only one writer OR one/many readers** concurrently active for a file; however, now a new handle can be opened which can override the current active handles (despite not being officially released) if all the active handles are marked "flushed". As part of opening the new handle, Mountpoint will also attempt uploading any pending data written for the previous file handle. All the requests to the overridden handle(s) will then start to fail or be no-op. Multiple concurrent writers or concurrent readers and writers are still not allowed. A handle is marked "flushed" when a close/`flush` is called on a file descriptor mapped to that handle. A following `read`/`write` request will revert that flushed state and signify that the handle is actively in use and can not be overridden. We maintain this information at the individual handle level and also in an inode-locked map of handles. Breaking changes: - Requests made to a duplicate file descriptor for a flushed file handle will start to fail (for e.g. a `read`/`write` would fail with `EBADF: file handle has been invalidated by a newer handle opened`) or be no-op (for e.g. `flush`, `release`) if a new `open` has overridden the flushed handle(s). - A race condition can occur between a `read`/`write` request for a duplicate file descriptor on an existing (flushed) handle and multiple concurrent `open` requests, and any of them might succeed due to parallel processing of FUSE requests within Mountpoint. However, only one of them will ever succeed and there cannot be two concurrent writers or reader+writer for the inode at any point in time. - An `open` request for an inode might fail if the pending upload to S3 fails. This is independent of whether the file has been truncated in the second `open`. ### Does this change need a changelog entry? Does it require a version change? Yes, it needs a changelog entry and update to the semantics.md. Yes it also requires a version change. --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and I agree to the terms of the [Developer Certificate of Origin (DCO)](https://developercertificate.org/). --------- Signed-off-by: Mansi Pandey <mansipnd@amazon.co.uk> Signed-off-by: Alessandro Passaro <alexpax@amazon.co.uk> Co-authored-by: Mansi Pandey <mansipnd@amazon.com> Co-authored-by: Alessandro Passaro <alexpax@amazon.co.uk>
1 parent 23bffa1 commit 763ac0f

22 files changed

Lines changed: 1805 additions & 491 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mountpoint-s3-client/src/object_client.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,12 @@ impl ProvideErrorMetadata for RenameObjectError {
210210
}
211211
}
212212

213+
impl ProvideErrorMetadata for PutObjectError {
214+
fn meta(&self) -> ClientErrorMetadata {
215+
Default::default()
216+
}
217+
}
218+
213219
/// Shorthand type for the result of an object client request
214220
pub type ObjectClientResult<T, S, C> = Result<T, ObjectClientError<S, C>>;
215221

mountpoint-s3-fs/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## Unreleased (v0.8.5)
1+
## Unreleased (v0.9.0 (January 06, 2025))
22

3+
* Update Mountpoint's semantics to enable opening a new file handle on an inode if all the existing open handles have been flushed. ([#1704](https://github.com/awslabs/mountpoint-s3/pull/1704))
34
* Upgrade cargo dependencies.
45

56
## v0.8.4 (December 22, 2025)

mountpoint-s3-fs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "mountpoint-s3-fs"
33
# See `/doc/PUBLISHING_CRATES.md` to read how to publish new versions.
4-
version = "0.8.5"
4+
version = "0.9.0"
55
edition = "2024"
66
license = "Apache-2.0"
77
repository = "https://github.com/awslabs/mountpoint-s3"

mountpoint-s3-fs/src/fs.rs

Lines changed: 343 additions & 104 deletions
Large diffs are not rendered by default.

mountpoint-s3-fs/src/fs/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ impl ToErrno for InodeError {
188188
InodeError::OperationNotSupportedOnSyntheticInode { .. } => libc::EIO,
189189
InodeError::OutOfOrderReadDir { .. } => libc::EBADF,
190190
InodeError::NoSuchDirHandle { .. } => libc::EINVAL,
191+
InodeError::FlexibleRetrievalObjectNotAccessible(_) => libc::EACCES,
191192
}
192193
}
193194
}

mountpoint-s3-fs/src/fs/flags.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ libc_flags! {
8585
}
8686
}
8787

88+
impl OpenFlags {
89+
#[cfg(not(target_os = "linux"))]
90+
pub fn direct_io(&self) -> bool {
91+
false
92+
}
93+
94+
#[cfg(target_os = "linux")]
95+
pub fn direct_io(&self) -> bool {
96+
self.contains(OpenFlags::O_DIRECT)
97+
}
98+
}
99+
88100
/// Flags used in [rename](super::S3Filesystem::rename).
89101
#[derive(Clone, Copy, PartialEq, Eq)]
90102
pub struct RenameFlags(u32);

0 commit comments

Comments
 (0)