Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Repair detached filecache entries through occ files:scan
  • Loading branch information
Vincent Petry authored and tomneedham committed Sep 26, 2017
commit b66caa92ab8cde144969692d27bc2ba80df3d530
43 changes: 39 additions & 4 deletions apps/files/lib/Command/Scan.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\Table;
use OC\Repair\RepairMismatchFileCachePath;
use OC\Migration\ConsoleOutput;
use OCP\Lock\ILockingProvider;
use OCP\Lock\LockedException;

class Scan extends Base {

Expand Down Expand Up @@ -90,6 +94,12 @@ protected function configure() {
null,
InputOption::VALUE_NONE,
'will rescan all files of all known users'
)
->addOption(
'repair',
null,
InputOption::VALUE_NONE,
'will repair detached filecache entries (slow)'
)->addOption(
'unscanned',
null,
Expand All @@ -107,9 +117,34 @@ public function checkScanWarning($fullPath, OutputInterface $output) {
}
}

protected function scanFiles($user, $path, $verbose, OutputInterface $output, $backgroundScan = false) {
protected function scanFiles($user, $path, $verbose, OutputInterface $output, $backgroundScan = false, $shouldRepair = false) {
$connection = $this->reconnectToDatabase($output);
$scanner = new \OC\Files\Utils\Scanner($user, $connection, \OC::$server->getLogger());
if ($shouldRepair) {
$scanner->listen('\OC\Files\Utils\Scanner', 'beforeScanStorage', function ($storage) use ($output, $connection) {
$lockingProvider = \OC::$server->getLockingProvider();
try {
// FIXME: this will lock the storage even if there is nothing to repair
$storage->acquireLock('', ILockingProvider::LOCK_EXCLUSIVE, $lockingProvider);
} catch (OCP\Lock\LockedException $e) {
$output->writeln("\t<error>Storage \"" . $storage->getCache()->getNumericStorageId() . '" cannot be repaired as it is currently in use, please try again later</error>');
return;
}
try {
// TODO: use DI
$repairStep = new RepairMismatchFileCachePath(
$connection,
\OC::$server->getMimeTypeLoader()
);
$repairStep->setStorageNumericId($storage->getCache()->getNumericStorageId());
$repairStep->setCountOnly(false);
$repairStep->run(new ConsoleOutput($output));
} finally {
$storage->releaseLock('', ILockingProvider::LOCK_EXCLUSIVE, $lockingProvider);
}
});
}

# check on each file/folder if there was a user interrupt (ctrl-c) and throw an exception
# printout and count
if ($verbose) {
Expand Down Expand Up @@ -156,7 +191,7 @@ protected function scanFiles($user, $path, $verbose, OutputInterface $output, $b
if ($backgroundScan) {
$scanner->backgroundScan($path);
}else {
$scanner->scan($path);
$scanner->scan($path, $shouldRepair);
}
} catch (ForbiddenException $e) {
$output->writeln("<error>Home storage for user $user not writable</error>");
Expand All @@ -166,7 +201,7 @@ protected function scanFiles($user, $path, $verbose, OutputInterface $output, $b
$output->writeln('Interrupted by user');
return;
} catch (\Exception $e) {
$output->writeln('<error>Exception during scan: ' . $e->getMessage() . "\n" . $e->getTraceAsString() . '</error>');
$output->writeln('<error>Exception during scan: ' . get_class($e) . ': ' . $e->getMessage() . "\n" . $e->getTraceAsString() . '</error>');
}
}

Expand Down Expand Up @@ -225,7 +260,7 @@ protected function execute(InputInterface $input, OutputInterface $output) {
if ($verbose) {$output->writeln(""); }
$output->writeln("Starting scan for user $user_count out of $users_total ($user)");
# full: printout data if $verbose was set
$this->scanFiles($user, $path, $verbose, $output, $input->getOption('unscanned'));
$this->scanFiles($user, $path, $verbose, $output, $input->getOption('unscanned'), $input->getOption('repair'));
} else {
$output->writeln("<error>Unknown user $user_count $user</error>");
}
Expand Down
7 changes: 6 additions & 1 deletion lib/private/Files/Utils/Scanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ public function scan($dir = '') {
}

// if the home storage isn't writable then the scanner is run as the wrong user
if ($storage->instanceOfStorage('\OC\Files\Storage\Home') and
$isHome = $storage->instanceOfStorage('\OC\Files\Storage\Home');
if ($isHome and
(!$storage->isCreatable('') or !$storage->isCreatable('files'))
) {
if ($storage->file_exists('') or $storage->getCache()->inCache('')) {
Expand All @@ -211,6 +212,9 @@ public function scan($dir = '') {
if ($storage->instanceOfStorage('OCA\Files_Sharing\ISharedStorage')) {
continue;
}

$this->emit('\OC\Files\Utils\Scanner', 'beforeScanStorage', [$storage]);

$relativePath = $mount->getInternalPath($dir);
$scanner = $storage->getScanner();
$scanner->setUseTransactions(false);
Expand Down Expand Up @@ -247,6 +251,7 @@ public function scan($dir = '') {
if ($this->useTransaction) {
$this->db->commit();
}
$this->emit('\OC\Files\Utils\Scanner', 'afterScanStorage', [$storage]);
}
}

Expand Down
Loading