summaryrefslogtreecommitdiff
path: root/includes/filebackend
diff options
context:
space:
mode:
Diffstat (limited to 'includes/filebackend')
-rw-r--r--includes/filebackend/FSFile.php9
-rw-r--r--includes/filebackend/FileBackend.php15
-rw-r--r--includes/filebackend/FileBackendGroup.php2
-rw-r--r--includes/filebackend/FileBackendMultiWrite.php176
-rw-r--r--includes/filebackend/FileBackendStore.php80
-rw-r--r--includes/filebackend/FileOp.php4
-rw-r--r--includes/filebackend/MemoryFileBackend.php8
-rw-r--r--includes/filebackend/SwiftFileBackend.php151
-rw-r--r--includes/filebackend/TempFSFile.php15
-rw-r--r--includes/filebackend/lockmanager/DBLockManager.php2
-rw-r--r--includes/filebackend/lockmanager/FSLockManager.php4
-rw-r--r--includes/filebackend/lockmanager/LockManager.php1
12 files changed, 267 insertions, 200 deletions
diff --git a/includes/filebackend/FSFile.php b/includes/filebackend/FSFile.php
index 6ee9b2e0..213bb87d 100644
--- a/includes/filebackend/FSFile.php
+++ b/includes/filebackend/FSFile.php
@@ -75,9 +75,9 @@ class FSFile {
* @return string|bool TS_MW timestamp or false on failure
*/
public function getTimestamp() {
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$timestamp = filemtime( $this->path );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( $timestamp !== false ) {
$timestamp = wfTimestamp( TS_MW, $timestamp );
}
@@ -200,13 +200,12 @@ class FSFile {
public function getSha1Base36( $recache = false ) {
if ( $this->sha1Base36 !== null && !$recache ) {
-
return $this->sha1Base36;
}
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$this->sha1Base36 = sha1_file( $this->path );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( $this->sha1Base36 !== false ) {
$this->sha1Base36 = wfBaseConvert( $this->sha1Base36, 16, 36, 31 );
diff --git a/includes/filebackend/FileBackend.php b/includes/filebackend/FileBackend.php
index b87e26d3..cd82ab10 100644
--- a/includes/filebackend/FileBackend.php
+++ b/includes/filebackend/FileBackend.php
@@ -380,12 +380,15 @@ abstract class FileBackend {
$op['headers']['Content-Disposition'] = $op['disposition'];
}
}
+ /** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
return $this->doOperationsInternal( $ops, $opts );
}
/**
* @see FileBackend::doOperations()
+ * @param array $ops
+ * @param array $opts
*/
abstract protected function doOperationsInternal( array $ops, array $opts );
@@ -612,12 +615,14 @@ abstract class FileBackend {
$op['headers']['Content-Disposition'] = $op['disposition'];
}
}
+ /** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
return $this->doQuickOperationsInternal( $ops );
}
/**
* @see FileBackend::doQuickOperations()
+ * @param array $ops
* @since 1.20
*/
abstract protected function doQuickOperationsInternal( array $ops );
@@ -756,12 +761,14 @@ abstract class FileBackend {
if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
}
+ /** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
return $this->doPrepare( $params );
}
/**
* @see FileBackend::prepare()
+ * @param array $params
*/
abstract protected function doPrepare( array $params );
@@ -785,12 +792,14 @@ abstract class FileBackend {
if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
}
+ /** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
return $this->doSecure( $params );
}
/**
* @see FileBackend::secure()
+ * @param array $params
*/
abstract protected function doSecure( array $params );
@@ -816,12 +825,14 @@ abstract class FileBackend {
if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
}
+ /** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
return $this->doPublish( $params );
}
/**
* @see FileBackend::publish()
+ * @param array $params
*/
abstract protected function doPublish( array $params );
@@ -840,12 +851,14 @@ abstract class FileBackend {
if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
}
+ /** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
return $this->doClean( $params );
}
/**
* @see FileBackend::clean()
+ * @param array $params
*/
abstract protected function doClean( array $params );
@@ -1289,7 +1302,7 @@ abstract class FileBackend {
*
* @param array $ops List of file operations to FileBackend::doOperations()
* @param Status $status Status to update on lock/unlock
- * @return array List of ScopedFileLocks or null values
+ * @return ScopedLock|null
* @since 1.20
*/
abstract public function getScopedLocksForOps( array $ops, Status $status );
diff --git a/includes/filebackend/FileBackendGroup.php b/includes/filebackend/FileBackendGroup.php
index 1b88db7e..9bb15825 100644
--- a/includes/filebackend/FileBackendGroup.php
+++ b/includes/filebackend/FileBackendGroup.php
@@ -160,6 +160,8 @@ class FileBackendGroup {
$config['fileJournal'] = isset( $config['fileJournal'] )
? FileJournal::factory( $config['fileJournal'], $name )
: FileJournal::factory( array( 'class' => 'NullFileJournal' ), $name );
+ $config['wanCache'] = ObjectCache::getMainWANInstance();
+
$this->backends[$name]['instance'] = new $class( $config );
}
diff --git a/includes/filebackend/FileBackendMultiWrite.php b/includes/filebackend/FileBackendMultiWrite.php
index f2d13eeb..1603d44f 100644
--- a/includes/filebackend/FileBackendMultiWrite.php
+++ b/includes/filebackend/FileBackendMultiWrite.php
@@ -33,20 +33,22 @@
* Only use this class when transitioning from one storage system to another.
*
* Read operations are only done on the 'master' backend for consistency.
- * Write operations are performed on all backends, in the order defined.
- * If an operation fails on one backend it will be rolled back from the others.
+ * Write operations are performed on all backends, starting with the master.
+ * This makes a best-effort to have transactional semantics, but since requests
+ * may sometimes fail, the use of "autoResync" or background scripts to fix
+ * inconsistencies is important.
*
* @ingroup FileBackend
* @since 1.19
*/
class FileBackendMultiWrite extends FileBackend {
- /** @var array Prioritized list of FileBackendStore objects.
- * array of (backend index => backends)
- */
+ /** @var FileBackendStore[] Prioritized list of FileBackendStore objects */
protected $backends = array();
/** @var int Index of master backend */
protected $masterIndex = -1;
+ /** @var int Index of read affinity backend */
+ protected $readIndex = -1;
/** @var int Bitfield */
protected $syncChecks = 0;
@@ -54,12 +56,6 @@ class FileBackendMultiWrite extends FileBackend {
/** @var string|bool */
protected $autoResync = false;
- /** @var array */
- protected $noPushDirConts = array();
-
- /** @var bool */
- protected $noPushQuickOps = false;
-
/* Possible internal backend consistency checks */
const CHECK_SIZE = 1;
const CHECK_TIME = 2;
@@ -75,6 +71,7 @@ class FileBackendMultiWrite extends FileBackend {
* FileBackendStore class, but with these additional settings:
* - class : The name of the backend class
* - isMultiMaster : This must be set for one backend.
+ * - readAffinity : Use this for reads without 'latest' set.
* - template: : If given a backend name, this will use
* the config of that backend as a template.
* Values specified here take precedence.
@@ -88,8 +85,6 @@ class FileBackendMultiWrite extends FileBackend {
* Use "conservative" to limit resyncing to copying newer master
* backend files over older (or non-existing) clone backend files.
* Cases that cannot be handled will result in operation abortion.
- * - noPushQuickOps : (hack) Only apply doQuickOperations() to the master backend.
- * - noPushDirConts : (hack) Only apply directory functions to the master backend.
*
* @param array $config
* @throws FileBackendError
@@ -102,12 +97,6 @@ class FileBackendMultiWrite extends FileBackend {
$this->autoResync = isset( $config['autoResync'] )
? $config['autoResync']
: false;
- $this->noPushQuickOps = isset( $config['noPushQuickOps'] )
- ? $config['noPushQuickOps']
- : false;
- $this->noPushDirConts = isset( $config['noPushDirConts'] )
- ? $config['noPushDirConts']
- : array();
// Construct backends here rather than via registration
// to keep these backends hidden from outside the proxy.
$namesUsed = array();
@@ -134,6 +123,9 @@ class FileBackendMultiWrite extends FileBackend {
$this->masterIndex = $index; // this is the "master"
$config['fileJournal'] = $this->fileJournal; // log under proxy backend
}
+ if ( !empty( $config['readAffinity'] ) ) {
+ $this->readIndex = $index; // prefer this for reads
+ }
// Create sub-backend object
if ( !isset( $config['class'] ) ) {
throw new FileBackendError( 'No class given for a backend config.' );
@@ -144,6 +136,9 @@ class FileBackendMultiWrite extends FileBackend {
if ( $this->masterIndex < 0 ) { // need backends and must have a master
throw new FileBackendError( 'No master backend defined.' );
}
+ if ( $this->readIndex < 0 ) {
+ $this->readIndex = $this->masterIndex; // default
+ }
}
final protected function doOperationsInternal( array $ops, array $opts ) {
@@ -154,6 +149,7 @@ class FileBackendMultiWrite extends FileBackend {
// Try to lock those files for the scope of this function...
if ( empty( $opts['nonLocking'] ) ) {
// Try to lock those files for the scope of this function...
+ /** @noinspection PhpUnusedLocalVariableInspection */
$scopeLock = $this->getScopedLocksForOps( $ops, $status );
if ( !$status->isOK() ) {
return $status; // abort
@@ -328,8 +324,8 @@ class FileBackendMultiWrite extends FileBackend {
$cStat = $cBackend->getFileStat( array( 'src' => $cPath, 'latest' => true ) );
if ( $cStat === null || ( $cSha1 !== false && !$cStat ) ) { // sanity
$status->fatal( 'backend-fail-internal', $cBackend->getName() );
- wfDebugLog( 'FileOperation', __METHOD__
- . ': File is not available on the clone backend' );
+ wfDebugLog( 'FileOperation', __METHOD__ .
+ ': File is not available on the clone backend' );
continue; // file is not available on the clone backend...
}
if ( $mSha1 === $cSha1 ) {
@@ -433,7 +429,7 @@ class FileBackendMultiWrite extends FileBackend {
*/
protected function substPaths( $paths, FileBackendStore $backend ) {
return preg_replace(
- '!^mwstore://' . preg_quote( $this->name ) . '/!',
+ '!^mwstore://' . preg_quote( $this->name, '!' ) . '/!',
StringUtils::escapeRegexReplacement( "mwstore://{$backend->getName()}/" ),
$paths // string or array
);
@@ -460,12 +456,10 @@ class FileBackendMultiWrite extends FileBackend {
$masterStatus = $this->backends[$this->masterIndex]->doQuickOperations( $realOps );
$status->merge( $masterStatus );
// Propagate the operations to the clone backends...
- if ( !$this->noPushQuickOps ) {
- foreach ( $this->backends as $index => $backend ) {
- if ( $index !== $this->masterIndex ) { // not done already
- $realOps = $this->substOpBatchPaths( $ops, $backend );
- $status->merge( $backend->doQuickOperations( $realOps ) );
- }
+ foreach ( $this->backends as $index => $backend ) {
+ if ( $index !== $this->masterIndex ) { // not done already
+ $realOps = $this->substOpBatchPaths( $ops, $backend );
+ $status->merge( $backend->doQuickOperations( $realOps ) );
}
}
// Make 'success', 'successCount', and 'failCount' fields reflect
@@ -478,24 +472,11 @@ class FileBackendMultiWrite extends FileBackend {
return $status;
}
- /**
- * @param string $path Storage path
- * @return bool Path container should have dir changes pushed to all backends
- */
- protected function replicateContainerDirChanges( $path ) {
- list( , $shortCont, ) = self::splitStoragePath( $path );
-
- return !in_array( $shortCont, $this->noPushDirConts );
- }
-
protected function doPrepare( array $params ) {
$status = Status::newGood();
- $replicate = $this->replicateContainerDirChanges( $params['dir'] );
foreach ( $this->backends as $index => $backend ) {
- if ( $replicate || $index == $this->masterIndex ) {
- $realParams = $this->substOpPaths( $params, $backend );
- $status->merge( $backend->doPrepare( $realParams ) );
- }
+ $realParams = $this->substOpPaths( $params, $backend );
+ $status->merge( $backend->doPrepare( $realParams ) );
}
return $status;
@@ -503,12 +484,9 @@ class FileBackendMultiWrite extends FileBackend {
protected function doSecure( array $params ) {
$status = Status::newGood();
- $replicate = $this->replicateContainerDirChanges( $params['dir'] );
foreach ( $this->backends as $index => $backend ) {
- if ( $replicate || $index == $this->masterIndex ) {
- $realParams = $this->substOpPaths( $params, $backend );
- $status->merge( $backend->doSecure( $realParams ) );
- }
+ $realParams = $this->substOpPaths( $params, $backend );
+ $status->merge( $backend->doSecure( $realParams ) );
}
return $status;
@@ -516,12 +494,9 @@ class FileBackendMultiWrite extends FileBackend {
protected function doPublish( array $params ) {
$status = Status::newGood();
- $replicate = $this->replicateContainerDirChanges( $params['dir'] );
foreach ( $this->backends as $index => $backend ) {
- if ( $replicate || $index == $this->masterIndex ) {
- $realParams = $this->substOpPaths( $params, $backend );
- $status->merge( $backend->doPublish( $realParams ) );
- }
+ $realParams = $this->substOpPaths( $params, $backend );
+ $status->merge( $backend->doPublish( $realParams ) );
}
return $status;
@@ -529,12 +504,9 @@ class FileBackendMultiWrite extends FileBackend {
protected function doClean( array $params ) {
$status = Status::newGood();
- $replicate = $this->replicateContainerDirChanges( $params['dir'] );
foreach ( $this->backends as $index => $backend ) {
- if ( $replicate || $index == $this->masterIndex ) {
- $realParams = $this->substOpPaths( $params, $backend );
- $status->merge( $backend->doClean( $realParams ) );
- }
+ $realParams = $this->substOpPaths( $params, $backend );
+ $status->merge( $backend->doClean( $realParams ) );
}
return $status;
@@ -542,44 +514,52 @@ class FileBackendMultiWrite extends FileBackend {
public function concatenate( array $params ) {
// We are writing to an FS file, so we don't need to do this per-backend
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->concatenate( $realParams );
+ return $this->backends[$index]->concatenate( $realParams );
}
public function fileExists( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->fileExists( $realParams );
+ return $this->backends[$index]->fileExists( $realParams );
}
public function getFileTimestamp( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->getFileTimestamp( $realParams );
+ return $this->backends[$index]->getFileTimestamp( $realParams );
}
public function getFileSize( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->getFileSize( $realParams );
+ return $this->backends[$index]->getFileSize( $realParams );
}
public function getFileStat( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->getFileStat( $realParams );
+ return $this->backends[$index]->getFileStat( $realParams );
}
public function getFileXAttributes( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->getFileXAttributes( $realParams );
+ return $this->backends[$index]->getFileXAttributes( $realParams );
}
public function getFileContentsMulti( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
- $contentsM = $this->backends[$this->masterIndex]->getFileContentsMulti( $realParams );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
+
+ $contentsM = $this->backends[$index]->getFileContentsMulti( $realParams );
$contents = array(); // (path => FSFile) mapping using the proxy backend's name
foreach ( $contentsM as $path => $data ) {
@@ -590,26 +570,31 @@ class FileBackendMultiWrite extends FileBackend {
}
public function getFileSha1Base36( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->getFileSha1Base36( $realParams );
+ return $this->backends[$index]->getFileSha1Base36( $realParams );
}
public function getFileProps( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->getFileProps( $realParams );
+ return $this->backends[$index]->getFileProps( $realParams );
}
public function streamFile( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->streamFile( $realParams );
+ return $this->backends[$index]->streamFile( $realParams );
}
public function getLocalReferenceMulti( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
- $fsFilesM = $this->backends[$this->masterIndex]->getLocalReferenceMulti( $realParams );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
+
+ $fsFilesM = $this->backends[$index]->getLocalReferenceMulti( $realParams );
$fsFiles = array(); // (path => FSFile) mapping using the proxy backend's name
foreach ( $fsFilesM as $path => $fsFile ) {
@@ -620,8 +605,10 @@ class FileBackendMultiWrite extends FileBackend {
}
public function getLocalCopyMulti( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
- $tempFilesM = $this->backends[$this->masterIndex]->getLocalCopyMulti( $realParams );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
+
+ $tempFilesM = $this->backends[$index]->getLocalCopyMulti( $realParams );
$tempFiles = array(); // (path => TempFSFile) mapping using the proxy backend's name
foreach ( $tempFilesM as $path => $tempFile ) {
@@ -632,9 +619,10 @@ class FileBackendMultiWrite extends FileBackend {
}
public function getFileHttpUrl( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
- return $this->backends[$this->masterIndex]->getFileHttpUrl( $realParams );
+ return $this->backends[$index]->getFileHttpUrl( $realParams );
}
public function directoryExists( array $params ) {
@@ -667,13 +655,15 @@ class FileBackendMultiWrite extends FileBackend {
}
public function preloadCache( array $paths ) {
- $realPaths = $this->substPaths( $paths, $this->backends[$this->masterIndex] );
- $this->backends[$this->masterIndex]->preloadCache( $realPaths );
+ $realPaths = $this->substPaths( $paths, $this->backends[$this->readIndex] );
+ $this->backends[$this->readIndex]->preloadCache( $realPaths );
}
public function preloadFileStat( array $params ) {
- $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
- return $this->backends[$this->masterIndex]->preloadFileStat( $realParams );
+ $index = $this->getReadIndexFromParams( $params );
+ $realParams = $this->substOpPaths( $params, $this->backends[$index] );
+
+ return $this->backends[$index]->preloadFileStat( $realParams );
}
public function getScopedLocksForOps( array $ops, Status $status ) {
@@ -688,6 +678,14 @@ class FileBackendMultiWrite extends FileBackend {
);
// Actually acquire the locks
- return array( $this->getScopedFileLocks( $pbPaths, 'mixed', $status ) );
+ return $this->getScopedFileLocks( $pbPaths, 'mixed', $status );
+ }
+
+ /**
+ * @param array $params
+ * @return int The master or read affinity backend index, based on $params['latest']
+ */
+ protected function getReadIndexFromParams( array $params ) {
+ return !empty( $params['latest'] ) ? $this->masterIndex : $this->readIndex;
}
}
diff --git a/includes/filebackend/FileBackendStore.php b/includes/filebackend/FileBackendStore.php
index 25e87d43..94339643 100644
--- a/includes/filebackend/FileBackendStore.php
+++ b/includes/filebackend/FileBackendStore.php
@@ -36,7 +36,7 @@
* @since 1.19
*/
abstract class FileBackendStore extends FileBackend {
- /** @var BagOStuff */
+ /** @var WANObjectCache */
protected $memCache;
/** @var ProcessCacheLRU Map of paths to small (RAM/disk) cache items */
protected $cheapCache;
@@ -58,6 +58,7 @@ abstract class FileBackendStore extends FileBackend {
/**
* @see FileBackend::__construct()
* Additional $config params include:
+ * - wanCache : WANOBjectCache object to use for persistent caching.
* - mimeCallback : Callback that takes (storage path, content, file system path) and
* returns the MIME type of the file or 'unknown/unknown'. The file
* system path parameter should be used if the content one is null.
@@ -72,7 +73,7 @@ abstract class FileBackendStore extends FileBackend {
// @todo handle the case of extension-less files using the contents
return StreamFile::contentTypeFromPath( $storagePath ) ?: 'unknown/unknown';
};
- $this->memCache = new EmptyBagOStuff(); // disabled by default
+ $this->memCache = WANObjectCache::newEmpty(); // disabled by default
$this->cheapCache = new ProcessCacheLRU( self::CACHE_CHEAP_SIZE );
$this->expensiveCache = new ProcessCacheLRU( self::CACHE_EXPENSIVE_SIZE );
}
@@ -376,9 +377,9 @@ abstract class FileBackendStore extends FileBackend {
unset( $params['latest'] ); // sanity
// Check that the specified temp file is valid...
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$ok = ( is_file( $tmpPath ) && filesize( $tmpPath ) == 0 );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( !$ok ) { // not present or not empty
$status->fatal( 'backend-fail-opentemp', $tmpPath );
@@ -693,9 +694,9 @@ abstract class FileBackendStore extends FileBackend {
protected function doGetFileContentsMulti( array $params ) {
$contents = array();
foreach ( $this->doGetLocalReferenceMulti( $params ) as $path => $fsFile ) {
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$contents[$path] = $fsFile ? file_get_contents( $fsFile->getPath() ) : false;
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
}
return $contents;
@@ -1057,7 +1058,7 @@ abstract class FileBackendStore extends FileBackend {
public function getScopedLocksForOps( array $ops, Status $status ) {
$paths = $this->getPathsToLockForOpsInternal( $this->getOperationsInternal( $ops ) );
- return array( $this->getScopedFileLocks( $paths, 'mixed', $status ) );
+ return $this->getScopedFileLocks( $paths, 'mixed', $status );
}
final protected function doOperationsInternal( array $ops, array $opts ) {
@@ -1075,6 +1076,7 @@ abstract class FileBackendStore extends FileBackend {
// Build up a list of files to lock...
$paths = $this->getPathsToLockForOpsInternal( $performOps );
// Try to lock those files for the scope of this function...
+
$scopeLock = $this->getScopedFileLocks( $paths, 'mixed', $status );
if ( !$status->isOK() ) {
return $status; // abort
@@ -1363,19 +1365,38 @@ abstract class FileBackendStore extends FileBackend {
abstract protected function directoriesAreVirtual();
/**
- * Check if a container name is valid.
+ * Check if a short container name is valid
+ *
+ * This checks for length and illegal characters.
+ * This may disallow certain characters that can appear
+ * in the prefix used to make the full container name.
+ *
+ * @param string $container
+ * @return bool
+ */
+ final protected static function isValidShortContainerName( $container ) {
+ // Suffixes like '.xxx' (hex shard chars) or '.seg' (file segments)
+ // might be used by subclasses. Reserve the dot character for sanity.
+ // The only way dots end up in containers (e.g. resolveStoragePath)
+ // is due to the wikiId container prefix or the above suffixes.
+ return self::isValidContainerName( $container ) && !preg_match( '/[.]/', $container );
+ }
+
+ /**
+ * Check if a full container name is valid
+ *
* This checks for length and illegal characters.
+ * Limiting the characters makes migrations to other stores easier.
*
* @param string $container
* @return bool
*/
final protected static function isValidContainerName( $container ) {
- // This accounts for Swift and S3 restrictions while leaving room
- // for things like '.xxx' (hex shard chars) or '.seg' (segments).
- // This disallows directory separators or traversal characters.
+ // This accounts for NTFS, Swift, and Ceph restrictions
+ // and disallows directory separators or traversal characters.
// Note that matching strings URL encode to the same string;
- // in Swift, the length restriction is *after* URL encoding.
- return preg_match( '/^[a-z0-9][a-z0-9-_]{0,199}$/i', $container );
+ // in Swift/Ceph, the length restriction is *after* URL encoding.
+ return (bool)preg_match( '/^[a-z0-9][a-z0-9-_.]{0,199}$/i', $container );
}
/**
@@ -1392,17 +1413,17 @@ abstract class FileBackendStore extends FileBackend {
* @return array (container, path, container suffix) or (null, null, null) if invalid
*/
final protected function resolveStoragePath( $storagePath ) {
- list( $backend, $container, $relPath ) = self::splitStoragePath( $storagePath );
+ list( $backend, $shortCont, $relPath ) = self::splitStoragePath( $storagePath );
if ( $backend === $this->name ) { // must be for this backend
$relPath = self::normalizeContainerPath( $relPath );
- if ( $relPath !== null ) {
+ if ( $relPath !== null && self::isValidShortContainerName( $shortCont ) ) {
// Get shard for the normalized path if this container is sharded
- $cShard = $this->getContainerShard( $container, $relPath );
+ $cShard = $this->getContainerShard( $shortCont, $relPath );
// Validate and sanitize the relative path (backend-specific)
- $relPath = $this->resolveContainerPath( $container, $relPath );
+ $relPath = $this->resolveContainerPath( $shortCont, $relPath );
if ( $relPath !== null ) {
// Prepend any wiki ID prefix to the container name
- $container = $this->fullContainerName( $container );
+ $container = $this->fullContainerName( $shortCont );
if ( self::isValidContainerName( $container ) ) {
// Validate and sanitize the container name (backend-specific)
$container = $this->resolveContainerName( "{$container}{$cShard}" );
@@ -1592,7 +1613,7 @@ abstract class FileBackendStore extends FileBackend {
* @param array $val Information to cache
*/
final protected function setContainerCache( $container, array $val ) {
- $this->memCache->add( $this->containerCacheKey( $container ), $val, 14 * 86400 );
+ $this->memCache->set( $this->containerCacheKey( $container ), $val, 14 * 86400 );
}
/**
@@ -1602,7 +1623,7 @@ abstract class FileBackendStore extends FileBackend {
* @param string $container Resolved container name
*/
final protected function deleteContainerCache( $container ) {
- if ( !$this->memCache->set( $this->containerCacheKey( $container ), 'PURGED', 300 ) ) {
+ if ( !$this->memCache->delete( $this->containerCacheKey( $container ), 300 ) ) {
trigger_error( "Unable to delete stat cache for container $container." );
}
}
@@ -1682,21 +1703,8 @@ abstract class FileBackendStore extends FileBackend {
$age = time() - wfTimestamp( TS_UNIX, $val['mtime'] );
$ttl = min( 7 * 86400, max( 300, floor( .1 * $age ) ) );
$key = $this->fileCacheKey( $path );
- // Set the cache unless it is currently salted with the value "PURGED".
- // Using add() handles this except it also is a no-op in that case where
- // the current value is not "latest" but $val is, so use CAS in that case.
- if ( !$this->memCache->add( $key, $val, $ttl ) && !empty( $val['latest'] ) ) {
- $this->memCache->merge(
- $key,
- function ( BagOStuff $cache, $key, $cValue ) use ( $val ) {
- return ( is_array( $cValue ) && empty( $cValue['latest'] ) )
- ? $val // update the stat cache with the lastest info
- : false; // do nothing (cache is salted or some error happened)
- },
- $ttl,
- 1
- );
- }
+ // Set the cache unless it is currently salted.
+ $this->memCache->set( $key, $val, $ttl );
}
/**
@@ -1712,7 +1720,7 @@ abstract class FileBackendStore extends FileBackend {
if ( $path === null ) {
return; // invalid storage path
}
- if ( !$this->memCache->set( $this->fileCacheKey( $path ), 'PURGED', 300 ) ) {
+ if ( !$this->memCache->delete( $this->fileCacheKey( $path ), 300 ) ) {
trigger_error( "Unable to delete stat cache for file $path." );
}
}
diff --git a/includes/filebackend/FileOp.php b/includes/filebackend/FileOp.php
index 66d87943..5d4e8e11 100644
--- a/includes/filebackend/FileOp.php
+++ b/includes/filebackend/FileOp.php
@@ -577,9 +577,9 @@ class StoreFileOp extends FileOp {
}
protected function getSourceSha1Base36() {
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$hash = sha1_file( $this->params['src'] );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( $hash !== false ) {
$hash = wfBaseConvert( $hash, 16, 36, 31 );
}
diff --git a/includes/filebackend/MemoryFileBackend.php b/includes/filebackend/MemoryFileBackend.php
index 7c2f8256..2879ddde 100644
--- a/includes/filebackend/MemoryFileBackend.php
+++ b/includes/filebackend/MemoryFileBackend.php
@@ -35,6 +35,10 @@ class MemoryFileBackend extends FileBackendStore {
/** @var array Map of (file path => (data,mtime) */
protected $files = array();
+ public function getFeatures() {
+ return self::ATTR_UNICODE_PATHS;
+ }
+
public function isPathUsableInternal( $storagePath ) {
return true;
}
@@ -67,9 +71,9 @@ class MemoryFileBackend extends FileBackendStore {
return $status;
}
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$data = file_get_contents( $params['src'] );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( $data === false ) { // source doesn't exist?
$status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
diff --git a/includes/filebackend/SwiftFileBackend.php b/includes/filebackend/SwiftFileBackend.php
index 5f406c9b..408194f4 100644
--- a/includes/filebackend/SwiftFileBackend.php
+++ b/includes/filebackend/SwiftFileBackend.php
@@ -128,7 +128,9 @@ class SwiftFileBackend extends FileBackendStore {
// HTTP helper client
$this->http = new MultiHttpClient( array() );
// Cache container information to mask latency
- $this->memCache = wfGetMainCache();
+ if ( isset( $config['wanCache'] ) && $config['wanCache'] instanceof WANObjectCache ) {
+ $this->memCache = $config['wanCache'];
+ }
// Process cache for container info
$this->containerStatCache = new ProcessCacheLRU( 300 );
// Cache auth token information to avoid RTTs
@@ -136,13 +138,12 @@ class SwiftFileBackend extends FileBackendStore {
if ( PHP_SAPI === 'cli' ) {
$this->srvCache = wfGetMainCache(); // preferrably memcached
} else {
- try { // look for APC, XCache, WinCache, ect...
- $this->srvCache = ObjectCache::newAccelerator( array() );
- } catch ( Exception $e ) {
- }
+ // look for APC, XCache, WinCache, ect...
+ $this->srvCache = ObjectCache::newAccelerator( CACHE_NONE );
}
+ } else {
+ $this->srvCache = new EmptyBagOStuff();
}
- $this->srvCache = $this->srvCache ?: new EmptyBagOStuff();
}
public function getFeatures() {
@@ -171,30 +172,40 @@ class SwiftFileBackend extends FileBackendStore {
/**
* Sanitize and filter the custom headers from a $params array.
- * We only allow certain Content- and X-Content- headers.
+ * Only allows certain "standard" Content- and X-Content- headers.
*
* @param array $params
* @return array Sanitized value of 'headers' field in $params
*/
protected function sanitizeHdrs( array $params ) {
+ return isset( $params['headers'] )
+ ? $this->getCustomHeaders( $params['headers'] )
+ : array();
+
+ }
+
+ /**
+ * @param array $rawHeaders
+ * @return array Custom non-metadata HTTP headers
+ */
+ protected function getCustomHeaders( array $rawHeaders ) {
$headers = array();
// Normalize casing, and strip out illegal headers
- if ( isset( $params['headers'] ) ) {
- foreach ( $params['headers'] as $name => $value ) {
- $name = strtolower( $name );
- if ( preg_match( '/^content-(type|length)$/', $name ) ) {
- continue; // blacklisted
- } elseif ( preg_match( '/^(x-)?content-/', $name ) ) {
- $headers[$name] = $value; // allowed
- } elseif ( preg_match( '/^content-(disposition)/', $name ) ) {
- $headers[$name] = $value; // allowed
- }
+ foreach ( $rawHeaders as $name => $value ) {
+ $name = strtolower( $name );
+ if ( preg_match( '/^content-(type|length)$/', $name ) ) {
+ continue; // blacklisted
+ } elseif ( preg_match( '/^(x-)?content-/', $name ) ) {
+ $headers[$name] = $value; // allowed
+ } elseif ( preg_match( '/^content-(disposition)/', $name ) ) {
+ $headers[$name] = $value; // allowed
}
}
// By default, Swift has annoyingly low maximum header value limits
if ( isset( $headers['content-disposition'] ) ) {
$disposition = '';
+ // @note: assume FileBackend::makeContentDisposition() already used
foreach ( explode( ';', $headers['content-disposition'] ) as $part ) {
$part = trim( $part );
$new = ( $disposition === '' ) ? $part : "{$disposition};{$part}";
@@ -210,6 +221,35 @@ class SwiftFileBackend extends FileBackendStore {
return $headers;
}
+ /**
+ * @param array $rawHeaders
+ * @return array Custom metadata headers
+ */
+ protected function getMetadataHeaders( array $rawHeaders ) {
+ $headers = array();
+ foreach ( $rawHeaders as $name => $value ) {
+ $name = strtolower( $name );
+ if ( strpos( $name, 'x-object-meta-' ) === 0 ) {
+ $headers[$name] = $value;
+ }
+ }
+
+ return $headers;
+ }
+
+ /**
+ * @param array $rawHeaders
+ * @return array Custom metadata headers with prefix removed
+ */
+ protected function getMetadata( array $rawHeaders ) {
+ $metadata = array();
+ foreach ( $this->getMetadataHeaders( $rawHeaders ) as $name => $value ) {
+ $metadata[substr( $name, strlen( 'x-object-meta-' ) )] = $value;
+ }
+
+ return $metadata;
+ }
+
protected function doCreateInternal( array $params ) {
$status = Status::newGood();
@@ -235,16 +275,16 @@ class SwiftFileBackend extends FileBackendStore {
'body' => $params['content']
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 412 ) {
$status->fatal( 'backend-fail-contenttype', $params['dst'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
@@ -268,9 +308,9 @@ class SwiftFileBackend extends FileBackendStore {
return $status;
}
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$sha1Hash = sha1_file( $params['src'] );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( $sha1Hash === false ) { // source doesn't exist?
$status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
@@ -298,16 +338,16 @@ class SwiftFileBackend extends FileBackendStore {
'body' => $handle // resource
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 412 ) {
$status->fatal( 'backend-fail-contenttype', $params['dst'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
@@ -347,16 +387,16 @@ class SwiftFileBackend extends FileBackendStore {
) + $this->sanitizeHdrs( $params ), // extra headers merged into object
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
@@ -405,9 +445,9 @@ class SwiftFileBackend extends FileBackendStore {
);
}
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $request['method'] === 'PUT' && $rcode === 201 ) {
// good
@@ -416,7 +456,7 @@ class SwiftFileBackend extends FileBackendStore {
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
@@ -446,9 +486,9 @@ class SwiftFileBackend extends FileBackendStore {
'headers' => array()
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 204 ) {
// good
@@ -457,7 +497,7 @@ class SwiftFileBackend extends FileBackendStore {
$status->fatal( 'backend-fail-delete', $params['src'] );
}
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
@@ -505,16 +545,16 @@ class SwiftFileBackend extends FileBackendStore {
'headers' => $metaHdrs + $customHdrs
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 202 ) {
// good
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-describe', $params['src'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
@@ -664,17 +704,24 @@ class SwiftFileBackend extends FileBackendStore {
return $objHdrs; // nothing to do
}
+ /** @noinspection PhpUnusedLocalVariableInspection */
$ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
- trigger_error( "$path was not stored with SHA-1 metadata.", E_USER_WARNING );
+ wfDebugLog( 'SwiftBackend', __METHOD__ . ": $path was not stored with SHA-1 metadata." );
+
+ $objHdrs['x-object-meta-sha1base36'] = false;
$auth = $this->getAuthentication();
if ( !$auth ) {
- $objHdrs['x-object-meta-sha1base36'] = false;
-
return $objHdrs; // failed
}
+ // Find prior custom HTTP headers
+ $postHeaders = $this->getCustomHeaders( $objHdrs );
+ // Find prior metadata headers
+ $postHeaders += $this->getMetadataHeaders( $objHdrs );
+
$status = Status::newGood();
+ /** @noinspection PhpUnusedLocalVariableInspection */
$scopeLockS = $this->getScopedFileLocks( array( $path ), LockManager::LOCK_UW, $status );
if ( $status->isOK() ) {
$tmpFile = $this->getLocalCopy( array( 'src' => $path, 'latest' => 1 ) );
@@ -682,20 +729,24 @@ class SwiftFileBackend extends FileBackendStore {
$hash = $tmpFile->getSha1Base36();
if ( $hash !== false ) {
$objHdrs['x-object-meta-sha1base36'] = $hash;
+ // Merge new SHA1 header into the old ones
+ $postHeaders['x-object-meta-sha1base36'] = $hash;
list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $path );
- list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
+ list( $rcode ) = $this->http->run( array(
'method' => 'POST',
'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
- 'headers' => $this->authTokenHeaders( $auth ) + $objHdrs
+ 'headers' => $this->authTokenHeaders( $auth ) + $postHeaders
) );
if ( $rcode >= 200 && $rcode <= 299 ) {
+ $this->deleteFileCache( $path );
+
return $objHdrs; // success
}
}
}
}
- trigger_error( "Unable to set SHA-1 metadata for $path", E_USER_WARNING );
- $objHdrs['x-object-meta-sha1base36'] = false;
+
+ wfDebugLog( 'SwiftBackend', __METHOD__ . ": unable to set SHA-1 metadata for $path" );
return $objHdrs; // failed
}
@@ -1544,22 +1595,16 @@ class SwiftFileBackend extends FileBackendStore {
*/
protected function getStatFromHeaders( array $rhdrs ) {
// Fetch all of the custom metadata headers
- $metadata = array();
- foreach ( $rhdrs as $name => $value ) {
- if ( strpos( $name, 'x-object-meta-' ) === 0 ) {
- $metadata[substr( $name, strlen( 'x-object-meta-' ) )] = $value;
- }
- }
+ $metadata = $this->getMetadata( $rhdrs );
// Fetch all of the custom raw HTTP headers
$headers = $this->sanitizeHdrs( array( 'headers' => $rhdrs ) );
+
return array(
// Convert various random Swift dates to TS_MW
'mtime' => $this->convertSwiftDate( $rhdrs['last-modified'], TS_MW ),
// Empty objects actually return no content-length header in Ceph
'size' => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0,
- 'sha1' => isset( $rhdrs['x-object-meta-sha1base36'] )
- ? $rhdrs['x-object-meta-sha1base36']
- : null,
+ 'sha1' => isset( $metadata['sha1base36'] ) ? $metadata['sha1base36'] : null,
// Note: manifiest ETags are not an MD5 of the file
'md5' => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null,
'xattr' => array( 'metadata' => $metadata, 'headers' => $headers )
diff --git a/includes/filebackend/TempFSFile.php b/includes/filebackend/TempFSFile.php
index 791be7fc..46b53600 100644
--- a/includes/filebackend/TempFSFile.php
+++ b/includes/filebackend/TempFSFile.php
@@ -59,15 +59,14 @@ class TempFSFile extends FSFile {
$ext = ( $extension != '' ) ? ".{$extension}" : "";
for ( $attempt = 1; true; $attempt++ ) {
$path = "{$base}-{$attempt}{$ext}";
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$newFileHandle = fopen( $path, 'x' );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( $newFileHandle ) {
fclose( $newFileHandle );
break; // got it
}
if ( $attempt >= 5 ) {
-
return null; // give up
}
}
@@ -84,9 +83,9 @@ class TempFSFile extends FSFile {
*/
public function purge() {
$this->canDelete = false; // done
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$ok = unlink( $this->path );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
unset( self::$pathsCollect[$this->path] );
@@ -96,7 +95,7 @@ class TempFSFile extends FSFile {
/**
* Clean up the temporary file only after an object goes out of scope
*
- * @param stdClass $object
+ * @param object $object
* @return TempFSFile This object
*/
public function bind( $object ) {
@@ -144,9 +143,9 @@ class TempFSFile extends FSFile {
*/
public static function purgeAllOnShutdown() {
foreach ( self::$pathsCollect as $path ) {
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
unlink( $path );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
}
}
diff --git a/includes/filebackend/lockmanager/DBLockManager.php b/includes/filebackend/lockmanager/DBLockManager.php
index 39a55635..b81cf3e4 100644
--- a/includes/filebackend/lockmanager/DBLockManager.php
+++ b/includes/filebackend/lockmanager/DBLockManager.php
@@ -96,7 +96,7 @@ abstract class DBLockManager extends QuorumLockManager {
// Tracks peers that couldn't be queried recently to avoid lengthy
// connection timeouts. This is useless if each bucket has one peer.
try {
- $this->statusCache = ObjectCache::newAccelerator( array() );
+ $this->statusCache = ObjectCache::newAccelerator();
} catch ( Exception $e ) {
trigger_error( __CLASS__ .
" using multiple DB peers without apc, xcache, or wincache." );
diff --git a/includes/filebackend/lockmanager/FSLockManager.php b/includes/filebackend/lockmanager/FSLockManager.php
index bce6b34c..6f46f0e4 100644
--- a/includes/filebackend/lockmanager/FSLockManager.php
+++ b/includes/filebackend/lockmanager/FSLockManager.php
@@ -117,9 +117,9 @@ class FSLockManager extends LockManager {
if ( isset( $this->handles[$path] ) ) {
$handle = $this->handles[$path];
} else {
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$handle = fopen( $this->getLockPath( $path ), 'a+' );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( !$handle ) { // lock dir missing?
wfMkdirParents( $this->lockDir );
$handle = fopen( $this->getLockPath( $path ), 'a+' ); // try again
diff --git a/includes/filebackend/lockmanager/LockManager.php b/includes/filebackend/lockmanager/LockManager.php
index 615ba77e..8115fd42 100644
--- a/includes/filebackend/lockmanager/LockManager.php
+++ b/includes/filebackend/lockmanager/LockManager.php
@@ -102,7 +102,6 @@ abstract class LockManager {
* @since 1.22
*/
final public function lockByType( array $pathsByType, $timeout = 0 ) {
- $status = Status::newGood();
$pathsByType = $this->normalizePathsByType( $pathsByType );
$msleep = array( 0, 50, 100, 300, 500 ); // retry backoff times
$start = microtime( true );