Add an additional free disk space check before saving the datastore (#1913)
Fixes https://github.com/shaarli/Shaarli/issues/1810
This commit is contained in:
parent
4242f6955a
commit
84b37c7baa
3 changed files with 55 additions and 1 deletions
|
@ -9,6 +9,8 @@
|
||||||
use malkusch\lock\mutex\NoMutex;
|
use malkusch\lock\mutex\NoMutex;
|
||||||
use Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
|
use Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
|
||||||
use Shaarli\Bookmark\Exception\EmptyDataStoreException;
|
use Shaarli\Bookmark\Exception\EmptyDataStoreException;
|
||||||
|
use Shaarli\Bookmark\Exception\InvalidWritableDataException;
|
||||||
|
use Shaarli\Bookmark\Exception\NotEnoughSpaceException;
|
||||||
use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
|
use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
||||||
|
|
||||||
|
@ -107,6 +109,7 @@ public function read()
|
||||||
* @param Bookmark[] $links
|
* @param Bookmark[] $links
|
||||||
*
|
*
|
||||||
* @throws NotWritableDataStoreException the datastore is not writable
|
* @throws NotWritableDataStoreException the datastore is not writable
|
||||||
|
* @throws InvalidWritableDataException
|
||||||
*/
|
*/
|
||||||
public function write($links)
|
public function write($links)
|
||||||
{
|
{
|
||||||
|
@ -118,9 +121,19 @@ public function write($links)
|
||||||
throw new NotWritableDataStoreException(dirname($this->datastore));
|
throw new NotWritableDataStoreException(dirname($this->datastore));
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = self::$phpPrefix . base64_encode(gzdeflate(serialize($links))) . self::$phpSuffix;
|
$data = base64_encode(gzdeflate(serialize($links)));
|
||||||
|
|
||||||
|
if (empty($data)) {
|
||||||
|
throw new InvalidWritableDataException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = self::$phpPrefix . $data . self::$phpSuffix;
|
||||||
|
|
||||||
$this->synchronized(function () use ($data) {
|
$this->synchronized(function () use ($data) {
|
||||||
|
if (!$this->checkDiskSpace($data)) {
|
||||||
|
throw new NotEnoughSpaceException();
|
||||||
|
}
|
||||||
|
|
||||||
file_put_contents(
|
file_put_contents(
|
||||||
$this->datastore,
|
$this->datastore,
|
||||||
$data
|
$data
|
||||||
|
@ -144,4 +157,17 @@ protected function synchronized(callable $function): void
|
||||||
$function();
|
$function();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure that there is enough disk space available to save the current data store.
|
||||||
|
* We add an arbitrary margin of 500kB.
|
||||||
|
*
|
||||||
|
* @param string $data to be saved
|
||||||
|
*
|
||||||
|
* @return bool True if data can safely be saved
|
||||||
|
*/
|
||||||
|
public function checkDiskSpace(string $data): bool
|
||||||
|
{
|
||||||
|
return disk_free_space(dirname($this->datastore)) > (strlen($data) + 1024 * 500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Shaarli\Bookmark\Exception;
|
||||||
|
|
||||||
|
class InvalidWritableDataException extends \Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* InvalidWritableDataException constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->message = 'Couldn\'t generate bookmark data to store in the datastore. Skipping file writing.';
|
||||||
|
}
|
||||||
|
}
|
14
application/bookmark/exception/NotEnoughSpaceException.php
Normal file
14
application/bookmark/exception/NotEnoughSpaceException.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Shaarli\Bookmark\Exception;
|
||||||
|
|
||||||
|
class NotEnoughSpaceException extends \Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* NotEnoughSpaceException constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->message = 'Not enough available disk space to save the datastore.';
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue