list object include deleted support (#882)

Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
weisd
2025-11-18 21:51:10 +08:00
committed by GitHub
parent 6da5766ea2
commit 55d44622ed
10 changed files with 31 additions and 5 deletions
+1 -1
View File
@@ -498,7 +498,7 @@ impl HealStorageAPI for ECStoreHealStorage {
match self match self
.ecstore .ecstore
.clone() .clone()
.list_objects_v2(bucket, prefix, None, None, 1000, false, None) .list_objects_v2(bucket, prefix, None, None, 1000, false, None, false)
.await .await
{ {
Ok(list_info) => { Ok(list_info) => {
+1
View File
@@ -1005,6 +1005,7 @@ impl Scanner {
100, // max_keys - small limit for performance 100, // max_keys - small limit for performance
false, // fetch_owner false, // fetch_owner
None, // start_after None, // start_after
false, // incl_deleted
) )
.await .await
{ {
+1
View File
@@ -277,6 +277,7 @@ pub async fn compute_bucket_usage(store: Arc<ECStore>, bucket_name: &str) -> Res
1000, // max_keys 1000, // max_keys
false, // fetch_owner false, // fetch_owner
None, // start_after None, // start_after
false, // incl_deleted
) )
.await?; .await?;
+1
View File
@@ -4483,6 +4483,7 @@ impl StorageAPI for SetDisks {
_max_keys: i32, _max_keys: i32,
_fetch_owner: bool, _fetch_owner: bool,
_start_after: Option<String>, _start_after: Option<String>,
_incl_deleted: bool,
) -> Result<ListObjectsV2Info> { ) -> Result<ListObjectsV2Info> {
unimplemented!() unimplemented!()
} }
+1
View File
@@ -440,6 +440,7 @@ impl StorageAPI for Sets {
_max_keys: i32, _max_keys: i32,
_fetch_owner: bool, _fetch_owner: bool,
_start_after: Option<String>, _start_after: Option<String>,
_incl_deleted: bool,
) -> Result<ListObjectsV2Info> { ) -> Result<ListObjectsV2Info> {
unimplemented!() unimplemented!()
} }
+12 -2
View File
@@ -1338,9 +1338,19 @@ impl StorageAPI for ECStore {
max_keys: i32, max_keys: i32,
fetch_owner: bool, fetch_owner: bool,
start_after: Option<String>, start_after: Option<String>,
incl_deleted: bool,
) -> Result<ListObjectsV2Info> { ) -> Result<ListObjectsV2Info> {
self.inner_list_objects_v2(bucket, prefix, continuation_token, delimiter, max_keys, fetch_owner, start_after) self.inner_list_objects_v2(
.await bucket,
prefix,
continuation_token,
delimiter,
max_keys,
fetch_owner,
start_after,
incl_deleted,
)
.await
} }
#[instrument(skip(self))] #[instrument(skip(self))]
+1
View File
@@ -1224,6 +1224,7 @@ pub trait StorageAPI: ObjectIO + Debug {
max_keys: i32, max_keys: i32,
fetch_owner: bool, fetch_owner: bool,
start_after: Option<String>, start_after: Option<String>,
incl_deleted: bool,
) -> Result<ListObjectsV2Info>; ) -> Result<ListObjectsV2Info>;
// ListObjectVersions TODO: FIXME: // ListObjectVersions TODO: FIXME:
async fn list_object_versions( async fn list_object_versions(
+6 -2
View File
@@ -225,6 +225,7 @@ impl ECStore {
max_keys: i32, max_keys: i32,
_fetch_owner: bool, _fetch_owner: bool,
start_after: Option<String>, start_after: Option<String>,
incl_deleted: bool,
) -> Result<ListObjectsV2Info> { ) -> Result<ListObjectsV2Info> {
let marker = { let marker = {
if continuation_token.is_none() { if continuation_token.is_none() {
@@ -234,7 +235,9 @@ impl ECStore {
} }
}; };
let loi = self.list_objects_generic(bucket, prefix, marker, delimiter, max_keys).await?; let loi = self
.list_objects_generic(bucket, prefix, marker, delimiter, max_keys, incl_deleted)
.await?;
Ok(ListObjectsV2Info { Ok(ListObjectsV2Info {
is_truncated: loi.is_truncated, is_truncated: loi.is_truncated,
continuation_token, continuation_token,
@@ -251,6 +254,7 @@ impl ECStore {
marker: Option<String>, marker: Option<String>,
delimiter: Option<String>, delimiter: Option<String>,
max_keys: i32, max_keys: i32,
incl_deleted: bool,
) -> Result<ListObjectsInfo> { ) -> Result<ListObjectsInfo> {
let opts = ListPathOptions { let opts = ListPathOptions {
bucket: bucket.to_owned(), bucket: bucket.to_owned(),
@@ -258,7 +262,7 @@ impl ECStore {
separator: delimiter.clone(), separator: delimiter.clone(),
limit: max_keys_plus_one(max_keys, marker.is_some()), limit: max_keys_plus_one(max_keys, marker.is_some()),
marker, marker,
incl_deleted: false, incl_deleted,
ask_disks: "strict".to_owned(), //TODO: from config ask_disks: "strict".to_owned(), //TODO: from config
..Default::default() ..Default::default()
}; };
+1
View File
@@ -163,6 +163,7 @@ pub const AMZ_TAGGING_DIRECTIVE: &str = "X-Amz-Tagging-Directive";
pub const RUSTFS_DATA_MOVE: &str = "X-Rustfs-Internal-data-mov"; pub const RUSTFS_DATA_MOVE: &str = "X-Rustfs-Internal-data-mov";
pub const RUSTFS_FORCE_DELETE: &str = "X-Rustfs-Force-Delete"; pub const RUSTFS_FORCE_DELETE: &str = "X-Rustfs-Force-Delete";
pub const RUSTFS_INCLUDE_DELETED: &str = "X-Rustfs-Include-Deleted";
pub const RUSTFS_REPLICATION_RESET_STATUS: &str = "X-Rustfs-Replication-Reset-Status"; pub const RUSTFS_REPLICATION_RESET_STATUS: &str = "X-Rustfs-Replication-Reset-Status";
pub const RUSTFS_REPLICATION_AUTUAL_OBJECT_SIZE: &str = "X-Rustfs-Replication-Actual-Object-Size"; pub const RUSTFS_REPLICATION_AUTUAL_OBJECT_SIZE: &str = "X-Rustfs-Replication-Actual-Object-Size";
+6
View File
@@ -2225,6 +2225,11 @@ impl S3 for FS {
let store = get_validated_store(&bucket).await?; let store = get_validated_store(&bucket).await?;
let incl_deleted = req
.headers
.get(rustfs_utils::http::headers::RUSTFS_INCLUDE_DELETED)
.is_some_and(|v| v.to_str().unwrap_or_default() == "true");
let object_infos = store let object_infos = store
.list_objects_v2( .list_objects_v2(
&bucket, &bucket,
@@ -2234,6 +2239,7 @@ impl S3 for FS {
max_keys, max_keys,
fetch_owner.unwrap_or_default(), fetch_owner.unwrap_or_default(),
start_after, start_after,
incl_deleted,
) )
.await .await
.map_err(ApiError::from)?; .map_err(ApiError::from)?;