From 37d8cc63df587443b55fb35d0858756f1f1ac62a Mon Sep 17 00:00:00 2001 From: zhangkaixiang Date: Sun, 12 Nov 2023 09:53:55 +0000 Subject: [PATCH] add database module and file operations helper Signed-off-by: zhangkaixiang --- services/cloudfiledaemon/BUILD.gn | 17 ++ .../include/cloud_disk/database_manager.h | 43 +++++ .../cloud_disk/file_operations_helper.h | 45 +++++ .../src/cloud_disk/database_manager.cpp | 42 +++++ .../src/cloud_disk/file_operations_helper.cpp | 156 ++++++++++++++++++ test/unittests/services_daemon/BUILD.gn | 32 ++++ 6 files changed, 335 insertions(+) create mode 100644 services/cloudfiledaemon/include/cloud_disk/database_manager.h create mode 100644 services/cloudfiledaemon/include/cloud_disk/file_operations_helper.h create mode 100644 services/cloudfiledaemon/src/cloud_disk/database_manager.cpp create mode 100644 services/cloudfiledaemon/src/cloud_disk/file_operations_helper.cpp diff --git a/services/cloudfiledaemon/BUILD.gn b/services/cloudfiledaemon/BUILD.gn index dd3ede85e..bf97f2ab3 100644 --- a/services/cloudfiledaemon/BUILD.gn +++ b/services/cloudfiledaemon/BUILD.gn @@ -23,12 +23,22 @@ ohos_shared_library("cloudfiledaemon") { } cloud_disk = [ + "src/cloud_disk/database_manager.cpp", "src/cloud_disk/file_operations_base.cpp", "src/cloud_disk/file_operations_cloud.cpp", + "src/cloud_disk/file_operations_helper.cpp", "src/cloud_disk/file_operations_local.cpp", "src/cloud_disk/fuse_operations.cpp", ] + clouddisk_database = [ + "${clouddisk_database_path}/src/clouddisk_rdbstore.cpp", + "${clouddisk_database_path}/src/file_column.cpp", + "${clouddisk_database_path}/src/clouddisk_rdb_utils.cpp", + ] + + media_library = [ "${media_library_path}/frameworks/innerkitsimpl/media_library_helper/src/mimetype_utils.cpp" ] + sources = [ "src/fuse_manager/fuse_manager.cpp", "src/ipc/cloud_daemon.cpp", @@ -36,6 +46,8 @@ ohos_shared_library("cloudfiledaemon") { ] sources += cloud_disk + sources += clouddisk_database + sources += media_library configs = [ "${utils_path}:compiler_configs" ] @@ -48,6 +60,10 @@ ohos_shared_library("cloudfiledaemon") { "${innerkits_native_path}/cloud_daemon_kit_inner", "${services_path}/cloudfiledaemon/include/cloud_disk/", "${services_path}/cloudsyncservice/include/data_sync/", + "${clouddisk_database_path}/include", + "${media_library_path}/frameworks/innerkitsimpl/media_library_helper/include", + "${media_library_path}/interfaces/inner_api/media_library_helper/include", + "${media_library_path}/frameworks/utils/include", ] deps = [ @@ -59,6 +75,7 @@ ohos_shared_library("cloudfiledaemon") { external_deps = [ "hilog:libhilog", "ipc:ipc_single", + "relational_store:native_rdb", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/services/cloudfiledaemon/include/cloud_disk/database_manager.h b/services/cloudfiledaemon/include/cloud_disk/database_manager.h new file mode 100644 index 000000000..98dd2a345 --- /dev/null +++ b/services/cloudfiledaemon/include/cloud_disk/database_manager.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CLOUD_FILE_DAEMON_CLOUD_DISK_DATABASE_MANAGER_H +#define CLOUD_FILE_DAEMON_CLOUD_DISK_DATABASE_MANAGER_H +#include +#include +#include +#include + +#include "clouddisk_rdbstore.h" + +namespace OHOS { +namespace FileManagement { +namespace CloudDisk { +class DatabaseManager final { +public: + static DatabaseManager &GetInstance(); + std::shared_ptr GetRdbStore(const std::string &bundleName, + int32_t userId); + DatabaseManager(const DatabaseManager&) = delete; + DatabaseManager& operator=(const DatabaseManager&) = delete; +private: + DatabaseManager() = default; + ~DatabaseManager() = default; + std::shared_mutex mapLock_; + std::unordered_map>rdbMap_; +}; +} // namespace CloudDisk +} // namespace FileManagement +} // namespace OHOS +#endif // CLOUD_FILE_DAEMON_CLOUD_DISK_DATABASE_MANAGER_H diff --git a/services/cloudfiledaemon/include/cloud_disk/file_operations_helper.h b/services/cloudfiledaemon/include/cloud_disk/file_operations_helper.h new file mode 100644 index 000000000..2d85a98f7 --- /dev/null +++ b/services/cloudfiledaemon/include/cloud_disk/file_operations_helper.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CLOUD_FILE_DAEMON_FILE_OPERATIONS_HELPER_H +#define CLOUD_FILE_DAEMON_FILE_OPERATIONS_HELPER_H + +#include "cloud_disk_inode.h" + +namespace OHOS { +namespace FileManagement { +namespace CloudDisk { +class FileOperationsHelper { +public: + static int32_t GetNextLayer(fuse_ino_t parent); + static std::string GetCloudDiskRootPath(int32_t userId); + static std::string GetCloudDiskLocalPath(int32_t userId, std::string fileName); + static void GetInodeAttr(std::shared_ptr ino, struct stat *statBuf); + static std::shared_ptr FindCloudDiskInode(struct CloudDiskFuseData *data, + const std::string &key); + static void AddDirEntry(fuse_req_t req, std::string &buf, size_t &size, const char *name, + std::shared_ptr ino); + static void FuseReplyLimited(fuse_req_t req, const char *buf, size_t bufSize, + off_t off, size_t maxSize); + static void PutCloudDiskInode(struct CloudDiskFuseData *data, + std::shared_ptr inoPtr, uint64_t num); + static std::shared_ptr GenerateCloudDiskInode(struct CloudDiskFuseData *data, + struct CloudDiskInode *parent, + const std::string &fileName, + const std::string &path); +}; +} // namespace CloudDisk +} // namespace FileManagement +} // namespace OHOS +#endif // CLOUD_FILE_DAEMON_FILE_OPERATIONS_HELPER_H diff --git a/services/cloudfiledaemon/src/cloud_disk/database_manager.cpp b/services/cloudfiledaemon/src/cloud_disk/database_manager.cpp new file mode 100644 index 000000000..65bc21e65 --- /dev/null +++ b/services/cloudfiledaemon/src/cloud_disk/database_manager.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "database_manager.h" + +namespace OHOS { +namespace FileManagement { +namespace CloudDisk { +using namespace std; +DatabaseManager &DatabaseManager::GetInstance() +{ + static DatabaseManager instance_; + return instance_; +} + +shared_ptr DatabaseManager::GetRdbStore(const string &bundleName, int32_t userId) +{ + std::unique_lock wLock(mapLock_, std::defer_lock); + string key = to_string(userId) + bundleName; + + wLock.lock(); + if (rdbMap_.find(key) == rdbMap_.end()) { + rdbMap_[key] = make_shared(bundleName, userId); + } + wLock.unlock(); + + return rdbMap_[key]; +} +} // namespace CloudDisk +} // namespace FileManagement +} // namespace OHOS diff --git a/services/cloudfiledaemon/src/cloud_disk/file_operations_helper.cpp b/services/cloudfiledaemon/src/cloud_disk/file_operations_helper.cpp new file mode 100644 index 000000000..1b56ba88e --- /dev/null +++ b/services/cloudfiledaemon/src/cloud_disk/file_operations_helper.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "file_operations_helper.h" + +#include + +#include "file_operations_cloud.h" +#include "file_operations_local.h" +#include "securec.h" +#include "utils_log.h" + +namespace OHOS { +namespace FileManagement { +namespace CloudDisk { +using namespace std; +namespace { + static const string LOCAL_PATH_DATA_SERVICE_EL2 = "/data/service/el2/"; + static const string LOCAL_PATH_HMDFS_CLOUD_DATA = "/hmdfs/cloud/data/"; + static const string LOCAL_PATH_HMDFS_CLOUD = "/hmdfs/cloud/"; +} + +string FileOperationsHelper::GetCloudDiskRootPath(int32_t userId) +{ + return LOCAL_PATH_DATA_SERVICE_EL2 + to_string(userId) + LOCAL_PATH_HMDFS_CLOUD; +} + +string FileOperationsHelper::GetCloudDiskLocalPath(int32_t userId, string fileName) +{ + if (fileName == "data") { + return LOCAL_PATH_DATA_SERVICE_EL2 + to_string(userId) + + LOCAL_PATH_HMDFS_CLOUD_DATA; + } else if (fileName == "/") { + return GetCloudDiskRootPath(userId); + } else { + return LOCAL_PATH_DATA_SERVICE_EL2 + to_string(userId) + + LOCAL_PATH_HMDFS_CLOUD_DATA + fileName; + } +} + +void FileOperationsHelper::GetInodeAttr(shared_ptr ino, struct stat *statBuf) +{ + statBuf->st_ino = reinterpret_cast(ino.get()); + statBuf->st_uid = ino->stat.st_uid; + statBuf->st_gid = ino->stat.st_gid; + statBuf->st_mtime = ino->stat.st_mtime; + statBuf->st_mode = ino->stat.st_mode; + statBuf->st_nlink = ino->stat.st_nlink; + if (statBuf->st_mode & S_IFREG) { + statBuf->st_size = ino->stat.st_size; + } +} + +int32_t FileOperationsHelper::GetNextLayer(fuse_ino_t ino) +{ + if (ino == FUSE_ROOT_ID) { + return CLOUD_DISK_INODE_ZERO_LAYER; + } + struct CloudDiskInode *inoPtr = reinterpret_cast(ino); + if (inoPtr->layer >= CLOUD_DISK_INODE_OTHER_LAYER) { + return CLOUD_DISK_INODE_OTHER_LAYER; + } else { + return inoPtr->layer + 1; + } +} + +shared_ptr FileOperationsHelper::FindCloudDiskInode(struct CloudDiskFuseData *data, + const string &key) +{ + shared_ptr ret; + shared_lock rLock(data->cacheLock, std::defer_lock); + rLock.lock(); + if (data->inodeCache.find(key) != data->inodeCache.end()) { + ret = data->inodeCache[key]; + } else { + ret = nullptr; + } + rLock.unlock(); + return ret; +} + +void FileOperationsHelper::AddDirEntry(fuse_req_t req, std::string &buf, size_t &size, const char *name, + std::shared_ptr ino) +{ + size_t oldSize = size; + size += fuse_add_direntry(req, NULL, 0, name, NULL, 0); + buf.resize(size); + fuse_add_direntry(req, &buf[oldSize], size - oldSize, name, &ino->stat, size); +} + +void FileOperationsHelper::FuseReplyLimited(fuse_req_t req, const char *buf, size_t bufSize, + off_t off, size_t maxSize) +{ + if (off < bufSize) { + size_t size = (bufSize - off) < maxSize ? (bufSize - off) : maxSize; + fuse_reply_buf(req, buf + off, size); + } else { + fuse_reply_buf(req, NULL, 0); + } +} + +shared_ptr FileOperationsHelper::GenerateCloudDiskInode(struct CloudDiskFuseData *data, + struct CloudDiskInode *parent, + const string &fileName, + const string &path) +{ + std::unique_lock wLock(data->cacheLock, std::defer_lock); + shared_ptr child = make_shared(); + int32_t err = stat(path.c_str(), &child->stat); + if (err != 0) { + LOGE("GenerateCloudDiskInode %{public}s error, err: %{public}d", path.c_str(), errno); + return nullptr; + } + + child->refCount++; + child->parent = reinterpret_cast(parent); + child->path = path; + child->layer = GetNextLayer(child->parent); + child->stat.st_ino = reinterpret_cast(child.get()); + child->ops = make_shared(); + wLock.lock(); + data->inodeCache[path] = child; + wLock.unlock(); + if (child->layer == CLOUD_DISK_INODE_FIRST_LAYER) { + child->bundleName = fileName; + child->ops = make_shared(); + } + return child; +} + +void FileOperationsHelper::PutCloudDiskInode(struct CloudDiskFuseData *data, + shared_ptr inoPtr, uint64_t num) +{ + std::unique_lock wLock(data->cacheLock, std::defer_lock); + inoPtr->refCount -= num; + if (inoPtr->refCount == 0) { + LOGD("node released: %{public}s", inoPtr->path.c_str()); + wLock.lock(); + data->inodeCache.erase(inoPtr->path); + wLock.unlock(); + } +} +} // namespace CloudDisk +} // namespace FileManagement +} // namespace OHOS diff --git a/test/unittests/services_daemon/BUILD.gn b/test/unittests/services_daemon/BUILD.gn index 5db3eeb39..09c829a2f 100644 --- a/test/unittests/services_daemon/BUILD.gn +++ b/test/unittests/services_daemon/BUILD.gn @@ -30,13 +30,24 @@ ohos_unittest("fuse_manager_test") { ] cloud_disk = [ + "${services_path}/cloudfiledaemon/src/cloud_disk/database_manager.cpp", "${services_path}/cloudfiledaemon/src/cloud_disk/file_operations_base.cpp", "${services_path}/cloudfiledaemon/src/cloud_disk/file_operations_cloud.cpp", "${services_path}/cloudfiledaemon/src/cloud_disk/file_operations_local.cpp", "${services_path}/cloudfiledaemon/src/cloud_disk/fuse_operations.cpp", ] + clouddisk_database = [ + "${clouddisk_database_path}/src/clouddisk_rdbstore.cpp", + "${clouddisk_database_path}/src/file_column.cpp", + "${clouddisk_database_path}/src/clouddisk_rdb_utils.cpp", + ] + + media_library = [ "${media_library_path}/frameworks/innerkitsimpl/media_library_helper/src/mimetype_utils.cpp" ] + sources += cloud_disk + sources += clouddisk_database + sources += media_library include_dirs = [ "../../../../../communication/ipc/interfaces/innerkits/ipc_core/include", @@ -46,6 +57,10 @@ ohos_unittest("fuse_manager_test") { "${services_path}/cloudfiledaemon/include/cloud_disk/", "${services_path}/cloudsyncservice/include/data_sync/", "${distributedfile_path}/adapter/cloud_adapter_example/include", + "${clouddisk_database_path}/include", + "${media_library_path}/frameworks/innerkitsimpl/media_library_helper/include", + "${media_library_path}/interfaces/inner_api/media_library_helper/include", + "${media_library_path}/frameworks/utils/include", ] deps = [ @@ -60,6 +75,7 @@ ohos_unittest("fuse_manager_test") { external_deps = [ "hilog:libhilog", "ipc:ipc_single", + "relational_store:native_rdb", ] defines = [ @@ -91,13 +107,24 @@ ohos_unittest("cloud_daemon_test") { ] cloud_disk = [ + "${services_path}/cloudfiledaemon/src/cloud_disk/database_manager.cpp", "${services_path}/cloudfiledaemon/src/cloud_disk/file_operations_base.cpp", "${services_path}/cloudfiledaemon/src/cloud_disk/file_operations_cloud.cpp", "${services_path}/cloudfiledaemon/src/cloud_disk/file_operations_local.cpp", "${services_path}/cloudfiledaemon/src/cloud_disk/fuse_operations.cpp", ] + clouddisk_database = [ + "${clouddisk_database_path}/src/clouddisk_rdbstore.cpp", + "${clouddisk_database_path}/src/file_column.cpp", + "${clouddisk_database_path}/src/clouddisk_rdb_utils.cpp", + ] + + media_library = [ "${media_library_path}/frameworks/innerkitsimpl/media_library_helper/src/mimetype_utils.cpp" ] + sources += cloud_disk + sources += clouddisk_database + sources += media_library include_dirs = [ "../../../../../communication/ipc/interfaces/innerkits/ipc_core/include", @@ -107,6 +134,10 @@ ohos_unittest("cloud_daemon_test") { "${services_path}/cloudfiledaemon/include/cloud_disk/", "${services_path}/cloudsyncservice/include/data_sync/", "${distributedfile_path}/adapter/cloud_adapter_example/include", + "${clouddisk_database_path}/include", + "${media_library_path}/frameworks/innerkitsimpl/media_library_helper/include", + "${media_library_path}/interfaces/inner_api/media_library_helper/include", + "${media_library_path}/frameworks/utils/include", ] deps = [ @@ -121,6 +152,7 @@ ohos_unittest("cloud_daemon_test") { external_deps = [ "hilog:libhilog", "ipc:ipc_single", + "relational_store:native_rdb", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] -- Gitee