dont set folder size to negative values during propagation

normally this shouldn't be a problem, but cache/storage desync might cause this
so this adds some failsafe to ensure we dont corrupt the cache further

the minimum value is set to -1 instead of 0 in order to triger a background scan
on the folder and figure out the size properly

Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
Robin Appelman 2019-11-06 12:05:46 +01:00 committed by Roeland Jago Douma
parent 9e450d727a
commit 74c6beb603
No known key found for this signature in database
GPG key ID: F941078878347C0C
2 changed files with 16 additions and 2 deletions

View file

@ -91,7 +91,7 @@ class Propagator implements IPropagator {
}, $parentHashes); }, $parentHashes);
$builder->update('filecache') $builder->update('filecache')
->set('mtime', $builder->createFunction('GREATEST(' . $builder->getColumnName('mtime') . ', ' . $builder->createNamedParameter((int)$time, IQueryBuilder::PARAM_INT) . ')')) ->set('mtime', $builder->func()->greatest('mtime', $builder->createNamedParameter((int)$time, IQueryBuilder::PARAM_INT)))
->set('etag', $builder->createNamedParameter($etag, IQueryBuilder::PARAM_STR)) ->set('etag', $builder->createNamedParameter($etag, IQueryBuilder::PARAM_STR))
->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) ->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($builder->expr()->in('path_hash', $hashParams)); ->andWhere($builder->expr()->in('path_hash', $hashParams));
@ -102,7 +102,10 @@ class Propagator implements IPropagator {
// we need to do size separably so we can ignore entries with uncalculated size // we need to do size separably so we can ignore entries with uncalculated size
$builder = $this->connection->getQueryBuilder(); $builder = $this->connection->getQueryBuilder();
$builder->update('filecache') $builder->update('filecache')
->set('size', $builder->func()->add('size', $builder->createNamedParameter($sizeDifference))) ->set('size', $builder->func()->greatest(
$builder->createNamedParameter(-1, IQueryBuilder::PARAM_INT),
$builder->func()->add('size', $builder->createNamedParameter($sizeDifference)))
)
->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) ->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($builder->expr()->in('path_hash', $hashParams)) ->andWhere($builder->expr()->in('path_hash', $hashParams))
->andWhere($builder->expr()->gt('size', $builder->expr()->literal(-1, IQueryBuilder::PARAM_INT))); ->andWhere($builder->expr()->gt('size', $builder->expr()->literal(-1, IQueryBuilder::PARAM_INT)));

View file

@ -81,6 +81,17 @@ class PropagatorTest extends TestCase {
} }
} }
public function testSizePropagationNoNegative() {
$paths = ['', 'foo', 'foo/bar'];
$oldInfos = $this->getFileInfos($paths);
$this->storage->getPropagator()->propagateChange('foo/bar/file.txt', time(), -100);
$newInfos = $this->getFileInfos($paths);
foreach ($oldInfos as $i => $oldInfo) {
$this->assertEquals(-1, $newInfos[$i]->getSize());
}
}
public function testBatchedPropagation() { public function testBatchedPropagation() {
$this->storage->mkdir('foo/baz'); $this->storage->mkdir('foo/baz');
$this->storage->mkdir('asd'); $this->storage->mkdir('asd');