@@ -61,6 +61,7 @@ const XATTR_PART_ETAG = XATTR_NOOBAA_INTERNAL_PREFIX + 'part_etag';
61
61
const XATTR_VERSION_ID = XATTR_NOOBAA_INTERNAL_PREFIX + 'version_id' ;
62
62
const XATTR_DELETE_MARKER = XATTR_NOOBAA_INTERNAL_PREFIX + 'delete_marker' ;
63
63
const XATTR_DIR_CONTENT = XATTR_NOOBAA_INTERNAL_PREFIX + 'dir_content' ;
64
+ const XATTR_NON_CURRENT_TIMESTASMP = XATTR_NOOBAA_INTERNAL_PREFIX + 'non_current_timestamp' ;
64
65
const XATTR_TAG = XATTR_NOOBAA_INTERNAL_PREFIX + 'tag.' ;
65
66
const HIDDEN_VERSIONS_PATH = '.versions' ;
66
67
const NULL_VERSION_ID = 'null' ;
@@ -1385,10 +1386,10 @@ class NamespaceFS {
1385
1386
fs_xattr = this . _assign_md5_to_fs_xattr ( digest , fs_xattr ) ;
1386
1387
}
1387
1388
if ( part_upload ) {
1388
- fs_xattr = await this . _assign_part_props_to_fs_xattr ( fs_context , params . size , digest , offset , fs_xattr ) ;
1389
+ fs_xattr = this . _assign_part_props_to_fs_xattr ( params . size , digest , offset , fs_xattr ) ;
1389
1390
}
1390
1391
if ( ! part_upload && ( this . _is_versioning_enabled ( ) || this . _is_versioning_suspended ( ) ) ) {
1391
- fs_xattr = await this . _assign_versions_to_fs_xattr ( stat , fs_xattr , undefined ) ;
1392
+ fs_xattr = this . _assign_versions_to_fs_xattr ( stat , fs_xattr , undefined ) ;
1392
1393
}
1393
1394
if ( ! part_upload && params . storage_class ) {
1394
1395
fs_xattr = Object . assign ( fs_xattr || { } , {
@@ -1540,6 +1541,7 @@ class NamespaceFS {
1540
1541
await native_fs_utils . _make_path_dirs ( versioned_path , fs_context ) ;
1541
1542
await native_fs_utils . safe_move ( fs_context , latest_ver_path , versioned_path , latest_ver_info ,
1542
1543
gpfs_options ?. move_to_versions , bucket_tmp_dir_path ) ;
1544
+ await this . _set_non_current_timestamp_on_past_version ( fs_context , versioned_path ) ;
1543
1545
}
1544
1546
try {
1545
1547
// move new version to latest_ver_path (key path)
@@ -2312,17 +2314,30 @@ class NamespaceFS {
2312
2314
return fs_xattr ;
2313
2315
}
2314
2316
2315
- async _assign_versions_to_fs_xattr ( new_ver_stat , fs_xattr , delete_marker ) {
2317
+ /**
2318
+ * _assign_versions_to_fs_xattr assigns version related xattrs to the file
2319
+ * 1. assign version_id xattr
2320
+ * 2. if delete_marker -
2321
+ * 2.1. assigns delete_marker xattr
2322
+ * 2.2. assigns non_current_timestamp xattr - on the current structure - delete marker is under .versions/
2323
+ * @param {nb.NativeFSStats } new_ver_stat
2324
+ * @param {nb.NativeFSXattr } fs_xattr
2325
+ * @param {Boolean } [delete_marker]
2326
+ * @returns {nb.NativeFSXattr }
2327
+ */
2328
+ _assign_versions_to_fs_xattr ( new_ver_stat , fs_xattr , delete_marker = undefined ) {
2316
2329
fs_xattr = Object . assign ( fs_xattr || { } , {
2317
2330
[ XATTR_VERSION_ID ] : this . _get_version_id_by_mode ( new_ver_stat )
2318
2331
} ) ;
2319
2332
2320
- if ( delete_marker ) fs_xattr [ XATTR_DELETE_MARKER ] = delete_marker ;
2321
-
2333
+ if ( delete_marker ) {
2334
+ fs_xattr [ XATTR_DELETE_MARKER ] = String ( delete_marker ) ;
2335
+ fs_xattr = this . _assign_non_current_timestamp_xattr ( fs_xattr ) ;
2336
+ }
2322
2337
return fs_xattr ;
2323
2338
}
2324
2339
2325
- async _assign_part_props_to_fs_xattr ( fs_context , size , digest , offset , fs_xattr ) {
2340
+ _assign_part_props_to_fs_xattr ( size , digest , offset , fs_xattr ) {
2326
2341
fs_xattr = Object . assign ( fs_xattr || { } , {
2327
2342
[ XATTR_PART_SIZE ] : size ,
2328
2343
[ XATTR_PART_OFFSET ] : offset ,
@@ -2332,6 +2347,39 @@ class NamespaceFS {
2332
2347
return fs_xattr ;
2333
2348
}
2334
2349
2350
+ /**
2351
+ * _assign_non_current_timestamp_xattr assigns non current timestamp xattr to file xattr
2352
+ * @param {nb.NativeFSXattr } fs_xattr
2353
+ * @returns {nb.NativeFSXattr }
2354
+ */
2355
+ _assign_non_current_timestamp_xattr ( fs_xattr = { } ) {
2356
+ fs_xattr = Object . assign ( fs_xattr , {
2357
+ [ XATTR_NON_CURRENT_TIMESTASMP ] : String ( Date . now ( ) )
2358
+ } ) ;
2359
+ return fs_xattr ;
2360
+ }
2361
+
2362
+ /**
2363
+ * _set_non_current_timestamp_on_past_version sets non current timestamp on past version - used as a hint for lifecycle process
2364
+ * @param {nb.NativeFSContext } fs_context
2365
+ * @param {String } versioned_path
2366
+ * @returns {Promise<Void> }
2367
+ */
2368
+ async _set_non_current_timestamp_on_past_version ( fs_context , versioned_path ) {
2369
+ const xattr = this . _assign_non_current_timestamp_xattr ( ) ;
2370
+ await this . set_fs_xattr_op ( fs_context , versioned_path , xattr ) ;
2371
+ }
2372
+
2373
+ /**
2374
+ * _unset_non_current_timestamp_on_past_version unsets non current timestamp on past version - used as a hint for lifecycle process
2375
+ * @param {nb.NativeFSContext } fs_context
2376
+ * @param {String } versioned_path
2377
+ * @returns {Promise<Void> }
2378
+ */
2379
+ async _unset_non_current_timestamp_on_past_version ( fs_context , versioned_path ) {
2380
+ await this . _clear_user_xattr ( fs_context , versioned_path , XATTR_NON_CURRENT_TIMESTASMP ) ;
2381
+ }
2382
+
2335
2383
/**
2336
2384
*
2337
2385
* @param {* } fs_context - fs context object
@@ -3088,6 +3136,8 @@ class NamespaceFS {
3088
3136
const bucket_tmp_dir_path = this . get_bucket_tmpdir_full_path ( ) ;
3089
3137
await native_fs_utils . safe_move_posix ( fs_context , max_past_ver_info . path , latest_ver_path ,
3090
3138
max_past_ver_info , bucket_tmp_dir_path ) ;
3139
+ // TODO - catch error if no such xattr
3140
+ await this . _unset_non_current_timestamp_on_past_version ( fs_context , latest_ver_path ) ;
3091
3141
break ;
3092
3142
} catch ( err ) {
3093
3143
dbg . warn ( `NamespaceFS: _promote_version_to_latest failed error: retries=${ retries } ` , err ) ;
@@ -3144,8 +3194,9 @@ class NamespaceFS {
3144
3194
const bucket_tmp_dir_path = this . get_bucket_tmpdir_full_path ( ) ;
3145
3195
if ( this . _is_versioning_enabled ( ) || suspended_and_latest_is_not_null ) {
3146
3196
await native_fs_utils . _make_path_dirs ( versioned_path , fs_context ) ;
3147
- await native_fs_utils . safe_move_posix ( fs_context , latest_ver_path , versioned_path , latest_ver_info ,
3197
+ await native_fs_utils . safe_move_posix ( fs_context , latest_ver_path , versioned_path , latest_ver_info ,
3148
3198
bucket_tmp_dir_path ) ;
3199
+ await this . _set_non_current_timestamp_on_past_version ( fs_context , versioned_path ) ;
3149
3200
if ( suspended_and_latest_is_not_null ) {
3150
3201
// remove a version (or delete marker) with null version ID from .versions/ (if exists)
3151
3202
await this . _delete_null_version_from_versions_directory ( params . key , fs_context ) ;
@@ -3225,7 +3276,7 @@ class NamespaceFS {
3225
3276
}
3226
3277
const file_path = this . _get_version_path ( params . key , delete_marker_version_id ) ;
3227
3278
3228
- const fs_xattr = await this . _assign_versions_to_fs_xattr ( stat , undefined , true ) ;
3279
+ const fs_xattr = this . _assign_versions_to_fs_xattr ( stat , undefined , true ) ;
3229
3280
if ( fs_xattr ) await upload_params . target_file . replacexattr ( fs_context , fs_xattr ) ;
3230
3281
// create .version in case we don't have it yet
3231
3282
await native_fs_utils . _make_path_dirs ( file_path , fs_context ) ;
0 commit comments