@@ -348,26 +348,48 @@ fm_account_reclaim_guard_acquire() { # <reclaim-directory> <grace-seconds>
348348}
349349
350350fm_account_meta_lock_reclaim () { # <lock-path> <ownerless-grace-seconds>
351- local lock=$1 grace=$2 now mtime reclaim guard inode_before inode_after
351+ local lock=$1 grace=$2 now mtime reclaim guard inode_before inode_after generation
352352 local ownerless_since ownerless_tmp baseline required_grace
353353 [ ! -L " $lock " ] || return 1
354354 required_grace=$grace
355355 [ " $required_grace " -ge 1 ] || required_grace=1
356356 if [ -f " $lock " ]; then
357357 guard=" $lock .reclaiming"
358358 fm_account_reclaim_guard_acquire " $guard " " $required_grace " || return 1
359- inode_before=$( fm_account_path_inode " $lock " ) || { fm_account_reclaim_guard_release " $guard " ; return 1; }
359+ # Pin the observed generation so unlink-and-replace cannot recycle its inode before comparison.
360+ generation=$( mktemp -d " $lock .generation.XXXXXX" 2> /dev/null) || { fm_account_reclaim_guard_release " $guard " ; return 1; }
361+ if ! ln -n " $lock " " $generation /lock" 2> /dev/null; then
362+ rm -rf " $generation "
363+ fm_account_reclaim_guard_release " $guard "
364+ return 1
365+ fi
366+ inode_before=$( fm_account_path_inode " $generation /lock" ) || {
367+ rm -rf " $generation "
368+ fm_account_reclaim_guard_release " $guard "
369+ return 1
370+ }
360371 if fm_account_meta_lock_owner_alive " $lock " ; then
372+ rm -rf " $generation "
361373 fm_account_reclaim_guard_release " $guard "
362374 return 1
363375 fi
364- fm_account_reclaim_guard_owned " $guard " || return 1
365- inode_after=$( fm_account_path_inode " $lock " ) || { fm_account_reclaim_guard_release " $guard " ; return 1; }
376+ fm_account_reclaim_guard_owned " $guard " || { rm -rf " $generation " ; return 1; }
377+ inode_after=$( fm_account_path_inode " $lock " ) || {
378+ rm -rf " $generation "
379+ fm_account_reclaim_guard_release " $guard "
380+ return 1
381+ }
366382 if [ " $inode_before " != " $inode_after " ]; then
383+ rm -rf " $generation "
367384 fm_account_reclaim_guard_release " $guard "
368385 return 1
369386 fi
370- rm -f " $lock " || { fm_account_reclaim_guard_release " $guard " ; return 1; }
387+ rm -f " $lock " || {
388+ rm -rf " $generation "
389+ fm_account_reclaim_guard_release " $guard "
390+ return 1
391+ }
392+ rm -rf " $generation " || { fm_account_reclaim_guard_release " $guard " ; return 1; }
371393 fm_account_reclaim_guard_release " $guard "
372394 return 0
373395 fi
0 commit comments