Skip to content

Commit 07a7878

Browse files
committed
NSFS | Fix delete last object deletes directory object if its size is 0
Signed-off-by: Romy <[email protected]>
1 parent cb95c81 commit 07a7878

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

src/sdk/namespace_fs.js

+21-4
Original file line numberDiff line numberDiff line change
@@ -2575,10 +2575,19 @@ class NamespaceFS {
25752575
}
25762576
}
25772577

2578+
/**
2579+
* _delete_path_dirs deletes all the paths in the hierarchy that are empty after a successful delete
2580+
* if dir is not empty it will stop at the first non empty dir
2581+
* if dir is also a directory object (disabled mode optimization - CONTENT_DIR xattr is on the directory) we stop the loop
2582+
* @param {String} file_path
2583+
* @param {nb.NativeFSContext} fs_context
2584+
*/
25782585
async _delete_path_dirs(file_path, fs_context) {
25792586
try {
25802587
let dir = path.dirname(file_path);
25812588
while (dir !== this.bucket_path) {
2589+
const dir_stat = await nb_native().fs.stat(fs_context, dir);
2590+
if (dir_stat.xattr && dir_stat.xattr[XATTR_DIR_CONTENT]) break;
25822591
await nb_native().fs.rmdir(fs_context, dir);
25832592
dir = path.dirname(dir);
25842593
}
@@ -3016,10 +3025,18 @@ class NamespaceFS {
30163025
return res;
30173026
}
30183027

3019-
// delete version_id -
3020-
// 1. get version info, if it's empty - return
3021-
// 2. unlink key
3022-
// 3. if version is latest version - promote second latest -> latest
3028+
/**
3029+
* delete version_id does the following -
3030+
* 1. get version info, if it's empty - return
3031+
* 2. unlink key
3032+
* 3. if version is latest version - promote second latest -> latest
3033+
* 4. if it's the latest version - delete the directory hirerachy of the key if it's empty
3034+
* if it's a past version - delete .versions/ and the directory hirerachy if it's empty
3035+
* @param {nb.NativeFSContext} fs_context
3036+
* @param {String} file_path
3037+
* @param {Object} params
3038+
* @returns {Promise<{deleted_delete_marker?: string, version_id?: string}>}
3039+
*/
30233040
async _delete_version_id(fs_context, file_path, params) {
30243041
// TODO optimization - GPFS link overrides, no need to unlink before promoting, but if there is nothing to promote we should unlink
30253042
const del_obj_version_info = await this._delete_single_object_versioned(fs_context, params.key, params.version_id);

src/test/unit_tests/test_namespace_fs.js

+16
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,22 @@ mocha.describe('namespace_fs folders tests', function() {
11771177

11781178
});
11791179

1180+
mocha.it('delete inner object in directory object size 0 - no .folder file', async function() {
1181+
const inner_key = '/inner_obj';
1182+
const key = upload_key_3 + inner_key;
1183+
const datar = crypto.randomBytes(100);
1184+
const source = buffer_utils.buffer_to_read_stream(datar);
1185+
await upload_object(ns_tmp, upload_bkt, key, dummy_object_sdk, source);
1186+
const p1 = path.join(ns_tmp_bucket_path, upload_key_3);
1187+
const p2 = path.join(ns_tmp_bucket_path, key);
1188+
const full_xattr1 = await get_xattr(p1);
1189+
assert.deepEqual(full_xattr1, { ...user_md_and_dir_content_xattr, [XATTR_DIR_CONTENT]: obj_sizes_map[upload_key_3] });
1190+
await ns_tmp.delete_object({ bucket: upload_bkt, key: key }, dummy_object_sdk);
1191+
await fs_utils.file_must_not_exist(path.join(p1, config.NSFS_FOLDER_OBJECT_NAME));
1192+
await fs_utils.file_must_exist(p1);
1193+
await fs_utils.file_must_not_exist(p2);
1194+
});
1195+
11801196
mocha.it('delete object content 0 - no .folder file', async function() {
11811197
const p1 = path.join(ns_tmp_bucket_path, upload_key_3);
11821198
const full_xattr1 = await get_xattr(p1);

0 commit comments

Comments
 (0)