Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ObjectStore.LocalFileSystem.put_opts for blobfuse #5094

Merged
merged 5 commits into from
Nov 27, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 32 additions & 24 deletions object_store/src/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,28 +338,41 @@ impl ObjectStore for LocalFileSystem {
maybe_spawn_blocking(move || {
let (mut file, suffix) = new_staged_upload(&path)?;
let staging_path = staged_upload_path(&path, &suffix);
let mut e_tag = None;

let err = match file.write_all(&bytes) {
Ok(_) => match opts.mode {
PutMode::Overwrite => match std::fs::rename(&staging_path, &path) {
Ok(_) => None,
Err(source) => Some(Error::UnableToRenameFile { source }),
},
PutMode::Create => match std::fs::hard_link(&staging_path, &path) {
Ok(_) => {
let _ = std::fs::remove_file(&staging_path); // Attempt to cleanup
None
Ok(_) => {
let metadata = file.metadata().map_err(|e| Error::Metadata {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work with blobfuse, the original description suggested the file had to be closed before the metadata could be retrieved?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it works with blobfuse. Because when it sends stat system call, blobfuse will look for local file cache firstly and it will success.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you confirm if this works

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have tested it in local and it worked.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @tustvold, you can see https://github.com/Azure/azure-storage-fuse/blob/master/blobfuse/utilities.cpp#L136
image

For metadate request, blobfuse will check local cache firstly and skip remote request. It's different with rename requests.

source: e.into(),
path: path.to_string_lossy().to_string(),
})?;
e_tag = Some(get_etag(&metadata));
match opts.mode {
PutMode::Overwrite => {
// For some fuse types of file systems, the file must be closed first
// to trigger the upload operation, and then renamed, such as Blobfuse
std::mem::drop(file);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we get a comment explaining the purpose of this to future readers, otherwise it is likely to be accidentally removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, thanks

match std::fs::rename(&staging_path, &path) {
Ok(_) => None,
Err(source) => Some(Error::UnableToRenameFile { source }),
}
}
Err(source) => match source.kind() {
ErrorKind::AlreadyExists => Some(Error::AlreadyExists {
path: path.to_str().unwrap().to_string(),
source,
}),
_ => Some(Error::UnableToRenameFile { source }),
PutMode::Create => match std::fs::hard_link(&staging_path, &path) {
Ok(_) => {
let _ = std::fs::remove_file(&staging_path); // Attempt to cleanup
None
}
Err(source) => match source.kind() {
ErrorKind::AlreadyExists => Some(Error::AlreadyExists {
path: path.to_str().unwrap().to_string(),
source,
}),
_ => Some(Error::UnableToRenameFile { source }),
},
},
},
PutMode::Update(_) => unreachable!(),
},
PutMode::Update(_) => unreachable!(),
}
}
Err(source) => Some(Error::UnableToCopyDataToFile { source }),
};

Expand All @@ -368,13 +381,8 @@ impl ObjectStore for LocalFileSystem {
return Err(err.into());
}

let metadata = file.metadata().map_err(|e| Error::Metadata {
source: e.into(),
path: path.to_string_lossy().to_string(),
})?;

Ok(PutResult {
e_tag: Some(get_etag(&metadata)),
e_tag,
version: None,
})
})
Expand Down
Loading