@@ -1405,6 +1405,8 @@ class NamespaceFS {
14051405 const is_disabled_dir_content = this . _is_directory_content ( file_path , params . key ) && this . _is_versioning_disabled ( ) ;
14061406
14071407 const stat = await target_file . stat ( fs_context ) ;
1408+ const file_path_stat = config . NSFS_GLACIER_DMAPI_ENABLE_TAPE_RECLAIM &&
1409+ await nb_native ( ) . fs . stat ( fs_context , file_path ) . catch ( _ . noop ) ;
14081410 this . _verify_encryption ( params . encryption , this . _get_encryption_info ( stat ) ) ;
14091411
14101412 const copy_xattr = params . copy_source && params . xattr_copy ;
@@ -1453,6 +1455,11 @@ class NamespaceFS {
14531455 dbg . log1 ( 'NamespaceFS._finish_upload:' , open_mode , file_path , upload_path , fs_xattr ) ;
14541456
14551457 if ( ! same_inode && ! part_upload ) {
1458+ // If the target file is already on tape then this is a candidate for tape reclaim
1459+ if ( file_path_stat && file_path_stat . xattr [ Glacier . GPFS_DMAPI_XATTR_TAPE_INDICATOR ] ) {
1460+ await this . append_to_reclaim_wal ( fs_context , upload_path , file_path_stat ) ;
1461+ }
1462+
14561463 await this . _move_to_dest ( fs_context , upload_path , file_path , target_file , open_mode , params . key ) ;
14571464 }
14581465
@@ -2124,7 +2131,16 @@ class NamespaceFS {
21242131 if ( files ) await this . _close_files ( fs_context , files . delete_version , undefined , true ) ;
21252132 }
21262133 } else {
2127- await native_fs_utils . unlink_ignore_enoent ( fs_context , file_path ) ;
2134+ try {
2135+ const stat = config . NSFS_GLACIER_DMAPI_ENABLE_TAPE_RECLAIM &&
2136+ await nb_native ( ) . fs . stat ( fs_context , file_path ) . catch ( dbg . warn . bind ( this ) ) ;
2137+ await nb_native ( ) . fs . unlink ( fs_context , file_path ) ;
2138+ if ( stat ) {
2139+ await this . append_to_reclaim_wal ( fs_context , file_path , stat ) ;
2140+ }
2141+ } catch ( err ) {
2142+ if ( err . code !== 'ENOENT' && err . code !== 'EISDIR' ) throw err ;
2143+ }
21282144 }
21292145
21302146 await this . _delete_path_dirs ( file_path , fs_context ) ;
@@ -3709,6 +3725,28 @@ class NamespaceFS {
37093725 await NamespaceFS . restore_wal . append ( entry ) ;
37103726 }
37113727
3728+ /**
3729+ *
3730+ * @param {nb.NativeFSContext } fs_context
3731+ * @param {string } file_path
3732+ * @param {nb.NativeFSStats } [stat]
3733+ * @returns
3734+ */
3735+ async append_to_reclaim_wal ( fs_context , file_path , stat ) {
3736+ if ( ! config . NSFS_GLACIER_LOGS_ENABLED || ! config . NSFS_GLACIER_DMAPI_ENABLE_TAPE_RECLAIM ) return ;
3737+
3738+ if ( ! stat ) {
3739+ stat = await nb_native ( ) . fs . stat ( fs_context , file_path ) ;
3740+ }
3741+
3742+ const data = JSON . stringify ( {
3743+ full_path : file_path ,
3744+ logical_size : stat . size ,
3745+ ea : stat . xattr ,
3746+ } ) ;
3747+ await NamespaceFS . reclaim_wal . append ( data ) ;
3748+ }
3749+
37123750 static get migrate_wal ( ) {
37133751 if ( ! NamespaceFS . _migrate_wal ) {
37143752 NamespaceFS . _migrate_wal = new PersistentLogger ( config . NSFS_GLACIER_LOGS_DIR , Glacier . MIGRATE_WAL_NAME , {
@@ -3731,6 +3769,17 @@ class NamespaceFS {
37313769 return NamespaceFS . _restore_wal ;
37323770 }
37333771
3772+ static get reclaim_wal ( ) {
3773+ if ( ! NamespaceFS . _reclaim_wal ) {
3774+ NamespaceFS . _reclaim_wal = new PersistentLogger ( config . NSFS_GLACIER_LOGS_DIR , Glacier . RECLAIM_WAL_NAME , {
3775+ poll_interval : config . NSFS_GLACIER_LOGS_POLL_INTERVAL ,
3776+ locking : 'SHARED' ,
3777+ } ) ;
3778+ }
3779+
3780+ return NamespaceFS . _reclaim_wal ;
3781+ }
3782+
37343783 ////////////////////////////
37353784 // LIFECYLE HELPERS //
37363785 ////////////////////////////
@@ -3757,6 +3806,9 @@ class NamespaceFS {
37573806 this . _check_lifecycle_filter_before_deletion ( params , stat ) ;
37583807 const bucket_tmp_dir_path = this . get_bucket_tmpdir_full_path ( ) ;
37593808 await native_fs_utils . safe_unlink ( fs_context , file_path , stat , { dir_file, src_file } , bucket_tmp_dir_path ) ;
3809+ if ( ! is_empty_directory_content ) {
3810+ await this . append_to_reclaim_wal ( fs_context , file_path , src_stat ) . catch ( dbg . warn . bind ( this ) ) ;
3811+ }
37603812 } catch ( err ) {
37613813 dbg . log0 ( '_verify_lifecycle_filter_and_unlink err' , err . code , err , file_path ) ;
37623814 if ( err . code !== 'ENOENT' && err . code !== 'EISDIR' ) throw err ;
@@ -3803,7 +3855,8 @@ NamespaceFS._migrate_wal = null;
38033855/** @type {PersistentLogger } */
38043856NamespaceFS . _restore_wal = null ;
38053857
3858+ /** @type {PersistentLogger } */
3859+ NamespaceFS . _reclaim_wal = null ;
3860+
38063861module . exports = NamespaceFS ;
38073862module . exports . multi_buffer_pool = multi_buffer_pool ;
3808-
3809-
0 commit comments