|
11 | 11 | use OC\SystemConfig; |
12 | 12 | use OCP\Files\Cache\ICacheEntry; |
13 | 13 | use OCP\Files\FileInfo; |
| 14 | +use OCP\Files\GenericFileException; |
| 15 | +use OCP\Files\NotEnoughSpaceException; |
14 | 16 | use OCP\Files\Storage\IStorage; |
15 | 17 |
|
16 | 18 | class Quota extends Wrapper { |
@@ -120,19 +122,20 @@ public function copy(string $source, string $target): bool { |
120 | 122 |
|
121 | 123 | #[\Override] |
122 | 124 | public function fopen(string $path, string $mode) { |
123 | | - if (!$this->hasQuota()) { |
| 125 | + if (!$this->hasQuota() || $this->isPartFile($path)) { |
124 | 126 | return $this->getWrapperStorage()->fopen($path, $mode); |
125 | 127 | } |
126 | | - $source = $this->getWrapperStorage()->fopen($path, $mode); |
127 | 128 |
|
128 | | - // don't apply quota for part files |
129 | | - if (!$this->isPartFile($path)) { |
130 | | - $free = $this->free_space($path); |
131 | | - if ($source && (is_int($free) || is_float($free)) && $free >= 0 && $mode !== 'r' && $mode !== 'rb') { |
132 | | - // only apply quota for files, not metadata, trash or others |
133 | | - if ($this->shouldApplyQuota($path)) { |
134 | | - return \OC\Files\Stream\Quota::wrap($source, $free); |
135 | | - } |
| 129 | + $free = $this->free_space($path); |
| 130 | + if ($this->shouldApplyQuota($path) && $free == 0) { |
| 131 | + return false; |
| 132 | + } |
| 133 | + |
| 134 | + $source = $this->getWrapperStorage()->fopen($path, $mode); |
| 135 | + if ($source && (is_int($free) || is_float($free)) && $free >= 0 && $mode !== 'r' && $mode !== 'rb') { |
| 136 | + // only apply quota for files, not metadata, trash or others |
| 137 | + if ($this->shouldApplyQuota($path)) { |
| 138 | + return \OC\Files\Stream\Quota::wrap($source, $free); |
136 | 139 | } |
137 | 140 | } |
138 | 141 |
|
@@ -213,4 +216,31 @@ public function touch(string $path, ?int $mtime = null): bool { |
213 | 216 | public function enableQuota(bool $enabled): void { |
214 | 217 | $this->enabled = $enabled; |
215 | 218 | } |
| 219 | + |
| 220 | + #[\Override] |
| 221 | + public function writeStream(string $path, $stream, ?int $size = null): int { |
| 222 | + if (!$this->hasQuota()) { |
| 223 | + return parent::writeStream($path, $stream, $size); |
| 224 | + } |
| 225 | + |
| 226 | + $free = $this->free_space($path); |
| 227 | + if ($this->shouldApplyQuota($path) && $free == 0) { |
| 228 | + throw new NotEnoughSpaceException(); |
| 229 | + } |
| 230 | + |
| 231 | + if ($size !== null) { |
| 232 | + if ($size < $free) { |
| 233 | + return parent::writeStream($path, $stream, $size); |
| 234 | + } else { |
| 235 | + throw new NotEnoughSpaceException(); |
| 236 | + } |
| 237 | + } else { |
| 238 | + // force fallback through `fopen` to handle the quota |
| 239 | + try { |
| 240 | + return parent::writeStreamFallback($path, $stream); |
| 241 | + } catch (GenericFileException) { |
| 242 | + throw new NotEnoughSpaceException(); |
| 243 | + } |
| 244 | + } |
| 245 | + } |
216 | 246 | } |
0 commit comments