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 Shaarli\Bookmark\Exception\DatastoreNotInitializedException;
|
||||
use Shaarli\Bookmark\Exception\EmptyDataStoreException;
|
||||
use Shaarli\Bookmark\Exception\InvalidWritableDataException;
|
||||
use Shaarli\Bookmark\Exception\NotEnoughSpaceException;
|
||||
use Shaarli\Bookmark\Exception\NotWritableDataStoreException;
|
||||
use Shaarli\Config\ConfigManager;
|
||||
|
||||
|
@ -107,6 +109,7 @@ public function read()
|
|||
* @param Bookmark[] $links
|
||||
*
|
||||
* @throws NotWritableDataStoreException the datastore is not writable
|
||||
* @throws InvalidWritableDataException
|
||||
*/
|
||||
public function write($links)
|
||||
{
|
||||
|
@ -118,9 +121,19 @@ public function write($links)
|
|||
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) {
|
||||
if (!$this->checkDiskSpace($data)) {
|
||||
throw new NotEnoughSpaceException();
|
||||
}
|
||||
|
||||
file_put_contents(
|
||||
$this->datastore,
|
||||
$data
|
||||
|
@ -144,4 +157,17 @@ protected function synchronized(callable $function): void
|
|||
$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