@@ -1407,6 +1407,8 @@ class NamespaceFS {
14071407 const is_disabled_dir_content = this . _is_directory_content ( file_path , params . key ) && this . _is_versioning_disabled ( ) ;
14081408
14091409 const stat = await target_file . stat ( fs_context ) ;
1410+ const file_path_stat = config . NSFS_GLACIER_DMAPI_ENABLE_TAPE_RECLAIM &&
1411+ await nb_native ( ) . fs . stat ( fs_context , file_path ) . catch ( _ . noop ) ;
14101412 this . _verify_encryption ( params . encryption , this . _get_encryption_info ( stat ) ) ;
14111413
14121414 const copy_xattr = params . copy_source && params . xattr_copy ;
@@ -1455,6 +1457,11 @@ class NamespaceFS {
14551457 dbg . log1 ( 'NamespaceFS._finish_upload:' , open_mode , file_path , upload_path , fs_xattr ) ;
14561458
14571459 if ( ! same_inode && ! part_upload ) {
1460+ // If the target file is already on tape then this is a candidate for tape reclaim
1461+ if ( file_path_stat && file_path_stat . xattr [ Glacier . GPFS_DMAPI_XATTR_TAPE_INDICATOR ] ) {
1462+ await this . append_to_reclaim_wal ( fs_context , upload_path , file_path_stat ) ;
1463+ }
1464+
14581465 await this . _move_to_dest ( fs_context , upload_path , file_path , target_file , open_mode , params . key ) ;
14591466 }
14601467
@@ -2126,7 +2133,16 @@ class NamespaceFS {
21262133 if ( files ) await this . _close_files ( fs_context , files . delete_version , undefined , true ) ;
21272134 }
21282135 } else {
2129- await native_fs_utils . unlink_ignore_enoent ( fs_context , file_path ) ;
2136+ try {
2137+ const stat = config . NSFS_GLACIER_DMAPI_ENABLE_TAPE_RECLAIM &&
2138+ await nb_native ( ) . fs . stat ( fs_context , file_path ) . catch ( dbg . warn . bind ( this ) ) ;
2139+ await nb_native ( ) . fs . unlink ( fs_context , file_path ) ;
2140+ if ( stat ) {
2141+ await this . append_to_reclaim_wal ( fs_context , file_path , stat ) ;
2142+ }
2143+ } catch ( err ) {
2144+ if ( err . code !== 'ENOENT' && err . code !== 'EISDIR' ) throw err ;
2145+ }
21302146 }
21312147
21322148 await this . _delete_path_dirs ( file_path , fs_context ) ;
@@ -3711,6 +3727,28 @@ class NamespaceFS {
37113727 await NamespaceFS . restore_wal . append ( Glacier . getBackend ( ) . encode_log ( entry ) ) ;
37123728 }
37133729
3730+ /**
3731+ *
3732+ * @param {nb.NativeFSContext } fs_context
3733+ * @param {string } file_path
3734+ * @param {nb.NativeFSStats } [stat]
3735+ * @returns
3736+ */
3737+ async append_to_reclaim_wal ( fs_context , file_path , stat ) {
3738+ if ( ! config . NSFS_GLACIER_LOGS_ENABLED || ! config . NSFS_GLACIER_DMAPI_ENABLE_TAPE_RECLAIM ) return ;
3739+
3740+ if ( ! stat ) {
3741+ stat = await nb_native ( ) . fs . stat ( fs_context , file_path ) ;
3742+ }
3743+
3744+ const data = JSON . stringify ( {
3745+ full_path : file_path ,
3746+ logical_size : stat . size ,
3747+ ea : stat . xattr ,
3748+ } ) ;
3749+ await NamespaceFS . reclaim_wal . append ( data ) ;
3750+ }
3751+
37143752 static get migrate_wal ( ) {
37153753 if ( ! NamespaceFS . _migrate_wal ) {
37163754 NamespaceFS . _migrate_wal = new PersistentLogger ( config . NSFS_GLACIER_LOGS_DIR , Glacier . MIGRATE_WAL_NAME , {
@@ -3733,6 +3771,17 @@ class NamespaceFS {
37333771 return NamespaceFS . _restore_wal ;
37343772 }
37353773
3774+ static get reclaim_wal ( ) {
3775+ if ( ! NamespaceFS . _reclaim_wal ) {
3776+ NamespaceFS . _reclaim_wal = new PersistentLogger ( config . NSFS_GLACIER_LOGS_DIR , Glacier . RECLAIM_WAL_NAME , {
3777+ poll_interval : config . NSFS_GLACIER_LOGS_POLL_INTERVAL ,
3778+ locking : 'SHARED' ,
3779+ } ) ;
3780+ }
3781+
3782+ return NamespaceFS . _reclaim_wal ;
3783+ }
3784+
37363785 ////////////////////////////
37373786 // LIFECYLE HELPERS //
37383787 ////////////////////////////
@@ -3759,6 +3808,9 @@ class NamespaceFS {
37593808 this . _check_lifecycle_filter_before_deletion ( params , stat ) ;
37603809 const bucket_tmp_dir_path = this . get_bucket_tmpdir_full_path ( ) ;
37613810 await native_fs_utils . safe_unlink ( fs_context , file_path , stat , { dir_file, src_file } , bucket_tmp_dir_path ) ;
3811+ if ( ! is_empty_directory_content ) {
3812+ await this . append_to_reclaim_wal ( fs_context , file_path , src_stat ) . catch ( dbg . warn . bind ( this ) ) ;
3813+ }
37623814 } catch ( err ) {
37633815 dbg . log0 ( '_verify_lifecycle_filter_and_unlink err' , err . code , err , file_path ) ;
37643816 if ( err . code !== 'ENOENT' && err . code !== 'EISDIR' ) throw err ;
@@ -3805,7 +3857,8 @@ NamespaceFS._migrate_wal = null;
38053857/** @type {PersistentLogger } */
38063858NamespaceFS . _restore_wal = null ;
38073859
3860+ /** @type {PersistentLogger } */
3861+ NamespaceFS . _reclaim_wal = null ;
3862+
38083863module . exports = NamespaceFS ;
38093864module . exports . multi_buffer_pool = multi_buffer_pool ;
3810-
3811-
0 commit comments