Bug 1581067 - P2 - Extract similar to reuse the code; r=asuth

Differential Revision: https://phabricator.services.mozilla.com/D46780

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tom Tung 2019-09-27 16:54:45 +00:00
Родитель 8c5237086f
Коммит 6621347502
3 изменённых файлов: 163 добавлений и 169 удалений

273
dom/cache/FileUtils.cpp поставляемый
Просмотреть файл

@ -358,72 +358,41 @@ nsresult BodyMaybeUpdatePaddingSize(const QuotaInfo& aQuotaInfo,
nsresult BodyDeleteFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
const nsTArray<nsID>& aIdList) {
nsresult rv = NS_OK;
for (uint32_t i = 0; i < aIdList.Length(); ++i) {
nsCOMPtr<nsIFile> tmpFile;
rv = BodyIdToFile(aBaseDir, aIdList[i], BODY_FILE_TMP,
getter_AddRefs(tmpFile));
for (const auto id : aIdList) {
nsCOMPtr<nsIFile> bodyDir;
rv = BodyGetCacheDir(aBaseDir, id, getter_AddRefs(bodyDir));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = RemoveNsIFile(aQuotaInfo, tmpFile);
// Only treat file deletion as a hard failure in DEBUG builds. Users
// can unfortunately hit this on windows if anti-virus is scanning files,
// etc.
MOZ_ASSERT(NS_SUCCEEDED(rv));
const auto removeFileForId = [&aQuotaInfo, &id](nsIFile* bodyFile,
const nsACString& leafName,
bool& fileDeleted) {
MOZ_DIAGNOSTIC_ASSERT(bodyFile);
nsCOMPtr<nsIFile> finalFile;
rv = BodyIdToFile(aBaseDir, aIdList[i], BODY_FILE_FINAL,
getter_AddRefs(finalFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIFile> bodyDirectory;
rv = finalFile->GetParent(getter_AddRefs(bodyDirectory));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = RemoveNsIFile(aQuotaInfo, finalFile);
// Again, only treat removal as hard failure in debug build.
MOZ_ASSERT(NS_SUCCEEDED(rv));
// Checking if the directory is empty or not. If it's, then remove the
// directory as well.
nsCOMPtr<nsIDirectoryEnumerator> entries;
rv = bodyDirectory->GetDirectoryEntries(getter_AddRefs(entries));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isEmpty = true;
nsCOMPtr<nsIFile> file;
while (NS_SUCCEEDED(rv = entries->GetNextFile(getter_AddRefs(file))) &&
file) {
nsAutoCString leafName;
rv = file->GetNativeLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
nsID fileId;
if (NS_WARN_IF(!fileId.Parse(leafName.BeginReading()))) {
DebugOnly<nsresult> result =
RemoveNsIFile(aQuotaInfo, bodyFile, /* aTrackQuota */ false);
MOZ_ASSERT(NS_SUCCEEDED(result));
fileDeleted = true;
return NS_OK;
}
if (StringEndsWith(leafName, NS_LITERAL_CSTRING(".tmp")) ||
StringEndsWith(leafName, NS_LITERAL_CSTRING(".final"))) {
isEmpty = false;
break;
if (id.Equals(fileId)) {
DebugOnly<nsresult> result = RemoveNsIFile(aQuotaInfo, bodyFile);
MOZ_ASSERT(NS_SUCCEEDED(result));
fileDeleted = true;
return NS_OK;
}
}
fileDeleted = false;
return NS_OK;
};
rv = BodyTraverseFiles(aQuotaInfo, bodyDir, removeFileForId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isEmpty) {
DebugOnly<nsresult> result =
RemoveNsIFileRecursively(aQuotaInfo, bodyDirectory,
/* aTrackQuota */ false);
MOZ_ASSERT(NS_SUCCEEDED(result));
}
}
return NS_OK;
@ -566,83 +535,34 @@ nsresult BodyDeleteOrphanedFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
continue;
}
nsCOMPtr<nsIDirectoryEnumerator> subEntries;
rv = subdir->GetDirectoryEntries(getter_AddRefs(subEntries));
const auto removeOrphanedFiles =
[&aQuotaInfo, &aKnownBodyIdList](
nsIFile* bodyFile, const nsACString& leafName, bool& fileDeleted) {
MOZ_DIAGNOSTIC_ASSERT(bodyFile);
// Finally, parse the uuid out of the name. If its fails to parse,
// the ignore the file.
nsID id;
if (NS_WARN_IF(!id.Parse(leafName.BeginReading()))) {
DebugOnly<nsresult> result = RemoveNsIFile(aQuotaInfo, bodyFile);
MOZ_ASSERT(NS_SUCCEEDED(result));
fileDeleted = true;
return NS_OK;
}
if (!aKnownBodyIdList.Contains(id)) {
DebugOnly<nsresult> result = RemoveNsIFile(aQuotaInfo, bodyFile);
MOZ_ASSERT(NS_SUCCEEDED(result));
fileDeleted = true;
return NS_OK;
}
fileDeleted = false;
return NS_OK;
};
rv = BodyTraverseFiles(aQuotaInfo, subdir, removeOrphanedFiles);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isEmpty = true;
// Now iterate over all the files in the subdir
nsCOMPtr<nsIFile> file;
while (NS_SUCCEEDED(rv = subEntries->GetNextFile(getter_AddRefs(file))) &&
file) {
bool isDirectory = false;
rv = file->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// If it's a directory somehow, try to remove it and move on
if (isDirectory) {
DebugOnly<nsresult> result =
RemoveNsIFileRecursively(aQuotaInfo, file, /* aTrackQuota */ false);
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
nsAutoCString leafName;
rv = file->GetNativeLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Delete all tmp files regardless of known bodies. These are all
// considered orphans.
if (StringEndsWith(leafName, NS_LITERAL_CSTRING(".tmp"))) {
DebugOnly<nsresult> result = RemoveNsIFile(aQuotaInfo, file);
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
nsCString suffix(NS_LITERAL_CSTRING(".final"));
// Otherwise, it must be a .final file. If its not, then try to remove it
// and move on
if (NS_WARN_IF(!StringEndsWith(leafName, suffix) ||
leafName.Length() != NSID_LENGTH - 1 + suffix.Length())) {
DebugOnly<nsresult> result = RemoveNsIFile(aQuotaInfo, file);
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
// Finally, parse the uuid out of the name. If its fails to parse,
// the ignore the file.
nsID id;
if (NS_WARN_IF(!id.Parse(leafName.BeginReading()))) {
DebugOnly<nsresult> result =
RemoveNsIFile(aQuotaInfo, file, /* aTrackQuota */ false);
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
if (!aKnownBodyIdList.Contains(id)) {
DebugOnly<nsresult> result = RemoveNsIFile(aQuotaInfo, file);
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
isEmpty = false;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isEmpty) {
DebugOnly<nsresult> result =
RemoveNsIFileRecursively(aQuotaInfo, subdir, /* aTrackQuota */ false);
MOZ_ASSERT(NS_SUCCEEDED(result));
}
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -651,6 +571,101 @@ nsresult BodyDeleteOrphanedFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
return rv;
}
template <typename Func>
nsresult BodyTraverseFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBodyDir,
const Func& aHandleFileFunc,
const bool aTrackQuota) {
MOZ_DIAGNOSTIC_ASSERT(aBodyDir);
nsresult rv;
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
nsCOMPtr<nsIFile> parentFile;
rv = aBodyDir->GetParent(getter_AddRefs(parentFile));
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
MOZ_DIAGNOSTIC_ASSERT(parentFile);
nsAutoCString nativeLeafName;
rv = parentFile->GetNativeLeafName(nativeLeafName);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
MOZ_DIAGNOSTIC_ASSERT(
StringEndsWith(nativeLeafName, NS_LITERAL_CSTRING("morgue")));
#endif
nsCOMPtr<nsIDirectoryEnumerator> entries;
rv = aBodyDir->GetDirectoryEntries(getter_AddRefs(entries));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isEmpty = true;
nsCOMPtr<nsIFile> file;
while (NS_SUCCEEDED(rv = entries->GetNextFile(getter_AddRefs(file))) &&
file) {
bool isDir = false;
rv = file->IsDirectory(&isDir);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// If it's a directory somehow, try to remove it and move on
if (NS_WARN_IF(isDir)) {
DebugOnly<nsresult> result =
RemoveNsIFileRecursively(aQuotaInfo, file, /* aTrackQuota */ false);
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
nsAutoCString leafName;
rv = file->GetNativeLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Delete all tmp files regardless of known bodies. These are all
// considered orphans.
if (StringEndsWith(leafName, NS_LITERAL_CSTRING(".tmp"))) {
DebugOnly<nsresult> result = RemoveNsIFile(aQuotaInfo, file, aTrackQuota);
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
nsCString suffix(NS_LITERAL_CSTRING(".final"));
// Otherwise, it must be a .final file. If its not, then try to remove it
// and move on
if (NS_WARN_IF(!StringEndsWith(leafName, suffix) ||
leafName.Length() != NSID_LENGTH - 1 + suffix.Length())) {
DebugOnly<nsresult> result =
RemoveNsIFile(aQuotaInfo, file, /* aTrackQuota */ false);
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
bool fileDeleted;
rv = aHandleFileFunc(file, leafName, fileDeleted);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (fileDeleted) {
continue;
}
isEmpty = false;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isEmpty) {
DebugOnly<nsresult> result =
RemoveNsIFileRecursively(aQuotaInfo, aBodyDir, /* aTrackQuota */ false);
MOZ_ASSERT(NS_SUCCEEDED(result));
}
return rv;
}
namespace {
nsresult GetMarkerFileHandle(const QuotaInfo& aQuotaInfo, nsIFile** aFileOut) {

5
dom/cache/FileUtils.h поставляемый
Просмотреть файл

@ -58,6 +58,11 @@ nsresult BodyDeleteFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
nsresult BodyDeleteOrphanedFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
nsTArray<nsID>& aKnownBodyIdList);
template <typename Func>
nsresult BodyTraverseFiles(const QuotaInfo& aQuotaInfo, nsIFile* aBodyDir,
const Func& aHandleFileFunc,
const bool aTrackQuota = true);
nsresult CreateMarkerFile(const QuotaInfo& aQuotaInfo);
nsresult DeleteMarkerFile(const QuotaInfo& aQuotaInfo);

54
dom/cache/QuotaClient.cpp поставляемый
Просмотреть файл

@ -68,56 +68,30 @@ static nsresult GetBodyUsage(nsIFile* aMorgueDir, const Atomic<bool>& aCanceled,
continue;
}
nsCOMPtr<nsIDirectoryEnumerator> subEntries;
rv = bodyDir->GetDirectoryEntries(getter_AddRefs(subEntries));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isEmpty = true;
nsCOMPtr<nsIFile> bodyFile;
while (
NS_SUCCEEDED(rv = subEntries->GetNextFile(getter_AddRefs(bodyFile))) &&
bodyFile && !aCanceled) {
bool isDirectory;
rv = bodyFile->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDirectory) {
QuotaInfo dummy;
mozilla::DebugOnly<nsresult> result =
RemoveNsIFileRecursively(dummy, bodyFile, /* aTrackQuota */ false);
// Try to remove the unexpected files, and keep moving on even if it
// fails because it might be created by virus or the operation system
MOZ_ASSERT(NS_SUCCEEDED(result));
continue;
}
isEmpty = false;
const QuotaInfo dummy;
const auto getUsage = [&aUsageInfo](nsIFile* bodyFile,
const nsACString& leafName,
bool& fileDeleted) {
MOZ_DIAGNOSTIC_ASSERT(bodyFile);
Unused << leafName;
int64_t fileSize;
rv = bodyFile->GetFileSize(&fileSize);
nsresult rv = bodyFile->GetFileSize(&fileSize);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_DIAGNOSTIC_ASSERT(fileSize >= 0);
aUsageInfo->AppendToFileUsage(Some(fileSize));
}
fileDeleted = false;
return NS_OK;
};
rv = mozilla::dom::cache::BodyTraverseFiles(dummy, bodyDir, getUsage,
/* aTrackQuota */ false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isEmpty) {
QuotaInfo dummy;
mozilla::DebugOnly<nsresult> result =
RemoveNsIFileRecursively(dummy, bodyDir, /* aTrackQuota */ false);
// Try to remove the unexpected files, and keep moving on even if it
// fails because it might be created by virus or the operation system
MOZ_ASSERT(NS_SUCCEEDED(result));
}
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;