summaryrefslogtreecommitdiffstats
path: root/dom/cache/FileUtils.h
blob: e22a08908d3ba9ef41a6186832e2b49bf71fee44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_cache_FileUtils_h
#define mozilla_dom_cache_FileUtils_h

#include "mozilla/Attributes.h"
#include "mozilla/dom/cache/Types.h"
#include "CacheCommon.h"
#include "mozIStorageConnection.h"
#include "nsStreamUtils.h"
#include "nsTArrayForwardDeclare.h"

struct nsID;
class nsIFile;

namespace mozilla::dom::cache {

#define PADDING_FILE_NAME u".padding"
#define PADDING_TMP_FILE_NAME u".padding-tmp"

enum class DirPaddingFile { FILE, TMP_FILE };

nsresult BodyCreateDir(nsIFile& aBaseDir);

// Note that this function can only be used during the initialization of the
// database.  We're unlikely to be able to delete the DB successfully past
// that point due to the file being in use.
nsresult BodyDeleteDir(const CacheDirectoryMetadata& aDirectoryMetadata,
                       nsIFile& aBaseDir);

// Returns a Result with a success value with the body id and, optionally, the
// copy context.
Result<std::pair<nsID, nsCOMPtr<nsISupports>>, nsresult> BodyStartWriteStream(
    const CacheDirectoryMetadata& aDirectoryMetadata, nsIFile& aBaseDir,
    nsIInputStream& aSource, void* aClosure, nsAsyncCopyCallbackFun aCallback);

void BodyCancelWrite(nsISupports& aCopyContext);

nsresult BodyFinalizeWrite(nsIFile& aBaseDir, const nsID& aId);

Result<MovingNotNull<nsCOMPtr<nsIInputStream>>, nsresult> BodyOpen(
    const CacheDirectoryMetadata& aDirectoryMetadata, nsIFile& aBaseDir,
    const nsID& aId);

nsresult BodyMaybeUpdatePaddingSize(
    const CacheDirectoryMetadata& aDirectoryMetadata, nsIFile& aBaseDir,
    const nsID& aId, uint32_t aPaddingInfo, int64_t* aPaddingSizeInOut);

nsresult BodyDeleteFiles(const CacheDirectoryMetadata& aDirectoryMetadata,
                         nsIFile& aBaseDir, const nsTArray<nsID>& aIdList);

nsresult BodyDeleteOrphanedFiles(
    const CacheDirectoryMetadata& aDirectoryMetadata, nsIFile& aBaseDir,
    const nsTArray<nsID>& aKnownBodyIdList);

// If aCanRemoveFiles is true, that means we are safe to touch the files which
// can be accessed in other threads.
// If it's not, that means we cannot remove the files which are possible to
// created by other threads. Note that if the files are not expected, we should
// be safe to remove them in any case.
template <typename Func>
nsresult BodyTraverseFiles(
    const Maybe<CacheDirectoryMetadata>& aDirectoryMetadata, nsIFile& aBodyDir,
    const Func& aHandleFileFunc, bool aCanRemoveFiles, bool aTrackQuota = true);

// XXX Remove this method when all callers properly wrap aClientMetadata with
// Some/Nothing
template <typename Func>
nsresult BodyTraverseFiles(const CacheDirectoryMetadata& aDirectoryMetadata,
                           nsIFile& aBodyDir, const Func& aHandleFileFunc,
                           bool aCanRemoveFiles, bool aTrackQuota = true) {
  return BodyTraverseFiles(Some(aDirectoryMetadata), aBodyDir, aHandleFileFunc,
                           aCanRemoveFiles, aTrackQuota);
}

nsresult CreateMarkerFile(const CacheDirectoryMetadata& aDirectoryMetadata);

nsresult DeleteMarkerFile(const CacheDirectoryMetadata& aDirectoryMetadata);

bool MarkerFileExists(const CacheDirectoryMetadata& aDirectoryMetadata);

nsresult RemoveNsIFileRecursively(
    const Maybe<CacheDirectoryMetadata>& aDirectoryMetadata, nsIFile& aFile,
    bool aTrackQuota = true);

// XXX Remove this method when all callers properly wrap aClientMetadata with
// Some/Nothing
inline nsresult RemoveNsIFileRecursively(
    const CacheDirectoryMetadata& aDirectoryMetadata, nsIFile& aFile,
    bool aTrackQuota = true) {
  return RemoveNsIFileRecursively(Some(aDirectoryMetadata), aFile, aTrackQuota);
}

// Delete a file that you think exists. If the file doesn't exist, an error
// will not be returned, but warning telemetry will be generated! So only call
// this on files that you know exist (idempotent usage, but it's not
// recommended).
nsresult RemoveNsIFile(const Maybe<CacheDirectoryMetadata>& aDirectoryMetadata,
                       nsIFile& aFile, bool aTrackQuota = true);

// XXX Remove this method when all callers properly wrap aClientMetadata with
// Some/Nothing
inline nsresult RemoveNsIFile(const CacheDirectoryMetadata& aDirectoryMetadata,
                              nsIFile& aFile, bool aTrackQuota = true) {
  return RemoveNsIFile(Some(aDirectoryMetadata), aFile, aTrackQuota);
}

void DecreaseUsageForDirectoryMetadata(
    const CacheDirectoryMetadata& aDirectoryMetadata, int64_t aUpdatingSize);

/**
 * This function is used to check if the directory padding file is existed.
 */
bool DirectoryPaddingFileExists(nsIFile& aBaseDir,
                                DirPaddingFile aPaddingFileType);

/**
 *
 * The functions below are used to read/write/delete the directory padding file
 * after acquiring the mutex lock. The mutex lock is held by
 * CacheQuotaClient to prevent multi-thread accessing issue. To avoid deadlock,
 * these functions should only access by static functions in
 * dom/cache/QuotaClient.cpp.
 *
 */

// Returns a Result with a success value denoting the padding size.
Result<int64_t, nsresult> DirectoryPaddingGet(nsIFile& aBaseDir);

nsresult DirectoryPaddingInit(nsIFile& aBaseDir);

nsresult UpdateDirectoryPaddingFile(nsIFile& aBaseDir,
                                    mozIStorageConnection& aConn,
                                    int64_t aIncreaseSize,
                                    int64_t aDecreaseSize,
                                    bool aTemporaryFileExist);

nsresult DirectoryPaddingFinalizeWrite(nsIFile& aBaseDir);

// Returns a Result with a success value denoting the padding size.
Result<int64_t, nsresult> DirectoryPaddingRestore(nsIFile& aBaseDir,
                                                  mozIStorageConnection& aConn,
                                                  bool aMustRestore);

nsresult DirectoryPaddingDeleteFile(nsIFile& aBaseDir,
                                    DirPaddingFile aPaddingFileType);
}  // namespace mozilla::dom::cache

#endif  // mozilla_dom_cache_FileUtils_h