diff --git a/src/query/frontend/ast/ast.hpp b/src/query/frontend/ast/ast.hpp
index 161903335..c9f27da66 100644
--- a/src/query/frontend/ast/ast.hpp
+++ b/src/query/frontend/ast/ast.hpp
@@ -2898,7 +2898,7 @@ class LockPathQuery : public memgraph::query::Query {
   static const utils::TypeInfo kType;
   const utils::TypeInfo &GetTypeInfo() const override { return kType; }
 
-  enum class Action { LOCK_PATH, UNLOCK_PATH };
+  enum class Action { LOCK_PATH, UNLOCK_PATH, STATUS };
 
   LockPathQuery() = default;
 
diff --git a/src/query/frontend/ast/cypher_main_visitor.cpp b/src/query/frontend/ast/cypher_main_visitor.cpp
index 82cae5f55..502d6ca5d 100644
--- a/src/query/frontend/ast/cypher_main_visitor.cpp
+++ b/src/query/frontend/ast/cypher_main_visitor.cpp
@@ -328,7 +328,9 @@ antlrcpp::Any CypherMainVisitor::visitShowReplicas(MemgraphCypher::ShowReplicasC
 
 antlrcpp::Any CypherMainVisitor::visitLockPathQuery(MemgraphCypher::LockPathQueryContext *ctx) {
   auto *lock_query = storage_->Create<LockPathQuery>();
-  if (ctx->LOCK()) {
+  if (ctx->STATUS()) {
+    lock_query->action_ = LockPathQuery::Action::STATUS;
+  } else if (ctx->LOCK()) {
     lock_query->action_ = LockPathQuery::Action::LOCK_PATH;
   } else if (ctx->UNLOCK()) {
     lock_query->action_ = LockPathQuery::Action::UNLOCK_PATH;
diff --git a/src/query/frontend/opencypher/grammar/MemgraphCypher.g4 b/src/query/frontend/opencypher/grammar/MemgraphCypher.g4
index 1a7a7e803..9bb1bfabc 100644
--- a/src/query/frontend/opencypher/grammar/MemgraphCypher.g4
+++ b/src/query/frontend/opencypher/grammar/MemgraphCypher.g4
@@ -91,6 +91,7 @@ memgraphCypherKeyword : cypherKeyword
                       | SNAPSHOT
                       | START
                       | STATS
+                      | STATUS
                       | STORAGE
                       | STREAM
                       | STREAMS
@@ -335,7 +336,7 @@ dropReplica : DROP REPLICA replicaName ;
 
 showReplicas  : SHOW REPLICAS ;
 
-lockPathQuery : ( LOCK | UNLOCK ) DATA DIRECTORY ;
+lockPathQuery : ( LOCK | UNLOCK ) DATA DIRECTORY | DATA DIRECTORY LOCK STATUS;
 
 freeMemoryQuery : FREE MEMORY ;
 
diff --git a/src/query/frontend/opencypher/grammar/MemgraphCypherLexer.g4 b/src/query/frontend/opencypher/grammar/MemgraphCypherLexer.g4
index 931960583..862682d6e 100644
--- a/src/query/frontend/opencypher/grammar/MemgraphCypherLexer.g4
+++ b/src/query/frontend/opencypher/grammar/MemgraphCypherLexer.g4
@@ -107,6 +107,7 @@ SNAPSHOT                : S N A P S H O T ;
 START                   : S T A R T ;
 STATISTICS              : S T A T I S T I C S ;
 STATS                   : S T A T S ;
+STATUS                  : S T A T U S ;
 STOP                    : S T O P ;
 STORAGE                 : S T O R A G E;
 STORAGE_MODE            : S T O R A G E UNDERSCORE MODE;
diff --git a/src/query/frontend/stripped_lexer_constants.hpp b/src/query/frontend/stripped_lexer_constants.hpp
index 076fe1186..456c704e6 100644
--- a/src/query/frontend/stripped_lexer_constants.hpp
+++ b/src/query/frontend/stripped_lexer_constants.hpp
@@ -145,6 +145,7 @@ const trie::Trie kKeywords = {"union",
                               "drop",
                               "show",
                               "stats",
+                              "status",
                               "unique",
                               "explain",
                               "profile",
@@ -212,6 +213,10 @@ const trie::Trie kKeywords = {"union",
                               "off",
                               "in_memory_transactional",
                               "in_memory_analytical",
+                              "data",
+                              "directory",
+                              "lock",
+                              "unlock"
                               "build"};
 
 // Unicode codepoints that are allowed at the start of the unescaped name.
diff --git a/src/query/interpreter.cpp b/src/query/interpreter.cpp
index 8d58b3093..3e94fa0e8 100644
--- a/src/query/interpreter.cpp
+++ b/src/query/interpreter.cpp
@@ -1780,25 +1780,49 @@ PreparedQuery PrepareLockPathQuery(ParsedQuery parsed_query, bool in_explicit_tr
 
   auto *lock_path_query = utils::Downcast<LockPathQuery>(parsed_query.query);
 
-  return PreparedQuery{{},
-                       std::move(parsed_query.required_privileges),
-                       [interpreter_context, action = lock_path_query->action_](
-                           AnyStream *stream, std::optional<int> n) -> std::optional<QueryHandlerResult> {
-                         switch (action) {
-                           case LockPathQuery::Action::LOCK_PATH:
-                             if (!interpreter_context->db->LockPath()) {
-                               throw QueryRuntimeException("Failed to lock the data directory");
-                             }
-                             break;
-                           case LockPathQuery::Action::UNLOCK_PATH:
-                             if (!interpreter_context->db->UnlockPath()) {
-                               throw QueryRuntimeException("Failed to unlock the data directory");
-                             }
-                             break;
-                         }
-                         return QueryHandlerResult::COMMIT;
-                       },
-                       RWType::NONE};
+  return PreparedQuery{
+      {"STATUS"},
+      std::move(parsed_query.required_privileges),
+      [interpreter_context, action = lock_path_query->action_](
+          AnyStream *stream, std::optional<int> n) -> std::optional<QueryHandlerResult> {
+        std::vector<std::vector<TypedValue>> status;
+        std::string res;
+
+        switch (action) {
+          case LockPathQuery::Action::LOCK_PATH: {
+            const auto lock_success = interpreter_context->db->LockPath();
+            if (lock_success.HasError()) [[unlikely]] {
+              throw QueryRuntimeException("Failed to lock the data directory");
+            }
+            res = lock_success.GetValue() ? "Data directory is now locked." : "Data directory is already locked.";
+            break;
+          }
+          case LockPathQuery::Action::UNLOCK_PATH: {
+            const auto unlock_success = interpreter_context->db->UnlockPath();
+            if (unlock_success.HasError()) [[unlikely]] {
+              throw QueryRuntimeException("Failed to unlock the data directory");
+            }
+            res = unlock_success.GetValue() ? "Data directory is now unlocked." : "Data directory is already unlocked.";
+            break;
+          }
+          case LockPathQuery::Action::STATUS: {
+            const auto locked_status = interpreter_context->db->IsPathLocked();
+            if (locked_status.HasError()) [[unlikely]] {
+              throw QueryRuntimeException("Failed to access the data directory");
+            }
+            res = locked_status.GetValue() ? "Data directory is locked." : "Data directory is unlocked.";
+            break;
+          }
+        }
+
+        status.emplace_back(std::vector<TypedValue>{TypedValue(res)});
+        auto pull_plan = std::make_shared<PullPlanVector>(std::move(status));
+        if (pull_plan->Pull(stream, n)) {
+          return QueryHandlerResult::COMMIT;
+        }
+        return std::nullopt;
+      },
+      RWType::NONE};
 }
 
 PreparedQuery PrepareFreeMemoryQuery(ParsedQuery parsed_query, bool in_explicit_transaction,
diff --git a/src/storage/v2/replication/replication_client.cpp b/src/storage/v2/replication/replication_client.cpp
index e458a0f4d..310b3d912 100644
--- a/src/storage/v2/replication/replication_client.cpp
+++ b/src/storage/v2/replication/replication_client.cpp
@@ -399,7 +399,8 @@ std::vector<Storage::ReplicationClient::RecoveryStep> Storage::ReplicationClient
     // we cannot know if the difference is only in the current WAL or we need
     // to send the snapshot.
     if (latest_snapshot) {
-      locker_acc.AddPath(latest_snapshot->path);
+      const auto lock_success = locker_acc.AddPath(latest_snapshot->path);
+      MG_ASSERT(!lock_success.HasError(), "Tried to lock a nonexistant path.");
       recovery_steps.emplace_back(std::in_place_type_t<RecoverySnapshot>{}, std::move(latest_snapshot->path));
     }
     // if there are no finalized WAL files, snapshot left the current WAL
@@ -446,7 +447,8 @@ std::vector<Storage::ReplicationClient::RecoveryStep> Storage::ReplicationClient
       // We need to lock these files and add them to the chain
       for (auto result_wal_it = wal_files->begin() + distance_from_first; result_wal_it != wal_files->end();
            ++result_wal_it) {
-        locker_acc.AddPath(result_wal_it->path);
+        const auto lock_success = locker_acc.AddPath(result_wal_it->path);
+        MG_ASSERT(!lock_success.HasError(), "Tried to lock a nonexistant path.");
         wal_chain.push_back(std::move(result_wal_it->path));
       }
 
@@ -464,7 +466,8 @@ std::vector<Storage::ReplicationClient::RecoveryStep> Storage::ReplicationClient
   MG_ASSERT(latest_snapshot, "Invalid durability state, missing snapshot");
   // We didn't manage to find a WAL chain, we need to send the latest snapshot
   // with its WALs
-  locker_acc.AddPath(latest_snapshot->path);
+  const auto lock_success = locker_acc.AddPath(latest_snapshot->path);
+  MG_ASSERT(!lock_success.HasError(), "Tried to lock a nonexistant path.");
   recovery_steps.emplace_back(std::in_place_type_t<RecoverySnapshot>{}, std::move(latest_snapshot->path));
 
   std::vector<std::filesystem::path> recovery_wal_files;
@@ -483,13 +486,15 @@ std::vector<Storage::ReplicationClient::RecoveryStep> Storage::ReplicationClient
   }
 
   for (; wal_it != wal_files->end(); ++wal_it) {
-    locker_acc.AddPath(wal_it->path);
+    const auto lock_success = locker_acc.AddPath(wal_it->path);
+    MG_ASSERT(!lock_success.HasError(), "Tried to lock a nonexistant path.");
     recovery_wal_files.push_back(std::move(wal_it->path));
   }
 
   // We only have a WAL before the snapshot
   if (recovery_wal_files.empty()) {
-    locker_acc.AddPath(wal_files->back().path);
+    const auto lock_success = locker_acc.AddPath(wal_files->back().path);
+    MG_ASSERT(!lock_success.HasError(), "Tried to lock a nonexistant path.");
     recovery_wal_files.push_back(std::move(wal_files->back().path));
   }
 
diff --git a/src/storage/v2/storage.cpp b/src/storage/v2/storage.cpp
index 4ebc144c0..f558cc5ac 100644
--- a/src/storage/v2/storage.cpp
+++ b/src/storage/v2/storage.cpp
@@ -1980,16 +1980,23 @@ utils::BasicResult<Storage::CreateSnapshotError> Storage::CreateSnapshot(std::op
   return CreateSnapshotError::ReachedMaxNumTries;
 }
 
-bool Storage::LockPath() {
+utils::FileRetainer::FileLockerAccessor::ret_type Storage::IsPathLocked() {
+  auto locker_accessor = global_locker_.Access();
+  return locker_accessor.IsPathLocked(config_.durability.storage_directory);
+}
+
+utils::FileRetainer::FileLockerAccessor::ret_type Storage::LockPath() {
   auto locker_accessor = global_locker_.Access();
   return locker_accessor.AddPath(config_.durability.storage_directory);
 }
 
-bool Storage::UnlockPath() {
+utils::FileRetainer::FileLockerAccessor::ret_type Storage::UnlockPath() {
   {
     auto locker_accessor = global_locker_.Access();
-    if (!locker_accessor.RemovePath(config_.durability.storage_directory)) {
-      return false;
+    const auto ret = locker_accessor.RemovePath(config_.durability.storage_directory);
+    if (ret.HasError() || !ret.GetValue()) {
+      // Exit without cleaning the queue
+      return ret;
     }
   }
 
diff --git a/src/storage/v2/storage.hpp b/src/storage/v2/storage.hpp
index 60541ed63..7fd816530 100644
--- a/src/storage/v2/storage.hpp
+++ b/src/storage/v2/storage.hpp
@@ -39,6 +39,7 @@
 #include "storage/v2/vertex_accessor.hpp"
 #include "utils/file_locker.hpp"
 #include "utils/on_scope_exit.hpp"
+#include "utils/result.hpp"
 #include "utils/rw_lock.hpp"
 #include "utils/scheduler.hpp"
 #include "utils/skip_list.hpp"
@@ -467,8 +468,9 @@ class Storage final {
 
   StorageInfo GetInfo() const;
 
-  bool LockPath();
-  bool UnlockPath();
+  utils::FileRetainer::FileLockerAccessor::ret_type IsPathLocked();
+  utils::FileRetainer::FileLockerAccessor::ret_type LockPath();
+  utils::FileRetainer::FileLockerAccessor::ret_type UnlockPath();
 
   bool SetReplicaRole(io::network::Endpoint endpoint, const replication::ReplicationServerConfig &config = {});
 
diff --git a/src/utils/file_locker.cpp b/src/utils/file_locker.cpp
index 7e8b6f6f8..39af7b9d9 100644
--- a/src/utils/file_locker.cpp
+++ b/src/utils/file_locker.cpp
@@ -1,4 +1,4 @@
-// Copyright 2022 Memgraph Ltd.
+// Copyright 2023 Memgraph Ltd.
 //
 // Use of this software is governed by the Business Source License
 // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -80,13 +80,14 @@ void FileRetainer::CleanQueue() {
 }
 
 ////// LockerEntry //////
-void FileRetainer::LockerEntry::LockPath(const std::filesystem::path &path) {
+bool FileRetainer::LockerEntry::LockPath(const std::filesystem::path &path) {
   auto absolute_path = std::filesystem::absolute(path);
   if (std::filesystem::is_directory(absolute_path)) {
-    directories_.emplace(std::move(absolute_path));
-    return;
+    const auto [itr, success] = directories_.emplace(std::move(absolute_path));
+    return success;
   }
-  files_.emplace(std::move(absolute_path));
+  const auto [itr, success] = files_.emplace(std::move(absolute_path));
+  return success;
 }
 
 bool FileRetainer::LockerEntry::RemovePath(const std::filesystem::path &path) {
@@ -140,13 +141,27 @@ FileRetainer::FileLockerAccessor::FileLockerAccessor(FileRetainer *retainer, siz
   file_retainer_->active_accessors_.fetch_add(1);
 }
 
-bool FileRetainer::FileLockerAccessor::AddPath(const std::filesystem::path &path) {
-  if (!std::filesystem::exists(path)) return false;
-  file_retainer_->lockers_.WithLock([&](auto &lockers) { lockers[locker_id_].LockPath(path); });
-  return true;
+FileRetainer::FileLockerAccessor::ret_type FileRetainer::FileLockerAccessor::IsPathLocked(
+    const std::filesystem::path &path) {
+  if (!std::filesystem::exists(path)) {
+    return Error::NonexistentPath;
+  }
+  return file_retainer_->FileLocked(std::filesystem::absolute(path));
 }
 
-bool FileRetainer::FileLockerAccessor::RemovePath(const std::filesystem::path &path) {
+FileRetainer::FileLockerAccessor::ret_type FileRetainer::FileLockerAccessor::AddPath(
+    const std::filesystem::path &path) {
+  if (!std::filesystem::exists(path)) {
+    return Error::NonexistentPath;
+  }
+  return file_retainer_->lockers_.WithLock([&](auto &lockers) { return lockers[locker_id_].LockPath(path); });
+}
+
+FileRetainer::FileLockerAccessor::ret_type FileRetainer::FileLockerAccessor::RemovePath(
+    const std::filesystem::path &path) {
+  if (!std::filesystem::exists(path)) {
+    return Error::NonexistentPath;
+  }
   return file_retainer_->lockers_.WithLock([&](auto &lockers) { return lockers[locker_id_].RemovePath(path); });
 }
 
diff --git a/src/utils/file_locker.hpp b/src/utils/file_locker.hpp
index 1134bd73e..5fd96e159 100644
--- a/src/utils/file_locker.hpp
+++ b/src/utils/file_locker.hpp
@@ -1,4 +1,4 @@
-// Copyright 2022 Memgraph Ltd.
+// Copyright 2023 Memgraph Ltd.
 //
 // Use of this software is governed by the Business Source License
 // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -18,6 +18,7 @@
 #include <unordered_map>
 
 #include "utils/file.hpp"
+#include "utils/result.hpp"
 #include "utils/rw_lock.hpp"
 #include "utils/spin_lock.hpp"
 #include "utils/synchronized.hpp"
@@ -114,15 +115,26 @@ class FileRetainer {
   struct FileLockerAccessor {
     friend FileLocker;
 
+    enum class Error : uint8_t {
+      NonexistentPath = 0,
+    };
+
+    using ret_type = utils::BasicResult<FileRetainer::FileLockerAccessor::Error, bool>;
+
+    /**
+     * Checks if a single path is in the current locker.
+     */
+    ret_type IsPathLocked(const std::filesystem::path &path);
+
     /**
      * Add a single path to the current locker.
      */
-    bool AddPath(const std::filesystem::path &path);
+    ret_type AddPath(const std::filesystem::path &path);
 
     /**
      * Remove a single path form the current locker.
      */
-    bool RemovePath(const std::filesystem::path &path);
+    ret_type RemovePath(const std::filesystem::path &path);
 
     FileLockerAccessor(const FileLockerAccessor &) = delete;
     FileLockerAccessor(FileLockerAccessor &&) = default;
@@ -182,7 +194,7 @@ class FileRetainer {
 
   class LockerEntry {
    public:
-    void LockPath(const std::filesystem::path &path);
+    bool LockPath(const std::filesystem::path &path);
     bool RemovePath(const std::filesystem::path &path);
     [[nodiscard]] bool LocksFile(const std::filesystem::path &path) const;
 
diff --git a/tests/unit/cypher_main_visitor.cpp b/tests/unit/cypher_main_visitor.cpp
index fcd0e5d74..c87e000b6 100644
--- a/tests/unit/cypher_main_visitor.cpp
+++ b/tests/unit/cypher_main_visitor.cpp
@@ -3368,10 +3368,43 @@ TEST_P(CypherMainVisitorTest, TestLockPathQuery) {
       ASSERT_TRUE(parsed_query);
       EXPECT_EQ(parsed_query->action_, action);
     }
+
+    {
+      const std::string query = fmt::format("{} DATA DIRECTORY LOCK STATUS", command);
+      ASSERT_THROW(ast_generator.ParseQuery(query), SyntaxException);
+    }
+
+    {
+      const std::string query = fmt::format("{} DATA DIRECTORY STATUS", command);
+      ASSERT_THROW(ast_generator.ParseQuery(query), SyntaxException);
+    }
   };
 
   test_lock_path_query("LOCK", LockPathQuery::Action::LOCK_PATH);
   test_lock_path_query("UNLOCK", LockPathQuery::Action::UNLOCK_PATH);
+
+  // Status test
+  {
+    const std::string query = "DATA DIRECTORY LOCK";
+    ASSERT_THROW(ast_generator.ParseQuery(query), SyntaxException);
+  }
+
+  {
+    const std::string query = "DATA LOCK STATUS";
+    ASSERT_THROW(ast_generator.ParseQuery(query), SyntaxException);
+  }
+
+  {
+    const std::string query = "DIRECTORY LOCK STATUS";
+    ASSERT_THROW(ast_generator.ParseQuery(query), SyntaxException);
+  }
+
+  {
+    const std::string query = "DATA DIRECTORY LOCK STATUS";
+    auto *parsed_query = dynamic_cast<LockPathQuery *>(ast_generator.ParseQuery(query));
+    ASSERT_TRUE(parsed_query);
+    EXPECT_EQ(parsed_query->action_, LockPathQuery::Action::STATUS);
+  }
 }
 
 TEST_P(CypherMainVisitorTest, TestLoadCsvClause) {
diff --git a/tests/unit/utils_file_locker.cpp b/tests/unit/utils_file_locker.cpp
index 21c71b1a3..bd0778d49 100644
--- a/tests/unit/utils_file_locker.cpp
+++ b/tests/unit/utils_file_locker.cpp
@@ -1,4 +1,4 @@
-// Copyright 2022 Memgraph Ltd.
+// Copyright 2023 Memgraph Ltd.
 //
 // Use of this software is governed by the Business Source License
 // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -89,7 +89,8 @@ TEST_P(FileLockerParameterizedTest, DeleteWhileInLocker) {
     auto locker = file_retainer.AddLocker();
     {
       auto acc = locker.Access();
-      acc.AddPath(lock_absolute ? file_absolute : file);
+      const auto lock_success = acc.AddPath(lock_absolute ? file_absolute : file);
+      ASSERT_FALSE(lock_success.HasError());
     }
 
     file_retainer.DeleteFile(delete_absolute ? file_absolute : file);
@@ -133,7 +134,9 @@ TEST_P(FileLockerParameterizedTest, DirectoryLock) {
       auto locker = file_retainer.AddLocker();
       {
         auto acc = locker.Access();
-        acc.AddPath(lock_absolute ? std::filesystem::absolute(directory_to_lock) : directory_to_lock);
+        const auto lock_success =
+            acc.AddPath(lock_absolute ? std::filesystem::absolute(directory_to_lock) : directory_to_lock);
+        ASSERT_FALSE(lock_success.HasError());
       }
 
       file_retainer.DeleteFile(delete_absolute ? file_absolute : file);
@@ -165,7 +168,8 @@ TEST_P(FileLockerParameterizedTest, RemovePath) {
     auto locker = file_retainer.AddLocker();
     {
       auto acc = locker.Access();
-      acc.AddPath(lock_absolute ? file_absolute : file);
+      const auto lock_success = acc.AddPath(lock_absolute ? file_absolute : file);
+      ASSERT_FALSE(lock_success.HasError());
     }
 
     file_retainer.DeleteFile(delete_absolute ? file_absolute : file);
@@ -205,8 +209,10 @@ TEST_F(FileLockerTest, MultipleLockers) {
     auto locker = file_retainer.AddLocker();
     {
       auto acc = locker.Access();
-      acc.AddPath(file1);
-      acc.AddPath(common_file);
+      const auto lock_success1 = acc.AddPath(file1);
+      ASSERT_FALSE(lock_success1.HasError());
+      const auto lock_success2 = acc.AddPath(common_file);
+      ASSERT_FALSE(lock_success2.HasError());
     }
     std::this_thread::sleep_for(200ms);
   });
@@ -215,8 +221,10 @@ TEST_F(FileLockerTest, MultipleLockers) {
     auto locker = file_retainer.AddLocker();
     {
       auto acc = locker.Access();
-      acc.AddPath(file2);
-      acc.AddPath(common_file);
+      const auto lock_success1 = acc.AddPath(file2);
+      ASSERT_FALSE(lock_success1.HasError());
+      const auto lock_success2 = acc.AddPath(common_file);
+      ASSERT_FALSE(lock_success2.HasError());
     }
     std::this_thread::sleep_for(200ms);
   });
@@ -275,7 +283,8 @@ TEST_F(FileLockerTest, MultipleLockersAndDeleters) {
         auto acc = locker.Access();
         for (auto i = 0; i < file_access_num; ++i) {
           auto file = random_file();
-          if (acc.AddPath(file)) {
+          const auto res = acc.AddPath(file);
+          if (!res.HasError()) {
             ASSERT_TRUE(std::filesystem::exists(file));
             locked_files.emplace_back(std::move(file));
           } else {