From 60f5c501f628cbb217c3845653cbd1189811d38d Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Wed, 16 Aug 2017 14:39:52 +0200 Subject: [PATCH] [Filesystem] Fix for moving files on different file systems [Verification] Code compiles. Now files can be moved between different mounted file systems. TCT pass rate 100% (286/286/0/0/0) Change-Id: I5b70bc96f14a53bcebd2b2db3f12748949aab410 Signed-off-by: Tomasz Marciniak --- src/filesystem/filesystem_manager.cc | 52 +++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/filesystem/filesystem_manager.cc b/src/filesystem/filesystem_manager.cc index 43f7462d..15dd88ce 100644 --- a/src/filesystem/filesystem_manager.cc +++ b/src/filesystem/filesystem_manager.cc @@ -316,19 +316,53 @@ void FilesystemManager::Rename( const std::function& error_cb) { LoggerD("enter"); + int status = rename(oldPath.c_str(), newPath.c_str()); - if (0 == status) { - FilesystemStat fileStat = FilesystemStat::getStat(newPath); - if (fileStat.valid) { - success_cb(FilesystemStat::getStat(newPath)); - } else { - LoggerE("Cannot perform stat on new path!"); + if (0 != status) { + if(EXDEV != errno) { + LoggerE("Error while moving file"); error_cb(FilesystemError::Other); + return; + } + + LoggerD("Files are not on the same mounted file system"); + //In case of EXDEV we need to copy and remove file + //EXDEV - oldpath and newpath are not on the same mounted file system. + //Linux permits a file system to be mounted at multiple points, but rename() does not work + //across different mount points, even if the same file system is mounted on both. + + if (FilesystemError::None != copyFile(oldPath, newPath)) { + LoggerE("Error while copying file"); + error_cb(FilesystemError::Other); + return; + } + + struct stat fileStat; + if (0 != stat(oldPath.c_str(), &fileStat)) { + LoggerE("Error while getting file status [%s]", GetErrorString(errno).c_str()); + error_cb(FilesystemError::Other); + return; + } + + int ret = 0; + ret |= chmod(newPath.c_str(), fileStat.st_mode); + ret |= chown(newPath.c_str(), fileStat.st_uid, fileStat.st_gid); + if (0 != ret) { + LoggerE("Error while changing ownership/permissions [%s]", GetErrorString(errno).c_str()); + remove(newPath.c_str()); + error_cb(FilesystemError::Other); + return; + } + + if (0 != remove(oldPath.c_str())) { + LoggerE("Error while removing file [%s]", GetErrorString(errno).c_str()); + remove(newPath.c_str()); + error_cb(FilesystemError::Other); + return; } - } else { - LoggerE("Cannot rename file: %s", GetErrorString(errno).c_str()); - error_cb(FilesystemError::Other); } + + success_cb(FilesystemStat::getStat(newPath)); } void FilesystemManager::ReadDir( -- 2.34.1