aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am9
-rw-r--r--src/addrdb.cpp3
-rw-r--r--src/addrdb.h2
-rw-r--r--src/banman.h2
-rw-r--r--src/bench/bench.cpp2
-rw-r--r--src/bench/bench.h2
-rw-r--r--src/bench/bench_bitcoin.cpp2
-rw-r--r--src/bitcoin-tx.cpp2
-rw-r--r--src/common/init.cpp4
-rw-r--r--src/compat/assumptions.h1
-rw-r--r--src/dbwrapper.cpp4
-rw-r--r--src/dbwrapper.h2
-rw-r--r--src/flatfile.cpp2
-rw-r--r--src/flatfile.h2
-rw-r--r--src/i2p.cpp2
-rw-r--r--src/i2p.h2
-rw-r--r--src/index/blockfilterindex.cpp1
-rw-r--r--src/init.cpp3
-rw-r--r--src/init/common.cpp3
-rw-r--r--src/interfaces/wallet.h2
-rw-r--r--src/ipc/interfaces.cpp2
-rw-r--r--src/ipc/process.cpp2
-rw-r--r--src/ipc/process.h2
-rw-r--r--src/kernel/mempool_persist.cpp4
-rw-r--r--src/kernel/mempool_persist.h2
-rw-r--r--src/logging.cpp2
-rw-r--r--src/logging.h2
-rw-r--r--src/net.cpp2
-rw-r--r--src/node/blockstorage.cpp2
-rw-r--r--src/node/blockstorage.h2
-rw-r--r--src/node/chainstate.cpp1
-rw-r--r--src/node/mempool_persist_args.cpp2
-rw-r--r--src/node/mempool_persist_args.h2
-rw-r--r--src/node/utxo_snapshot.cpp2
-rw-r--r--src/node/utxo_snapshot.h2
-rw-r--r--src/policy/fees.cpp2
-rw-r--r--src/policy/fees.h2
-rw-r--r--src/policy/fees_args.h2
-rw-r--r--src/qt/guiutil.cpp3
-rw-r--r--src/qt/guiutil.h2
-rw-r--r--src/qt/intro.cpp3
-rw-r--r--src/qt/psbtoperationsdialog.cpp2
-rw-r--r--src/qt/walletframe.cpp4
-rw-r--r--src/rpc/blockchain.cpp2
-rw-r--r--src/rpc/blockchain.h2
-rw-r--r--src/rpc/mempool.cpp2
-rw-r--r--src/rpc/request.cpp5
-rw-r--r--src/test/argsman_tests.cpp6
-rw-r--r--src/test/fs_tests.cpp4
-rw-r--r--src/test/fuzz/banman.cpp2
-rw-r--r--src/test/fuzz/fuzz.cpp2
-rw-r--r--src/test/fuzz/utxo_snapshot.cpp2
-rw-r--r--src/test/script_tests.cpp2
-rw-r--r--src/test/settings_tests.cpp2
-rw-r--r--src/test/streams_tests.cpp2
-rw-r--r--src/test/util/chainstate.h2
-rw-r--r--src/test/util/setup_common.h2
-rw-r--r--src/test/util_tests.cpp7
-rw-r--r--src/torcontrol.h2
-rw-r--r--src/txdb.h2
-rw-r--r--src/util/asmap.cpp2
-rw-r--r--src/util/asmap.h2
-rw-r--r--src/util/fs.cpp (renamed from src/fs.cpp)2
-rw-r--r--src/util/fs.h (renamed from src/fs.h)6
-rw-r--r--src/util/fs_helpers.cpp295
-rw-r--r--src/util/fs_helpers.h63
-rw-r--r--src/util/getuniquepath.cpp2
-rw-r--r--src/util/getuniquepath.h2
-rw-r--r--src/util/readwritefile.cpp2
-rw-r--r--src/util/readwritefile.h2
-rw-r--r--src/util/settings.cpp2
-rw-r--r--src/util/settings.h2
-rw-r--r--src/util/system.cpp264
-rw-r--r--src/util/system.h50
-rw-r--r--src/validation.cpp3
-rw-r--r--src/validation.h2
-rw-r--r--src/wallet/bdb.cpp3
-rw-r--r--src/wallet/bdb.h2
-rw-r--r--src/wallet/db.cpp2
-rw-r--r--src/wallet/db.h2
-rw-r--r--src/wallet/dump.cpp2
-rw-r--r--src/wallet/dump.h2
-rw-r--r--src/wallet/load.cpp2
-rw-r--r--src/wallet/rpc/backup.cpp2
-rw-r--r--src/wallet/salvage.cpp2
-rw-r--r--src/wallet/salvage.h2
-rw-r--r--src/wallet/sqlite.cpp2
-rw-r--r--src/wallet/test/db_tests.cpp2
-rw-r--r--src/wallet/test/init_test_fixture.cpp2
-rw-r--r--src/wallet/wallet.cpp5
-rw-r--r--src/wallet/wallet.h2
-rw-r--r--src/wallet/walletdb.cpp2
-rw-r--r--src/wallet/wallettool.cpp2
-rw-r--r--src/wallet/walletutil.h2
94 files changed, 480 insertions, 412 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 53c809c901..444480f824 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -154,7 +154,6 @@ BITCOIN_CORE_H = \
deploymentstatus.h \
external_signer.h \
flatfile.h \
- fs.h \
headerssync.h \
httprpc.h \
httpserver.h \
@@ -285,6 +284,8 @@ BITCOIN_CORE_H = \
util/exception.h \
util/fastrange.h \
util/fees.h \
+ util/fs.h \
+ util/fs_helpers.h \
util/getuniquepath.h \
util/golombrice.h \
util/hash_type.h \
@@ -694,7 +695,6 @@ libbitcoin_util_a_SOURCES = \
support/lockedpool.cpp \
chainparamsbase.cpp \
clientversion.cpp \
- fs.cpp \
logging.cpp \
random.cpp \
randomenv.cpp \
@@ -707,6 +707,8 @@ libbitcoin_util_a_SOURCES = \
util/error.cpp \
util/exception.cpp \
util/fees.cpp \
+ util/fs.cpp \
+ util/fs_helpers.cpp \
util/getuniquepath.cpp \
util/hasher.cpp \
util/sock.cpp \
@@ -908,7 +910,6 @@ libbitcoinkernel_la_SOURCES = \
deploymentinfo.cpp \
deploymentstatus.cpp \
flatfile.cpp \
- fs.cpp \
hash.cpp \
kernel/chain.cpp \
kernel/checks.cpp \
@@ -951,6 +952,8 @@ libbitcoinkernel_la_SOURCES = \
uint256.cpp \
util/check.cpp \
util/exception.cpp \
+ util/fs.cpp \
+ util/fs_helpers.cpp \
util/getuniquepath.cpp \
util/hasher.cpp \
util/moneystr.cpp \
diff --git a/src/addrdb.cpp b/src/addrdb.cpp
index 9ae8244d1c..8ecccd4d22 100644
--- a/src/addrdb.cpp
+++ b/src/addrdb.cpp
@@ -9,7 +9,6 @@
#include <chainparams.h>
#include <clientversion.h>
#include <cstdint>
-#include <fs.h>
#include <hash.h>
#include <logging.h>
#include <logging/timer.h>
@@ -19,6 +18,8 @@
#include <streams.h>
#include <tinyformat.h>
#include <univalue.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/settings.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/addrdb.h b/src/addrdb.h
index 627ef3ac3c..08d86d0f01 100644
--- a/src/addrdb.h
+++ b/src/addrdb.h
@@ -6,9 +6,9 @@
#ifndef BITCOIN_ADDRDB_H
#define BITCOIN_ADDRDB_H
-#include <fs.h>
#include <net_types.h> // For banmap_t
#include <univalue.h>
+#include <util/fs.h>
#include <optional>
#include <vector>
diff --git a/src/banman.h b/src/banman.h
index 241f01dd2e..5a5f5677b0 100644
--- a/src/banman.h
+++ b/src/banman.h
@@ -7,9 +7,9 @@
#include <addrdb.h>
#include <common/bloom.h>
-#include <fs.h>
#include <net_types.h> // For banmap_t
#include <sync.h>
+#include <util/fs.h>
#include <chrono>
#include <cstdint>
diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp
index 4374a63250..84b66bc4b2 100644
--- a/src/bench/bench.cpp
+++ b/src/bench/bench.cpp
@@ -4,8 +4,8 @@
#include <bench/bench.h>
-#include <fs.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <util/string.h>
#include <chrono>
diff --git a/src/bench/bench.h b/src/bench/bench.h
index 22c63a797b..78196134e7 100644
--- a/src/bench/bench.h
+++ b/src/bench/bench.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_BENCH_BENCH_H
#define BITCOIN_BENCH_BENCH_H
-#include <fs.h>
+#include <util/fs.h>
#include <util/macros.h>
#include <chrono>
diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp
index 06e32f684f..7faaa1fb14 100644
--- a/src/bench/bench_bitcoin.cpp
+++ b/src/bench/bench_bitcoin.cpp
@@ -6,7 +6,7 @@
#include <clientversion.h>
#include <crypto/sha256.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <util/system.h>
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index f36b6054bb..a05443a2e5 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -12,7 +12,6 @@
#include <consensus/amount.h>
#include <consensus/consensus.h>
#include <core_io.h>
-#include <fs.h>
#include <key_io.h>
#include <policy/policy.h>
#include <primitives/transaction.h>
@@ -21,6 +20,7 @@
#include <script/signingprovider.h>
#include <univalue.h>
#include <util/exception.h>
+#include <util/fs.h>
#include <util/moneystr.h>
#include <util/rbf.h>
#include <util/strencodings.h>
diff --git a/src/common/init.cpp b/src/common/init.cpp
index 159eb7e2ef..e8fa7a14fd 100644
--- a/src/common/init.cpp
+++ b/src/common/init.cpp
@@ -2,10 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <common/init.h>
#include <chainparams.h>
-#include <fs.h>
+#include <common/init.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/compat/assumptions.h b/src/compat/assumptions.h
index 92615b582a..4488db0886 100644
--- a/src/compat/assumptions.h
+++ b/src/compat/assumptions.h
@@ -8,6 +8,7 @@
#ifndef BITCOIN_COMPAT_ASSUMPTIONS_H
#define BITCOIN_COMPAT_ASSUMPTIONS_H
+#include <cstddef>
#include <limits>
// Assumption: We assume that the macro NDEBUG is not defined.
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index 0c6debfa80..2aade14ef4 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -4,12 +4,12 @@
#include <dbwrapper.h>
-#include <fs.h>
#include <logging.h>
#include <random.h>
#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <algorithm>
#include <cassert>
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index 578d9880ac..35782edca6 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -6,11 +6,11 @@
#define BITCOIN_DBWRAPPER_H
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <serialize.h>
#include <span.h>
#include <streams.h>
+#include <util/fs.h>
#include <cstddef>
#include <cstdint>
diff --git a/src/flatfile.cpp b/src/flatfile.cpp
index d6e84d02c1..59861a08ad 100644
--- a/src/flatfile.cpp
+++ b/src/flatfile.cpp
@@ -8,7 +8,7 @@
#include <flatfile.h>
#include <logging.h>
#include <tinyformat.h>
-#include <util/system.h>
+#include <util/fs_helpers.h>
FlatFileSeq::FlatFileSeq(fs::path dir, const char* prefix, size_t chunk_size) :
m_dir(std::move(dir)),
diff --git a/src/flatfile.h b/src/flatfile.h
index e4be9a9cb1..26b466db71 100644
--- a/src/flatfile.h
+++ b/src/flatfile.h
@@ -8,8 +8,8 @@
#include <string>
-#include <fs.h>
#include <serialize.h>
+#include <util/fs.h>
struct FlatFilePos
{
diff --git a/src/i2p.cpp b/src/i2p.cpp
index a3bfc23a65..76fbb89536 100644
--- a/src/i2p.cpp
+++ b/src/i2p.cpp
@@ -6,13 +6,13 @@
#include <compat/compat.h>
#include <compat/endian.h>
#include <crypto/sha256.h>
-#include <fs.h>
#include <i2p.h>
#include <logging.h>
#include <netaddress.h>
#include <netbase.h>
#include <random.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/readwritefile.h>
#include <util/sock.h>
#include <util/spanparsing.h>
diff --git a/src/i2p.h b/src/i2p.h
index 6e7bafc945..c9c99292d9 100644
--- a/src/i2p.h
+++ b/src/i2p.h
@@ -6,9 +6,9 @@
#define BITCOIN_I2P_H
#include <compat/compat.h>
-#include <fs.h>
#include <netaddress.h>
#include <sync.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/threadinterrupt.h>
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index 59bf6d34cf..43c2215338 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -8,6 +8,7 @@
#include <hash.h>
#include <index/blockfilterindex.h>
#include <node/blockstorage.h>
+#include <util/fs_helpers.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/init.cpp b/src/init.cpp
index 16909f7e47..1122496539 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -20,7 +20,6 @@
#include <chainparams.h>
#include <consensus/amount.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <hash.h>
#include <httprpc.h>
#include <httpserver.h>
@@ -70,6 +69,8 @@
#include <txmempool.h>
#include <util/asmap.h>
#include <util/check.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/moneystr.h>
#include <util/strencodings.h>
#include <util/string.h>
diff --git a/src/init/common.cpp b/src/init/common.cpp
index a7829c5d99..33a5cec3f1 100644
--- a/src/init/common.cpp
+++ b/src/init/common.cpp
@@ -7,10 +7,11 @@
#endif
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <node/interface_ui.h>
#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/string.h>
#include <util/system.h>
#include <util/time.h>
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index 86707b20b1..b37763e686 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -6,11 +6,11 @@
#define BITCOIN_INTERFACES_WALLET_H
#include <consensus/amount.h>
-#include <fs.h>
#include <interfaces/chain.h> // For ChainClient
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
#include <script/standard.h> // For CTxDestination
#include <support/allocators/secure.h> // For SecureString
+#include <util/fs.h>
#include <util/message.h>
#include <util/result.h>
#include <util/ui_change_type.h>
diff --git a/src/ipc/interfaces.cpp b/src/ipc/interfaces.cpp
index 396f3ddf25..d804d9d291 100644
--- a/src/ipc/interfaces.cpp
+++ b/src/ipc/interfaces.cpp
@@ -2,7 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <interfaces/init.h>
#include <interfaces/ipc.h>
#include <ipc/capnp/protocol.h>
@@ -10,6 +9,7 @@
#include <ipc/protocol.h>
#include <logging.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/system.h>
#include <cstdio>
diff --git a/src/ipc/process.cpp b/src/ipc/process.cpp
index 4dc88ae44b..9657dcd092 100644
--- a/src/ipc/process.cpp
+++ b/src/ipc/process.cpp
@@ -2,11 +2,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <ipc/process.h>
#include <ipc/protocol.h>
#include <mp/util.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <cstdint>
diff --git a/src/ipc/process.h b/src/ipc/process.h
index 4bb2930d9c..40f2d2acf6 100644
--- a/src/ipc/process.h
+++ b/src/ipc/process.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_IPC_PROCESS_H
#define BITCOIN_IPC_PROCESS_H
+#include <util/fs.h>
+
#include <memory>
#include <string>
diff --git a/src/kernel/mempool_persist.cpp b/src/kernel/mempool_persist.cpp
index a14b2e6163..71f3aac366 100644
--- a/src/kernel/mempool_persist.cpp
+++ b/src/kernel/mempool_persist.cpp
@@ -6,7 +6,6 @@
#include <clientversion.h>
#include <consensus/amount.h>
-#include <fs.h>
#include <logging.h>
#include <primitives/transaction.h>
#include <serialize.h>
@@ -15,7 +14,8 @@
#include <sync.h>
#include <txmempool.h>
#include <uint256.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/time.h>
#include <validation.h>
diff --git a/src/kernel/mempool_persist.h b/src/kernel/mempool_persist.h
index ca4917e38b..cb09119e4a 100644
--- a/src/kernel/mempool_persist.h
+++ b/src/kernel/mempool_persist.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_KERNEL_MEMPOOL_PERSIST_H
#define BITCOIN_KERNEL_MEMPOOL_PERSIST_H
-#include <fs.h>
+#include <util/fs.h>
class Chainstate;
class CTxMemPool;
diff --git a/src/logging.cpp b/src/logging.cpp
index a9b2a2b33a..6a7991255d 100644
--- a/src/logging.cpp
+++ b/src/logging.cpp
@@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <logging.h>
+#include <util/fs.h>
#include <util/string.h>
#include <util/threadnames.h>
#include <util/time.h>
diff --git a/src/logging.h b/src/logging.h
index 954731d214..e7c554e79f 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -6,9 +6,9 @@
#ifndef BITCOIN_LOGGING_H
#define BITCOIN_LOGGING_H
-#include <fs.h>
#include <threadsafety.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/string.h>
#include <atomic>
diff --git a/src/net.cpp b/src/net.cpp
index 7023cb0f49..4f4c0a4079 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -16,7 +16,6 @@
#include <compat/compat.h>
#include <consensus/consensus.h>
#include <crypto/sha256.h>
-#include <fs.h>
#include <i2p.h>
#include <logging.h>
#include <net_permissions.h>
@@ -27,6 +26,7 @@
#include <protocol.h>
#include <random.h>
#include <scheduler.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/strencodings.h>
#include <util/syscall_sandbox.h>
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index 53721b807c..af84e6d7e7 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -8,7 +8,6 @@
#include <clientversion.h>
#include <consensus/validation.h>
#include <flatfile.h>
-#include <fs.h>
#include <hash.h>
#include <logging.h>
#include <kernel/chainparams.h>
@@ -18,6 +17,7 @@
#include <signet.h>
#include <streams.h>
#include <undo.h>
+#include <util/fs.h>
#include <util/syscall_sandbox.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
index 5ba0045b8b..3eb27cc72d 100644
--- a/src/node/blockstorage.h
+++ b/src/node/blockstorage.h
@@ -7,12 +7,12 @@
#include <attributes.h>
#include <chain.h>
-#include <fs.h>
#include <kernel/blockmanager_opts.h>
#include <kernel/cs_main.h>
#include <protocol.h>
#include <sync.h>
#include <txdb.h>
+#include <util/fs.h>
#include <atomic>
#include <cstdint>
diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp
index cfd3472592..f60ff83a0d 100644
--- a/src/node/chainstate.cpp
+++ b/src/node/chainstate.cpp
@@ -16,6 +16,7 @@
#include <tinyformat.h>
#include <txdb.h>
#include <uint256.h>
+#include <util/fs.h>
#include <util/time.h>
#include <util/translation.h>
#include <validation.h>
diff --git a/src/node/mempool_persist_args.cpp b/src/node/mempool_persist_args.cpp
index 4e775869c6..78e3472644 100644
--- a/src/node/mempool_persist_args.cpp
+++ b/src/node/mempool_persist_args.cpp
@@ -4,7 +4,7 @@
#include <node/mempool_persist_args.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/node/mempool_persist_args.h b/src/node/mempool_persist_args.h
index f719ec62ab..3b101f0930 100644
--- a/src/node/mempool_persist_args.h
+++ b/src/node/mempool_persist_args.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_NODE_MEMPOOL_PERSIST_ARGS_H
#define BITCOIN_NODE_MEMPOOL_PERSIST_ARGS_H
-#include <fs.h>
+#include <util/fs.h>
class ArgsManager;
diff --git a/src/node/utxo_snapshot.cpp b/src/node/utxo_snapshot.cpp
index cccf95e552..591c1dad6e 100644
--- a/src/node/utxo_snapshot.cpp
+++ b/src/node/utxo_snapshot.cpp
@@ -4,13 +4,13 @@
#include <node/utxo_snapshot.h>
-#include <fs.h>
#include <logging.h>
#include <streams.h>
#include <sync.h>
#include <tinyformat.h>
#include <txdb.h>
#include <uint256.h>
+#include <util/fs.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/node/utxo_snapshot.h b/src/node/utxo_snapshot.h
index c5c018c9e8..44ddd77dc3 100644
--- a/src/node/utxo_snapshot.h
+++ b/src/node/utxo_snapshot.h
@@ -6,11 +6,11 @@
#ifndef BITCOIN_NODE_UTXO_SNAPSHOT_H
#define BITCOIN_NODE_UTXO_SNAPSHOT_H
-#include <fs.h>
#include <kernel/cs_main.h>
#include <serialize.h>
#include <sync.h>
#include <uint256.h>
+#include <util/fs.h>
#include <cstdint>
#include <optional>
diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp
index d244de1bb2..6121224979 100644
--- a/src/policy/fees.cpp
+++ b/src/policy/fees.cpp
@@ -7,7 +7,6 @@
#include <clientversion.h>
#include <consensus/amount.h>
-#include <fs.h>
#include <kernel/mempool_entry.h>
#include <logging.h>
#include <policy/feerate.h>
@@ -18,6 +17,7 @@
#include <sync.h>
#include <tinyformat.h>
#include <uint256.h>
+#include <util/fs.h>
#include <util/serfloat.h>
#include <util/system.h>
#include <util/time.h>
diff --git a/src/policy/fees.h b/src/policy/fees.h
index 1c24b8c7c3..775a72a764 100644
--- a/src/policy/fees.h
+++ b/src/policy/fees.h
@@ -6,12 +6,12 @@
#define BITCOIN_POLICY_FEES_H
#include <consensus/amount.h>
-#include <fs.h>
#include <policy/feerate.h>
#include <random.h>
#include <sync.h>
#include <threadsafety.h>
#include <uint256.h>
+#include <util/fs.h>
#include <array>
#include <map>
diff --git a/src/policy/fees_args.h b/src/policy/fees_args.h
index 6b65ce0aa9..ef5cf144af 100644
--- a/src/policy/fees_args.h
+++ b/src/policy/fees_args.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_POLICY_FEES_ARGS_H
#define BITCOIN_POLICY_FEES_ARGS_H
-#include <fs.h>
+#include <util/fs.h>
class ArgsManager;
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 96fe091b60..e98d953fd2 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -12,7 +12,6 @@
#include <base58.h>
#include <chainparams.h>
-#include <fs.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <policy/policy.h>
@@ -21,6 +20,8 @@
#include <script/script.h>
#include <script/standard.h>
#include <util/exception.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/system.h>
#include <util/time.h>
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 87a323bde9..7f06fdfe37 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -6,10 +6,10 @@
#define BITCOIN_QT_GUIUTIL_H
#include <consensus/amount.h>
-#include <fs.h>
#include <net.h>
#include <netaddress.h>
#include <util/check.h>
+#include <util/fs.h>
#include <QApplication>
#include <QEvent>
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 64c2890fc1..6423e457aa 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -7,15 +7,16 @@
#endif
#include <chainparams.h>
-#include <fs.h>
#include <qt/intro.h>
#include <qt/forms/ui_intro.h>
+#include <util/fs.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <interfaces/node.h>
+#include <util/fs_helpers.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/qt/psbtoperationsdialog.cpp b/src/qt/psbtoperationsdialog.cpp
index 0994e0080a..fe52e11157 100644
--- a/src/qt/psbtoperationsdialog.cpp
+++ b/src/qt/psbtoperationsdialog.cpp
@@ -5,7 +5,6 @@
#include <qt/psbtoperationsdialog.h>
#include <core_io.h>
-#include <fs.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <node/psbt.h>
@@ -14,6 +13,7 @@
#include <qt/forms/ui_psbtoperationsdialog.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <fstream>
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index 43411370a2..7a8a053900 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -4,7 +4,6 @@
#include <qt/walletframe.h>
-#include <fs.h>
#include <node/interface_ui.h>
#include <psbt.h>
#include <qt/guiutil.h>
@@ -12,7 +11,8 @@
#include <qt/psbtoperationsdialog.h>
#include <qt/walletmodel.h>
#include <qt/walletview.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <cassert>
#include <fstream>
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 1a9b265fbe..fb22321d90 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -15,7 +15,6 @@
#include <core_io.h>
#include <deploymentinfo.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
@@ -39,6 +38,7 @@
#include <undo.h>
#include <univalue.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
index 9ccb87b78a..0a86085db0 100644
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -7,9 +7,9 @@
#include <consensus/amount.h>
#include <core_io.h>
-#include <fs.h>
#include <streams.h>
#include <sync.h>
+#include <util/fs.h>
#include <validation.h>
#include <any>
diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
index 3a69e2d8a2..927b4ce1fc 100644
--- a/src/rpc/mempool.cpp
+++ b/src/rpc/mempool.cpp
@@ -9,7 +9,6 @@
#include <chainparams.h>
#include <core_io.h>
-#include <fs.h>
#include <kernel/mempool_entry.h>
#include <node/mempool_persist_args.h>
#include <policy/rbf.h>
@@ -21,6 +20,7 @@
#include <script/standard.h>
#include <txmempool.h>
#include <univalue.h>
+#include <util/fs.h>
#include <util/moneystr.h>
#include <util/time.h>
diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
index b6ef1909c9..4c5ccbbdad 100644
--- a/src/rpc/request.cpp
+++ b/src/rpc/request.cpp
@@ -5,12 +5,13 @@
#include <rpc/request.h>
-#include <fs.h>
+#include <util/fs.h>
#include <random.h>
#include <rpc/protocol.h>
-#include <util/system.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
+#include <util/system.h>
#include <fstream>
#include <stdexcept>
diff --git a/src/test/argsman_tests.cpp b/src/test/argsman_tests.cpp
index d00876bc70..5bade94f37 100644
--- a/src/test/argsman_tests.cpp
+++ b/src/test/argsman_tests.cpp
@@ -2,14 +2,14 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <util/system.h>
-#include <fs.h>
#include <sync.h>
#include <test/util/logging.h>
#include <test/util/setup_common.h>
#include <test/util/str.h>
-#include <util/strencodings.h>
#include <univalue.h>
+#include <util/fs.h>
+#include <util/strencodings.h>
+#include <util/system.h>
#include <array>
#include <optional>
diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp
index 7e7d630daa..7cfecb2b22 100644
--- a/src/test/fs_tests.cpp
+++ b/src/test/fs_tests.cpp
@@ -2,9 +2,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
-#include <fs.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/getuniquepath.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp
index 273dcfd850..b4a93499ed 100644
--- a/src/test/fuzz/banman.cpp
+++ b/src/test/fuzz/banman.cpp
@@ -3,13 +3,13 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <banman.h>
-#include <fs.h>
#include <netaddress.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <util/readwritefile.h>
#include <util/system.h>
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp
index 9683f32d84..0bbfb206d5 100644
--- a/src/test/fuzz/fuzz.cpp
+++ b/src/test/fuzz/fuzz.cpp
@@ -4,11 +4,11 @@
#include <test/fuzz/fuzz.h>
-#include <fs.h>
#include <netaddress.h>
#include <netbase.h>
#include <test/util/setup_common.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/time.h>
diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp
index 7119643b45..be34906025 100644
--- a/src/test/fuzz/utxo_snapshot.cpp
+++ b/src/test/fuzz/utxo_snapshot.cpp
@@ -4,13 +4,13 @@
#include <chainparams.h>
#include <consensus/validation.h>
-#include <fs.h>
#include <node/utxo_snapshot.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/mining.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <validation.h>
#include <validationinterface.h>
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 45d9f2cf29..d8898743b0 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -6,7 +6,6 @@
#include <test/data/bip341_wallet_vectors.json.h>
#include <core_io.h>
-#include <fs.h>
#include <key.h>
#include <rpc/util.h>
#include <script/script.h>
@@ -19,6 +18,7 @@
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <test/util/transaction_utils.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <util/system.h>
diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
index ad12c46561..4d0d42ae38 100644
--- a/src/test/settings_tests.cpp
+++ b/src/test/settings_tests.cpp
@@ -4,9 +4,9 @@
#include <util/settings.h>
-#include <fs.h>
#include <test/util/setup_common.h>
#include <test/util/str.h>
+#include <util/fs.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index a9b5251ad3..a0392570f1 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -2,10 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <streams.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/util/chainstate.h b/src/test/util/chainstate.h
index e664435e03..bf8f8b5819 100644
--- a/src/test/util/chainstate.h
+++ b/src/test/util/chainstate.h
@@ -6,12 +6,12 @@
#define BITCOIN_TEST_UTIL_CHAINSTATE_H
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <node/context.h>
#include <node/utxo_snapshot.h>
#include <rpc/blockchain.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <validation.h>
#include <univalue.h>
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index 8874db7e75..948ebc097c 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -6,7 +6,6 @@
#define BITCOIN_TEST_UTIL_SETUP_COMMON_H
#include <chainparamsbase.h>
-#include <fs.h>
#include <key.h>
#include <node/caches.h>
#include <node/context.h>
@@ -15,6 +14,7 @@
#include <random.h>
#include <stdexcept>
#include <util/check.h>
+#include <util/fs.h>
#include <util/string.h>
#include <util/system.h>
#include <util/vector.h>
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index a13552653e..3a5126f8a8 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -2,16 +2,16 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <util/system.h>
-
#include <clientversion.h>
-#include <fs.h>
#include <hash.h> // For Hash()
#include <key.h> // For CKey
#include <sync.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <uint256.h>
+#include <util/bitdeque.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/getuniquepath.h>
#include <util/message.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC
#include <util/moneystr.h>
@@ -22,7 +22,6 @@
#include <util/string.h>
#include <util/time.h>
#include <util/vector.h>
-#include <util/bitdeque.h>
#include <array>
#include <cmath>
diff --git a/src/torcontrol.h b/src/torcontrol.h
index 6563a2ef42..afc5413db0 100644
--- a/src/torcontrol.h
+++ b/src/torcontrol.h
@@ -8,8 +8,8 @@
#ifndef BITCOIN_TORCONTROL_H
#define BITCOIN_TORCONTROL_H
-#include <fs.h>
#include <netaddress.h>
+#include <util/fs.h>
#include <boost/signals2/signal.hpp>
diff --git a/src/txdb.h b/src/txdb.h
index 8a876349fb..63c7152097 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -10,7 +10,7 @@
#include <dbwrapper.h>
#include <kernel/cs_main.h>
#include <sync.h>
-#include <fs.h>
+#include <util/fs.h>
#include <memory>
#include <optional>
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp
index 4b548c5a4d..360573cbae 100644
--- a/src/util/asmap.cpp
+++ b/src/util/asmap.cpp
@@ -6,10 +6,10 @@
#include <clientversion.h>
#include <crypto/common.h>
-#include <fs.h>
#include <logging.h>
#include <serialize.h>
#include <streams.h>
+#include <util/fs.h>
#include <algorithm>
#include <cassert>
diff --git a/src/util/asmap.h b/src/util/asmap.h
index 844037f816..08a88f1b3c 100644
--- a/src/util/asmap.h
+++ b/src/util/asmap.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_ASMAP_H
#define BITCOIN_UTIL_ASMAP_H
-#include <fs.h>
+#include <util/fs.h>
#include <cstdint>
#include <vector>
diff --git a/src/fs.cpp b/src/util/fs.cpp
index 64411fe41f..e8fb72670f 100644
--- a/src/fs.cpp
+++ b/src/util/fs.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
+#include <util/fs.h>
#include <util/syserror.h>
#ifndef WIN32
diff --git a/src/fs.h b/src/util/fs.h
index 0ece256acb..886a30394e 100644
--- a/src/fs.h
+++ b/src/util/fs.h
@@ -2,8 +2,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_FS_H
-#define BITCOIN_FS_H
+#ifndef BITCOIN_UTIL_FS_H
+#define BITCOIN_UTIL_FS_H
#include <tinyformat.h>
@@ -248,4 +248,4 @@ template<> inline void formatValue(std::ostream&, const char*, const char*, int,
template<> inline void formatValue(std::ostream&, const char*, const char*, int, const fs::path&) = delete;
} // namespace tinyformat
-#endif // BITCOIN_FS_H
+#endif // BITCOIN_UTIL_FS_H
diff --git a/src/util/fs_helpers.cpp b/src/util/fs_helpers.cpp
new file mode 100644
index 0000000000..d05cb8a63d
--- /dev/null
+++ b/src/util/fs_helpers.cpp
@@ -0,0 +1,295 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2023 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <util/fs_helpers.h>
+
+#if defined(HAVE_CONFIG_H)
+#include <config/bitcoin-config.h>
+#endif
+
+#include <logging.h>
+#include <sync.h>
+#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/getuniquepath.h>
+
+#include <cerrno>
+#include <filesystem>
+#include <fstream>
+#include <map>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <utility>
+
+#ifndef WIN32
+// for posix_fallocate, in configure.ac we check if it is present after this
+#ifdef __linux__
+
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
+#endif
+
+#define _POSIX_C_SOURCE 200112L
+
+#endif // __linux__
+
+#include <fcntl.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#else
+#include <io.h> /* For _get_osfhandle, _chsize */
+#include <shlobj.h> /* For SHGetSpecialFolderPathW */
+#endif // WIN32
+
+/** Mutex to protect dir_locks. */
+static GlobalMutex cs_dir_locks;
+/** A map that contains all the currently held directory locks. After
+ * successful locking, these will be held here until the global destructor
+ * cleans them up and thus automatically unlocks them, or ReleaseDirectoryLocks
+ * is called.
+ */
+static std::map<std::string, std::unique_ptr<fsbridge::FileLock>> dir_locks GUARDED_BY(cs_dir_locks);
+
+bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only)
+{
+ LOCK(cs_dir_locks);
+ fs::path pathLockFile = directory / lockfile_name;
+
+ // If a lock for this directory already exists in the map, don't try to re-lock it
+ if (dir_locks.count(fs::PathToString(pathLockFile))) {
+ return true;
+ }
+
+ // Create empty lock file if it doesn't exist.
+ FILE* file = fsbridge::fopen(pathLockFile, "a");
+ if (file) fclose(file);
+ auto lock = std::make_unique<fsbridge::FileLock>(pathLockFile);
+ if (!lock->TryLock()) {
+ return error("Error while attempting to lock directory %s: %s", fs::PathToString(directory), lock->GetReason());
+ }
+ if (!probe_only) {
+ // Lock successful and we're not just probing, put it into the map
+ dir_locks.emplace(fs::PathToString(pathLockFile), std::move(lock));
+ }
+ return true;
+}
+
+void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name)
+{
+ LOCK(cs_dir_locks);
+ dir_locks.erase(fs::PathToString(directory / lockfile_name));
+}
+
+void ReleaseDirectoryLocks()
+{
+ LOCK(cs_dir_locks);
+ dir_locks.clear();
+}
+
+bool DirIsWritable(const fs::path& directory)
+{
+ fs::path tmpFile = GetUniquePath(directory);
+
+ FILE* file = fsbridge::fopen(tmpFile, "a");
+ if (!file) return false;
+
+ fclose(file);
+ remove(tmpFile);
+
+ return true;
+}
+
+bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes)
+{
+ constexpr uint64_t min_disk_space = 52428800; // 50 MiB
+
+ uint64_t free_bytes_available = fs::space(dir).available;
+ return free_bytes_available >= min_disk_space + additional_bytes;
+}
+
+std::streampos GetFileSize(const char* path, std::streamsize max)
+{
+ std::ifstream file{path, std::ios::binary};
+ file.ignore(max);
+ return file.gcount();
+}
+
+bool FileCommit(FILE* file)
+{
+ if (fflush(file) != 0) { // harmless if redundantly called
+ LogPrintf("%s: fflush failed: %d\n", __func__, errno);
+ return false;
+ }
+#ifdef WIN32
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
+ if (FlushFileBuffers(hFile) == 0) {
+ LogPrintf("%s: FlushFileBuffers failed: %d\n", __func__, GetLastError());
+ return false;
+ }
+#elif defined(MAC_OSX) && defined(F_FULLFSYNC)
+ if (fcntl(fileno(file), F_FULLFSYNC, 0) == -1) { // Manpage says "value other than -1" is returned on success
+ LogPrintf("%s: fcntl F_FULLFSYNC failed: %d\n", __func__, errno);
+ return false;
+ }
+#elif HAVE_FDATASYNC
+ if (fdatasync(fileno(file)) != 0 && errno != EINVAL) { // Ignore EINVAL for filesystems that don't support sync
+ LogPrintf("%s: fdatasync failed: %d\n", __func__, errno);
+ return false;
+ }
+#else
+ if (fsync(fileno(file)) != 0 && errno != EINVAL) {
+ LogPrintf("%s: fsync failed: %d\n", __func__, errno);
+ return false;
+ }
+#endif
+ return true;
+}
+
+void DirectoryCommit(const fs::path& dirname)
+{
+#ifndef WIN32
+ FILE* file = fsbridge::fopen(dirname, "r");
+ if (file) {
+ fsync(fileno(file));
+ fclose(file);
+ }
+#endif
+}
+
+bool TruncateFile(FILE* file, unsigned int length)
+{
+#if defined(WIN32)
+ return _chsize(_fileno(file), length) == 0;
+#else
+ return ftruncate(fileno(file), length) == 0;
+#endif
+}
+
+/**
+ * this function tries to raise the file descriptor limit to the requested number.
+ * It returns the actual file descriptor limit (which may be more or less than nMinFD)
+ */
+int RaiseFileDescriptorLimit(int nMinFD)
+{
+#if defined(WIN32)
+ return 2048;
+#else
+ struct rlimit limitFD;
+ if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
+ if (limitFD.rlim_cur < (rlim_t)nMinFD) {
+ limitFD.rlim_cur = nMinFD;
+ if (limitFD.rlim_cur > limitFD.rlim_max)
+ limitFD.rlim_cur = limitFD.rlim_max;
+ setrlimit(RLIMIT_NOFILE, &limitFD);
+ getrlimit(RLIMIT_NOFILE, &limitFD);
+ }
+ return limitFD.rlim_cur;
+ }
+ return nMinFD; // getrlimit failed, assume it's fine
+#endif
+}
+
+/**
+ * this function tries to make a particular range of a file allocated (corresponding to disk space)
+ * it is advisory, and the range specified in the arguments will never contain live data
+ */
+void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length)
+{
+#if defined(WIN32)
+ // Windows-specific version
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
+ LARGE_INTEGER nFileSize;
+ int64_t nEndPos = (int64_t)offset + length;
+ nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
+ nFileSize.u.HighPart = nEndPos >> 32;
+ SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
+ SetEndOfFile(hFile);
+#elif defined(MAC_OSX)
+ // OSX specific version
+ // NOTE: Contrary to other OS versions, the OSX version assumes that
+ // NOTE: offset is the size of the file.
+ fstore_t fst;
+ fst.fst_flags = F_ALLOCATECONTIG;
+ fst.fst_posmode = F_PEOFPOSMODE;
+ fst.fst_offset = 0;
+ fst.fst_length = length; // mac os fst_length takes the # of free bytes to allocate, not desired file size
+ fst.fst_bytesalloc = 0;
+ if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
+ fst.fst_flags = F_ALLOCATEALL;
+ fcntl(fileno(file), F_PREALLOCATE, &fst);
+ }
+ ftruncate(fileno(file), static_cast<off_t>(offset) + length);
+#else
+#if defined(HAVE_POSIX_FALLOCATE)
+ // Version using posix_fallocate
+ off_t nEndPos = (off_t)offset + length;
+ if (0 == posix_fallocate(fileno(file), 0, nEndPos)) return;
+#endif
+ // Fallback version
+ // TODO: just write one byte per block
+ static const char buf[65536] = {};
+ if (fseek(file, offset, SEEK_SET)) {
+ return;
+ }
+ while (length > 0) {
+ unsigned int now = 65536;
+ if (length < now)
+ now = length;
+ fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
+ length -= now;
+ }
+#endif
+}
+
+#ifdef WIN32
+fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
+{
+ WCHAR pszPath[MAX_PATH] = L"";
+
+ if (SHGetSpecialFolderPathW(nullptr, pszPath, nFolder, fCreate)) {
+ return fs::path(pszPath);
+ }
+
+ LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n");
+ return fs::path("");
+}
+#endif
+
+bool RenameOver(fs::path src, fs::path dest)
+{
+#ifdef __MINGW64__
+ // This is a workaround for a bug in libstdc++ which
+ // implements std::filesystem::rename with _wrename function.
+ // This bug has been fixed in upstream:
+ // - GCC 10.3: 8dd1c1085587c9f8a21bb5e588dfe1e8cdbba79e
+ // - GCC 11.1: 1dfd95f0a0ca1d9e6cbc00e6cbfd1fa20a98f312
+ // For more details see the commits mentioned above.
+ return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(),
+ MOVEFILE_REPLACE_EXISTING) != 0;
+#else
+ std::error_code error;
+ fs::rename(src, dest, error);
+ return !error;
+#endif
+}
+
+/**
+ * Ignores exceptions thrown by create_directories if the requested directory exists.
+ * Specifically handles case where path p exists, but it wasn't possible for the user to
+ * write to the parent directory.
+ */
+bool TryCreateDirectories(const fs::path& p)
+{
+ try {
+ return fs::create_directories(p);
+ } catch (const fs::filesystem_error&) {
+ if (!fs::exists(p) || !fs::is_directory(p))
+ throw;
+ }
+
+ // create_directories didn't create the directory, it had to have existed already
+ return false;
+}
diff --git a/src/util/fs_helpers.h b/src/util/fs_helpers.h
new file mode 100644
index 0000000000..e7db01a89b
--- /dev/null
+++ b/src/util/fs_helpers.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2023 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTIL_FS_HELPERS_H
+#define BITCOIN_UTIL_FS_HELPERS_H
+
+#include <util/fs.h>
+
+#include <cstdint>
+#include <cstdio>
+#include <iosfwd>
+#include <limits>
+
+/**
+ * Ensure file contents are fully committed to disk, using a platform-specific
+ * feature analogous to fsync().
+ */
+bool FileCommit(FILE* file);
+
+/**
+ * Sync directory contents. This is required on some environments to ensure that
+ * newly created files are committed to disk.
+ */
+void DirectoryCommit(const fs::path& dirname);
+
+bool TruncateFile(FILE* file, unsigned int length);
+int RaiseFileDescriptorLimit(int nMinFD);
+void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length);
+
+/**
+ * Rename src to dest.
+ * @return true if the rename was successful.
+ */
+[[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
+
+bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only = false);
+void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
+bool DirIsWritable(const fs::path& directory);
+bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
+
+/** Get the size of a file by scanning it.
+ *
+ * @param[in] path The file path
+ * @param[in] max Stop seeking beyond this limit
+ * @return The file size or max
+ */
+std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
+
+/** Release all directory locks. This is used for unit testing only, at runtime
+ * the global destructor will take care of the locks.
+ */
+void ReleaseDirectoryLocks();
+
+bool TryCreateDirectories(const fs::path& p);
+fs::path GetDefaultDataDir();
+
+#ifdef WIN32
+fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
+#endif
+
+#endif // BITCOIN_UTIL_FS_HELPERS_H
diff --git a/src/util/getuniquepath.cpp b/src/util/getuniquepath.cpp
index 42c5dee0ed..105b4d52d2 100644
--- a/src/util/getuniquepath.cpp
+++ b/src/util/getuniquepath.cpp
@@ -3,7 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <random.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/strencodings.h>
fs::path GetUniquePath(const fs::path& base)
diff --git a/src/util/getuniquepath.h b/src/util/getuniquepath.h
index e0c6147876..1563652300 100644
--- a/src/util/getuniquepath.h
+++ b/src/util/getuniquepath.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_GETUNIQUEPATH_H
#define BITCOIN_UTIL_GETUNIQUEPATH_H
-#include <fs.h>
+#include <util/fs.h>
/**
* Helper function for getting a unique path
diff --git a/src/util/readwritefile.cpp b/src/util/readwritefile.cpp
index cc555adf45..773d7ad1cc 100644
--- a/src/util/readwritefile.cpp
+++ b/src/util/readwritefile.cpp
@@ -5,7 +5,7 @@
#include <util/readwritefile.h>
-#include <fs.h>
+#include <util/fs.h>
#include <algorithm>
#include <cstdio>
diff --git a/src/util/readwritefile.h b/src/util/readwritefile.h
index 73437baf1b..6ddfcb4f35 100644
--- a/src/util/readwritefile.h
+++ b/src/util/readwritefile.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_READWRITEFILE_H
#define BITCOIN_UTIL_READWRITEFILE_H
-#include <fs.h>
+#include <util/fs.h>
#include <limits>
#include <string>
diff --git a/src/util/settings.cpp b/src/util/settings.cpp
index a2e30098dc..bb257c0584 100644
--- a/src/util/settings.cpp
+++ b/src/util/settings.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
+#include <util/fs.h>
#include <util/settings.h>
#include <tinyformat.h>
diff --git a/src/util/settings.h b/src/util/settings.h
index b0d8acb711..27e87a4751 100644
--- a/src/util/settings.h
+++ b/src/util/settings.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_SETTINGS_H
#define BITCOIN_UTIL_SETTINGS_H
-#include <fs.h>
+#include <util/fs.h>
#include <map>
#include <string>
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 98e89f82e7..630eff99e0 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -6,9 +6,10 @@
#include <util/system.h>
#include <chainparamsbase.h>
-#include <fs.h>
#include <sync.h>
#include <util/check.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/getuniquepath.h>
#include <util/strencodings.h>
#include <util/string.h>
@@ -22,17 +23,6 @@
#endif
#ifndef WIN32
-// for posix_fallocate, in configure.ac we check if it is present after this
-#ifdef __linux__
-
-#ifdef _POSIX_C_SOURCE
-#undef _POSIX_C_SOURCE
-#endif
-
-#define _POSIX_C_SOURCE 200112L
-
-#endif // __linux__
-
#include <algorithm>
#include <cassert>
#include <fcntl.h>
@@ -44,7 +34,6 @@
#include <codecvt>
-#include <io.h> /* for _commit */
#include <shellapi.h>
#include <shlobj.h>
#endif
@@ -72,78 +61,6 @@ const char * const BITCOIN_SETTINGS_FILENAME = "settings.json";
ArgsManager gArgs;
-/** Mutex to protect dir_locks. */
-static GlobalMutex cs_dir_locks;
-/** A map that contains all the currently held directory locks. After
- * successful locking, these will be held here until the global destructor
- * cleans them up and thus automatically unlocks them, or ReleaseDirectoryLocks
- * is called.
- */
-static std::map<std::string, std::unique_ptr<fsbridge::FileLock>> dir_locks GUARDED_BY(cs_dir_locks);
-
-bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only)
-{
- LOCK(cs_dir_locks);
- fs::path pathLockFile = directory / lockfile_name;
-
- // If a lock for this directory already exists in the map, don't try to re-lock it
- if (dir_locks.count(fs::PathToString(pathLockFile))) {
- return true;
- }
-
- // Create empty lock file if it doesn't exist.
- FILE* file = fsbridge::fopen(pathLockFile, "a");
- if (file) fclose(file);
- auto lock = std::make_unique<fsbridge::FileLock>(pathLockFile);
- if (!lock->TryLock()) {
- return error("Error while attempting to lock directory %s: %s", fs::PathToString(directory), lock->GetReason());
- }
- if (!probe_only) {
- // Lock successful and we're not just probing, put it into the map
- dir_locks.emplace(fs::PathToString(pathLockFile), std::move(lock));
- }
- return true;
-}
-
-void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name)
-{
- LOCK(cs_dir_locks);
- dir_locks.erase(fs::PathToString(directory / lockfile_name));
-}
-
-void ReleaseDirectoryLocks()
-{
- LOCK(cs_dir_locks);
- dir_locks.clear();
-}
-
-bool DirIsWritable(const fs::path& directory)
-{
- fs::path tmpFile = GetUniquePath(directory);
-
- FILE* file = fsbridge::fopen(tmpFile, "a");
- if (!file) return false;
-
- fclose(file);
- remove(tmpFile);
-
- return true;
-}
-
-bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes)
-{
- constexpr uint64_t min_disk_space = 52428800; // 50 MiB
-
- uint64_t free_bytes_available = fs::space(dir).available;
- return free_bytes_available >= min_disk_space + additional_bytes;
-}
-
-std::streampos GetFileSize(const char* path, std::streamsize max) {
- std::ifstream file{path, std::ios::binary};
- file.ignore(max);
- return file.gcount();
-}
-
/**
* Interpret a string argument as a boolean.
*
@@ -1091,182 +1008,6 @@ void ArgsManager::LogArgs() const
logArgsPrefix("Command-line arg:", "", m_settings.command_line_options);
}
-bool RenameOver(fs::path src, fs::path dest)
-{
-#ifdef __MINGW64__
- // This is a workaround for a bug in libstdc++ which
- // implements std::filesystem::rename with _wrename function.
- // This bug has been fixed in upstream:
- // - GCC 10.3: 8dd1c1085587c9f8a21bb5e588dfe1e8cdbba79e
- // - GCC 11.1: 1dfd95f0a0ca1d9e6cbc00e6cbfd1fa20a98f312
- // For more details see the commits mentioned above.
- return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(),
- MOVEFILE_REPLACE_EXISTING) != 0;
-#else
- std::error_code error;
- fs::rename(src, dest, error);
- return !error;
-#endif
-}
-
-/**
- * Ignores exceptions thrown by create_directories if the requested directory exists.
- * Specifically handles case where path p exists, but it wasn't possible for the user to
- * write to the parent directory.
- */
-bool TryCreateDirectories(const fs::path& p)
-{
- try
- {
- return fs::create_directories(p);
- } catch (const fs::filesystem_error&) {
- if (!fs::exists(p) || !fs::is_directory(p))
- throw;
- }
-
- // create_directories didn't create the directory, it had to have existed already
- return false;
-}
-
-bool FileCommit(FILE *file)
-{
- if (fflush(file) != 0) { // harmless if redundantly called
- LogPrintf("%s: fflush failed: %d\n", __func__, errno);
- return false;
- }
-#ifdef WIN32
- HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
- if (FlushFileBuffers(hFile) == 0) {
- LogPrintf("%s: FlushFileBuffers failed: %d\n", __func__, GetLastError());
- return false;
- }
-#elif defined(MAC_OSX) && defined(F_FULLFSYNC)
- if (fcntl(fileno(file), F_FULLFSYNC, 0) == -1) { // Manpage says "value other than -1" is returned on success
- LogPrintf("%s: fcntl F_FULLFSYNC failed: %d\n", __func__, errno);
- return false;
- }
-#elif HAVE_FDATASYNC
- if (fdatasync(fileno(file)) != 0 && errno != EINVAL) { // Ignore EINVAL for filesystems that don't support sync
- LogPrintf("%s: fdatasync failed: %d\n", __func__, errno);
- return false;
- }
-#else
- if (fsync(fileno(file)) != 0 && errno != EINVAL) {
- LogPrintf("%s: fsync failed: %d\n", __func__, errno);
- return false;
- }
-#endif
- return true;
-}
-
-void DirectoryCommit(const fs::path &dirname)
-{
-#ifndef WIN32
- FILE* file = fsbridge::fopen(dirname, "r");
- if (file) {
- fsync(fileno(file));
- fclose(file);
- }
-#endif
-}
-
-bool TruncateFile(FILE *file, unsigned int length) {
-#if defined(WIN32)
- return _chsize(_fileno(file), length) == 0;
-#else
- return ftruncate(fileno(file), length) == 0;
-#endif
-}
-
-/**
- * this function tries to raise the file descriptor limit to the requested number.
- * It returns the actual file descriptor limit (which may be more or less than nMinFD)
- */
-int RaiseFileDescriptorLimit(int nMinFD) {
-#if defined(WIN32)
- return 2048;
-#else
- struct rlimit limitFD;
- if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
- if (limitFD.rlim_cur < (rlim_t)nMinFD) {
- limitFD.rlim_cur = nMinFD;
- if (limitFD.rlim_cur > limitFD.rlim_max)
- limitFD.rlim_cur = limitFD.rlim_max;
- setrlimit(RLIMIT_NOFILE, &limitFD);
- getrlimit(RLIMIT_NOFILE, &limitFD);
- }
- return limitFD.rlim_cur;
- }
- return nMinFD; // getrlimit failed, assume it's fine
-#endif
-}
-
-/**
- * this function tries to make a particular range of a file allocated (corresponding to disk space)
- * it is advisory, and the range specified in the arguments will never contain live data
- */
-void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
-#if defined(WIN32)
- // Windows-specific version
- HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
- LARGE_INTEGER nFileSize;
- int64_t nEndPos = (int64_t)offset + length;
- nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
- nFileSize.u.HighPart = nEndPos >> 32;
- SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
- SetEndOfFile(hFile);
-#elif defined(MAC_OSX)
- // OSX specific version
- // NOTE: Contrary to other OS versions, the OSX version assumes that
- // NOTE: offset is the size of the file.
- fstore_t fst;
- fst.fst_flags = F_ALLOCATECONTIG;
- fst.fst_posmode = F_PEOFPOSMODE;
- fst.fst_offset = 0;
- fst.fst_length = length; // mac os fst_length takes the # of free bytes to allocate, not desired file size
- fst.fst_bytesalloc = 0;
- if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
- fst.fst_flags = F_ALLOCATEALL;
- fcntl(fileno(file), F_PREALLOCATE, &fst);
- }
- ftruncate(fileno(file), static_cast<off_t>(offset) + length);
-#else
- #if defined(HAVE_POSIX_FALLOCATE)
- // Version using posix_fallocate
- off_t nEndPos = (off_t)offset + length;
- if (0 == posix_fallocate(fileno(file), 0, nEndPos)) return;
- #endif
- // Fallback version
- // TODO: just write one byte per block
- static const char buf[65536] = {};
- if (fseek(file, offset, SEEK_SET)) {
- return;
- }
- while (length > 0) {
- unsigned int now = 65536;
- if (length < now)
- now = length;
- fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
- length -= now;
- }
-#endif
-}
-
-#ifdef WIN32
-fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
-{
- WCHAR pszPath[MAX_PATH] = L"";
-
- if(SHGetSpecialFolderPathW(nullptr, pszPath, nFolder, fCreate))
- {
- return fs::path(pszPath);
- }
-
- LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n");
- return fs::path("");
-}
-#endif
-
#ifndef WIN32
std::string ShellEscape(const std::string& arg)
{
@@ -1290,7 +1031,6 @@ void runCommand(const std::string& strCommand)
}
#endif
-
void SetupEnvironment()
{
#ifdef HAVE_MALLOPT_ARENA_MAX
diff --git a/src/util/system.h b/src/util/system.h
index 7292262bea..ff3155b498 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -14,11 +14,11 @@
#include <config/bitcoin-config.h>
#endif
-#include <compat/compat.h>
#include <compat/assumptions.h>
-#include <fs.h>
+#include <compat/compat.h>
#include <logging.h>
#include <sync.h>
+#include <util/fs.h>
#include <util/settings.h>
#include <util/time.h>
@@ -42,55 +42,9 @@ extern const char * const BITCOIN_SETTINGS_FILENAME;
void SetupEnvironment();
bool SetupNetworking();
-
-/**
- * Ensure file contents are fully committed to disk, using a platform-specific
- * feature analogous to fsync().
- */
-bool FileCommit(FILE *file);
-
-/**
- * Sync directory contents. This is required on some environments to ensure that
- * newly created files are committed to disk.
- */
-void DirectoryCommit(const fs::path &dirname);
-
-bool TruncateFile(FILE *file, unsigned int length);
-int RaiseFileDescriptorLimit(int nMinFD);
-void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
-
-/**
- * Rename src to dest.
- * @return true if the rename was successful.
- */
-[[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
-
-bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only=false);
-void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
-bool DirIsWritable(const fs::path& directory);
-bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
-
-/** Get the size of a file by scanning it.
- *
- * @param[in] path The file path
- * @param[in] max Stop seeking beyond this limit
- * @return The file size or max
- */
-std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
-
-/** Release all directory locks. This is used for unit testing only, at runtime
- * the global destructor will take care of the locks.
- */
-void ReleaseDirectoryLocks();
-
-bool TryCreateDirectories(const fs::path& p);
-fs::path GetDefaultDataDir();
// Return true if -datadir option points to a valid directory or is not specified.
bool CheckDataDirOption(const ArgsManager& args);
fs::path GetConfigFile(const ArgsManager& args, const fs::path& configuration_file_path);
-#ifdef WIN32
-fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
-#endif
#ifndef WIN32
std::string ShellEscape(const std::string& arg);
#endif
diff --git a/src/validation.cpp b/src/validation.cpp
index e82fead89e..1fd8f0e326 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -19,7 +19,6 @@
#include <consensus/validation.h>
#include <cuckoocache.h>
#include <flatfile.h>
-#include <fs.h>
#include <hash.h>
#include <kernel/chainparams.h>
#include <kernel/mempool_entry.h>
@@ -46,6 +45,8 @@
#include <uint256.h>
#include <undo.h>
#include <util/check.h> // For NDEBUG compile time check
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/hasher.h>
#include <util/moneystr.h>
#include <util/rbf.h>
diff --git a/src/validation.h b/src/validation.h
index 0044004b79..fd0e2115f7 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -15,7 +15,6 @@
#include <chain.h>
#include <consensus/amount.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <kernel/chainparams.h>
#include <kernel/chainstatemanager_opts.h>
#include <kernel/cs_main.h> // IWYU pragma: export
@@ -30,6 +29,7 @@
#include <txmempool.h> // For CTxMemPool::cs
#include <uint256.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/hasher.h>
#include <util/translation.h>
#include <versionbits.h>
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 4d3285333f..5fafd478ee 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -4,11 +4,12 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <compat/compat.h>
-#include <fs.h>
+#include <util/fs.h>
#include <wallet/bdb.h>
#include <wallet/db.h>
#include <util/check.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
#include <util/translation.h>
diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h
index 06c98972b0..fbec0bb90b 100644
--- a/src/wallet/bdb.h
+++ b/src/wallet/bdb.h
@@ -7,9 +7,9 @@
#define BITCOIN_WALLET_BDB_H
#include <clientversion.h>
-#include <fs.h>
#include <serialize.h>
#include <streams.h>
+#include <util/fs.h>
#include <util/system.h>
#include <wallet/db.h>
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 8e79ee678e..92e1d61ac4 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -4,8 +4,8 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
-#include <fs.h>
#include <logging.h>
+#include <util/fs.h>
#include <util/system.h>
#include <wallet/db.h>
diff --git a/src/wallet/db.h b/src/wallet/db.h
index d4c590fac7..2da94885be 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -7,9 +7,9 @@
#define BITCOIN_WALLET_DB_H
#include <clientversion.h>
-#include <fs.h>
#include <streams.h>
#include <support/allocators/secure.h>
+#include <util/fs.h>
#include <atomic>
#include <memory>
diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
index 69208c19dc..31b6eb4ae1 100644
--- a/src/wallet/dump.cpp
+++ b/src/wallet/dump.cpp
@@ -4,7 +4,7 @@
#include <wallet/dump.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/translation.h>
#include <wallet/wallet.h>
diff --git a/src/wallet/dump.h b/src/wallet/dump.h
index ff0d94e4b2..5034f95479 100644
--- a/src/wallet/dump.h
+++ b/src/wallet/dump.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_WALLET_DUMP_H
#define BITCOIN_WALLET_DUMP_H
-#include <fs.h>
+#include <util/fs.h>
#include <string>
#include <vector>
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index 8c60a2da72..2103fc64e4 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -5,10 +5,10 @@
#include <wallet/load.h>
-#include <fs.h>
#include <interfaces/chain.h>
#include <scheduler.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index 9b6b3d629c..f4ea66c833 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -5,7 +5,6 @@
#include <chain.h>
#include <clientversion.h>
#include <core_io.h>
-#include <fs.h>
#include <hash.h>
#include <interfaces/chain.h>
#include <key_io.h>
@@ -17,6 +16,7 @@
#include <sync.h>
#include <uint256.h>
#include <util/bip32.h>
+#include <util/fs.h>
#include <util/time.h>
#include <util/translation.h>
#include <wallet/rpc/util.h>
diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp
index e2b4dbf4c2..06c8c8bb37 100644
--- a/src/wallet/salvage.cpp
+++ b/src/wallet/salvage.cpp
@@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <streams.h>
+#include <util/fs.h>
#include <util/translation.h>
#include <wallet/bdb.h>
#include <wallet/salvage.h>
diff --git a/src/wallet/salvage.h b/src/wallet/salvage.h
index ce918aec2d..fbf152ec79 100644
--- a/src/wallet/salvage.h
+++ b/src/wallet/salvage.h
@@ -6,8 +6,8 @@
#ifndef BITCOIN_WALLET_SALVAGE_H
#define BITCOIN_WALLET_SALVAGE_H
-#include <fs.h>
#include <streams.h>
+#include <util/fs.h>
class ArgsManager;
struct bilingual_str;
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
index 8d8a7ab2a2..d6259e095e 100644
--- a/src/wallet/sqlite.cpp
+++ b/src/wallet/sqlite.cpp
@@ -8,8 +8,8 @@
#include <crypto/common.h>
#include <logging.h>
#include <sync.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <util/translation.h>
#include <wallet/db.h>
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp
index 7e26656b86..7761308bbc 100644
--- a/src/wallet/test/db_tests.cpp
+++ b/src/wallet/test/db_tests.cpp
@@ -4,8 +4,8 @@
#include <boost/test/unit_test.hpp>
-#include <fs.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <wallet/bdb.h>
#include <fstream>
diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
index 60b1bab8ac..1db2a06bf8 100644
--- a/src/wallet/test/init_test_fixture.cpp
+++ b/src/wallet/test/init_test_fixture.cpp
@@ -2,9 +2,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <univalue.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/system.h>
#include <fstream>
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index ef8fb29e64..50405b78fe 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -11,7 +11,6 @@
#include <consensus/consensus.h>
#include <consensus/validation.h>
#include <external_signer.h>
-#include <fs.h>
#include <interfaces/chain.h>
#include <interfaces/wallet.h>
#include <key.h>
@@ -32,6 +31,8 @@
#include <util/check.h>
#include <util/error.h>
#include <util/fees.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/moneystr.h>
#include <util/rbf.h>
#include <util/string.h>
@@ -39,8 +40,8 @@
#include <util/translation.h>
#include <wallet/coincontrol.h>
#include <wallet/context.h>
-#include <wallet/fees.h>
#include <wallet/external_signer_scriptpubkeyman.h>
+#include <wallet/fees.h>
#include <univalue.h>
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index e8c18dbb67..23c2de8191 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -7,7 +7,6 @@
#define BITCOIN_WALLET_WALLET_H
#include <consensus/amount.h>
-#include <fs.h>
#include <interfaces/chain.h>
#include <interfaces/handler.h>
#include <logging.h>
@@ -15,6 +14,7 @@
#include <policy/feerate.h>
#include <psbt.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/hasher.h>
#include <util/message.h>
#include <util/result.h>
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 2cd35ae40e..3c0ed21b66 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -5,12 +5,12 @@
#include <wallet/walletdb.h>
-#include <fs.h>
#include <key_io.h>
#include <protocol.h>
#include <serialize.h>
#include <sync.h>
#include <util/bip32.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/time.h>
#include <util/translation.h>
diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp
index f389676204..acd817a311 100644
--- a/src/wallet/wallettool.cpp
+++ b/src/wallet/wallettool.cpp
@@ -8,7 +8,7 @@
#include <wallet/wallettool.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/translation.h>
#include <wallet/dump.h>
diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h
index 8434d64fb5..f639078de5 100644
--- a/src/wallet/walletutil.h
+++ b/src/wallet/walletutil.h
@@ -5,8 +5,8 @@
#ifndef BITCOIN_WALLET_WALLETUTIL_H
#define BITCOIN_WALLET_WALLETUTIL_H
-#include <fs.h>
#include <script/descriptor.h>
+#include <util/fs.h>
#include <vector>