 core/modules/file/config/install/file.settings.yml |  2 +-
 core/modules/file/config/schema/file.schema.yml    |  3 ++
 core/modules/file/file.install                     | 30 +++++++++++++++++
 core/modules/file/file.module                      | 38 ++++++++++++++++++++++
 core/modules/file/file.services.yml                |  2 +-
 .../src/FileUsage/DatabaseFileUsageBackend.php     |  6 +++-
 core/modules/file/src/FileUsage/FileUsageBase.php  | 26 +++++++++++++++
 core/modules/file/src/Tests/FileAdminTest.php      | 33 +++++++++++++++++++
 .../file/src/Tests/FileFieldRevisionTest.php       |  5 +++
 core/modules/file/src/Tests/FileListingTest.php    |  5 +++
 .../file/src/Tests/FileOnTranslatedEntityTest.php  |  5 +++
 core/modules/file/src/Tests/FilePrivateTest.php    |  4 +++
 core/modules/file/tests/src/Kernel/DeleteTest.php  |  5 +++
 core/modules/file/tests/src/Kernel/UsageTest.php   | 26 ++++++++++++++-
 .../src/Tests/ImageOnTranslatedEntityTest.php      |  3 ++
 core/modules/system/src/Form/FileSystemForm.php    |  4 +--
 core/modules/user/src/Tests/UserPictureTest.php    |  6 ++++
 17 files changed, 197 insertions(+), 6 deletions(-)

diff --git a/core/modules/file/config/install/file.settings.yml b/core/modules/file/config/install/file.settings.yml
index e652277..9191a0b 100644
--- a/core/modules/file/config/install/file.settings.yml
+++ b/core/modules/file/config/install/file.settings.yml
@@ -3,4 +3,4 @@ description:
   length: 128
 icon:
   directory: 'core/modules/file/icons'
-
+make_unused_managed_files_temporary: false
diff --git a/core/modules/file/config/schema/file.schema.yml b/core/modules/file/config/schema/file.schema.yml
index b9f8918..42d57d9 100644
--- a/core/modules/file/config/schema/file.schema.yml
+++ b/core/modules/file/config/schema/file.schema.yml
@@ -21,6 +21,9 @@ file.settings:
         directory:
           type: path
           label: 'Directory'
+    make_unused_managed_files_temporary:
+      type: boolean
+      label: 'Controls if unused files should be marked temporary'
 
 field.storage_settings.file:
   type: base_entity_reference_field_settings
diff --git a/core/modules/file/file.install b/core/modules/file/file.install
index 9134a25..89426f8 100644
--- a/core/modules/file/file.install
+++ b/core/modules/file/file.install
@@ -5,6 +5,8 @@
  * Install, update and uninstall functions for File module.
  */
 
+use Drupal\Core\Url;
+
 /**
  * Implements hook_schema().
  */
@@ -112,7 +114,35 @@ function file_requirements($phase) {
       'value' => $value,
       'description' => $description,
     ];
+
+    $file_config = \Drupal::configFactory()->get('file.settings');
+    $make_unused_managed_files_temporary = $file_config->get('make_unused_managed_files_temporary');
+    $requirements['file_orphaned_deletion'] = [
+      'title' => t('Unused file deletion'),
+      'description' => t("There are currently known bugs with the identification of unused files in core. This can lead to files being deleted even though they're in use."),
+      'value' => $make_unused_managed_files_temporary
+        ? t('Enabled — to avoid data loss, <a href=":url">disable unused file deletion</a>.', [
+          ':url' => Url::fromRoute('system.file_system_settings', [], ['fragment' => 'edit-make-unused-managed-files-temporary'])->toString()
+        ])
+        : t('Disabled (no risk of data loss)'),
+      'severity' => $make_unused_managed_files_temporary ? REQUIREMENT_WARNING : REQUIREMENT_OK,
+    ];
   }
 
   return $requirements;
 }
+
+/**
+ * Prevent unused files from being deleted.
+ */
+function file_update_8300() {
+  // Disable deletion of unused permanent files.
+  \Drupal::configFactory()->getEditable('file.settings')
+    ->set('make_unused_managed_files_temporary', FALSE)
+    ->save();
+
+  return t('Files that have no remaining usages are no longer deleted by default. It is recommended to leave <a href=":url">\'Schedule all unused files for deletion\'</a> disabled to prevent the loss of files.', [
+    ':url' => Url::fromRoute('system.file_system_settings', [], ['fragment' => 'edit-make-unused-managed-files-temporary'])
+      ->toString()
+  ]);
+}
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 6902db6..e00b2d0 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -1568,3 +1568,41 @@ function _views_file_status($choice = NULL) {
 
   return $status;
 }
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function file_form_system_file_system_settings_alter(&$form, FormStateInterface $form_state) {
+  $config = \Drupal::configFactory()->getEditable('file.settings');
+
+  $form['temporary_files'] = [
+    '#type' => 'details',
+    '#title' => t('Temporary and other unused files'),
+    '#open' => TRUE
+  ];
+
+  // Move the temporary_maximum_age settings.
+  $temporary_maximum_age_element = $form['temporary_maximum_age'];
+  unset($form['temporary_maximum_age']);
+  $form['temporary_files']['temporary_maximum_age'] = $temporary_maximum_age_element;
+
+  $form['temporary_files']['make_unused_managed_files_temporary'] = [
+    '#type' => 'checkbox',
+    '#title' => t('Schedule all unused files for deletion'),
+    '#default_value' => $config->get('make_unused_managed_files_temporary'),
+    '#description' => t('If enabled, all files that are not referenced will be deleted after the time set above. For example, enabling this will delete files that previously were used by deleted content. <strong>Warning:</strong> There are currently known bugs with file usage counting. It is recommended to leave disabled to prevent the loss of files.'),
+  ];
+
+  $form['#submit'][] = 'file_system_file_settings_submit';
+}
+
+/**
+ * Form submission handler for system_logging_settings().
+ *
+ * @see syslog_form_system_logging_settings_alter()
+ */
+function file_system_file_settings_submit($form, FormStateInterface $form_state) {
+  \Drupal::configFactory()->getEditable('file.settings')
+    ->set('make_unused_managed_files_temporary', $form_state->getValue('make_unused_managed_files_temporary'))
+    ->save();
+}
diff --git a/core/modules/file/file.services.yml b/core/modules/file/file.services.yml
index 1c463af..03eb7bc 100644
--- a/core/modules/file/file.services.yml
+++ b/core/modules/file/file.services.yml
@@ -1,6 +1,6 @@
 services:
   file.usage:
     class: Drupal\file\FileUsage\DatabaseFileUsageBackend
-    arguments: ['@database']
+    arguments: ['@database', 'file_usage', '@config.factory']
     tags:
       - { name: backend_overridable }
diff --git a/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php b/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php
index cfb0c44..2b19954 100644
--- a/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php
+++ b/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\file\FileUsage;
 
+use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\file\FileInterface;
 
@@ -32,8 +33,11 @@ class DatabaseFileUsageBackend extends FileUsageBase {
    *   information.
    * @param string $table
    *   (optional) The table to store file usage info. Defaults to 'file_usage'.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   (optional) The config factory.
    */
-  public function __construct(Connection $connection, $table = 'file_usage') {
+  public function __construct(Connection $connection, $table = 'file_usage', ConfigFactoryInterface $config_factory = NULL) {
+    parent::__construct($config_factory);
     $this->connection = $connection;
 
     $this->tableName = $table;
diff --git a/core/modules/file/src/FileUsage/FileUsageBase.php b/core/modules/file/src/FileUsage/FileUsageBase.php
index c90359b..ba59cd5 100644
--- a/core/modules/file/src/FileUsage/FileUsageBase.php
+++ b/core/modules/file/src/FileUsage/FileUsageBase.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\file\FileUsage;
 
+use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\file\FileInterface;
 
 /**
@@ -10,6 +11,27 @@
 abstract class FileUsageBase implements FileUsageInterface {
 
   /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * Creates a FileUsageBase object.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   (optional) The config factory. Defaults to NULL and will use
+   *   \Drupal::configFactory() instead.
+   *
+   * @deprecated The $config_factory parameter will become required in Drupal
+   *   9.0.0.
+   */
+  public function __construct(ConfigFactoryInterface $config_factory = NULL) {
+    $this->configFactory = $config_factory ?: \Drupal::configFactory();
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function add(FileInterface $file, $module, $type, $id, $count = 1) {
@@ -24,6 +46,10 @@ public function add(FileInterface $file, $module, $type, $id, $count = 1) {
    * {@inheritdoc}
    */
   public function delete(FileInterface $file, $module, $type = NULL, $id = NULL, $count = 1) {
+    // Do not actually mark files as temporary when the behavior is disabled.
+    if (!$this->configFactory->get('file.settings')->get('make_unused_managed_files_temporary')) {
+      return;
+    }
     // If there are no more remaining usages of this file, mark it as temporary,
     // which result in a delete through system_cron().
     $usage = \Drupal::service('file.usage')->listUsage($file);
diff --git a/core/modules/file/src/Tests/FileAdminTest.php b/core/modules/file/src/Tests/FileAdminTest.php
new file mode 100644
index 0000000..f352b29
--- /dev/null
+++ b/core/modules/file/src/Tests/FileAdminTest.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\file\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests file_form_system_file_system_settings_alter().
+ *
+ * @group file
+ */
+class FileAdminTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['file'];
+
+  /**
+   * Tests changing the file configuration settings through the UI.
+   */
+  function testFileAdmin() {
+    $this->drupalLogin($this->drupalCreateUser(['administer site configuration']));
+    $this->assertFalse($this->config('file.settings')
+      ->get('make_unused_managed_files_temporary'), 'The file.settings:make_unused_managed_files_temporary is set to FALSE.');
+    $this->drupalPostForm('admin/config/media/file-system', ['make_unused_managed_files_temporary' => TRUE], t('Save configuration'));
+    $this->assertTrue($this->config('file.settings')
+      ->get('make_unused_managed_files_temporary'), 'The file.settings:make_unused_managed_files_temporary has been set to TRUE.');
+  }
+
+}
diff --git a/core/modules/file/src/Tests/FileFieldRevisionTest.php b/core/modules/file/src/Tests/FileFieldRevisionTest.php
index 7b7b4d3..04fbcb8 100644
--- a/core/modules/file/src/Tests/FileFieldRevisionTest.php
+++ b/core/modules/file/src/Tests/FileFieldRevisionTest.php
@@ -22,6 +22,11 @@ class FileFieldRevisionTest extends FileFieldTestBase {
    *    should be deleted also.
    */
   public function testRevisions() {
+    // This test expects unused managed files to be marked as a temporary file
+    // and then deleted up by file_cron().
+    $this->config('file.settings')
+      ->set('make_unused_managed_files_temporary', TRUE)
+      ->save();
     $node_storage = $this->container->get('entity.manager')->getStorage('node');
     $type_name = 'article';
     $field_name = strtolower($this->randomMachineName());
diff --git a/core/modules/file/src/Tests/FileListingTest.php b/core/modules/file/src/Tests/FileListingTest.php
index e348949..cca21c5 100644
--- a/core/modules/file/src/Tests/FileListingTest.php
+++ b/core/modules/file/src/Tests/FileListingTest.php
@@ -30,6 +30,11 @@ class FileListingTest extends FileFieldTestBase {
   protected function setUp() {
     parent::setUp();
 
+    // This test expects unused managed files to be marked as a temporary file.
+    $this->config('file.settings')
+      ->set('make_unused_managed_files_temporary', TRUE)
+      ->save();
+
     $this->adminUser = $this->drupalCreateUser(['access files overview', 'bypass node access']);
     $this->baseUser = $this->drupalCreateUser();
     $this->createFileField('file', 'node', 'article', [], ['file_extensions' => 'txt png']);
diff --git a/core/modules/file/src/Tests/FileOnTranslatedEntityTest.php b/core/modules/file/src/Tests/FileOnTranslatedEntityTest.php
index 5f1e707..b8a22ae 100644
--- a/core/modules/file/src/Tests/FileOnTranslatedEntityTest.php
+++ b/core/modules/file/src/Tests/FileOnTranslatedEntityTest.php
@@ -29,6 +29,11 @@ class FileOnTranslatedEntityTest extends FileFieldTestBase {
   protected function setUp() {
     parent::setUp();
 
+    // This test expects unused managed files to be marked as temporary a file.
+    $this->config('file.settings')
+      ->set('make_unused_managed_files_temporary', TRUE)
+      ->save();
+
     // Create the "Basic page" node type.
     // @todo Remove the disabling of new revision creation in
     //   https://www.drupal.org/node/1239558.
diff --git a/core/modules/file/src/Tests/FilePrivateTest.php b/core/modules/file/src/Tests/FilePrivateTest.php
index 6808a47..0174a89 100644
--- a/core/modules/file/src/Tests/FilePrivateTest.php
+++ b/core/modules/file/src/Tests/FilePrivateTest.php
@@ -27,6 +27,10 @@ protected function setUp() {
     node_access_test_add_field(NodeType::load('article'));
     node_access_rebuild();
     \Drupal::state()->set('node_access_test.private', TRUE);
+    // This test expects unused managed files to be marked as a temporary file.
+    $this->config('file.settings')
+      ->set('make_unused_managed_files_temporary', TRUE)
+      ->save();
   }
 
   /**
diff --git a/core/modules/file/tests/src/Kernel/DeleteTest.php b/core/modules/file/tests/src/Kernel/DeleteTest.php
index 3b868c0..de5a5bc 100644
--- a/core/modules/file/tests/src/Kernel/DeleteTest.php
+++ b/core/modules/file/tests/src/Kernel/DeleteTest.php
@@ -28,6 +28,11 @@ public function testUnused() {
    * Tries deleting a file that is in use.
    */
   public function testInUse() {
+    // This test expects unused managed files to be marked as a temporary file
+    // and then deleted up by file_cron().
+    $this->config('file.settings')
+      ->set('make_unused_managed_files_temporary', TRUE)
+      ->save();
     $file = $this->createFile();
     $file_usage = $this->container->get('file.usage');
     $file_usage->add($file, 'testing', 'test', 1);
diff --git a/core/modules/file/tests/src/Kernel/UsageTest.php b/core/modules/file/tests/src/Kernel/UsageTest.php
index 672de0f..88812a1 100644
--- a/core/modules/file/tests/src/Kernel/UsageTest.php
+++ b/core/modules/file/tests/src/Kernel/UsageTest.php
@@ -75,10 +75,33 @@ public function testAddUsage() {
   }
 
   /**
+   * Tests file usage deletion when files are made temporary.
+   */
+  function testRemoveUsageTemporary() {
+    $this->config('file.settings')
+      ->set('make_unused_managed_files_temporary', TRUE)
+      ->save();
+    $file = $this->doTestRemoveUsage();
+    $this->assertTrue($file->isTemporary());
+  }
+
+  /**
+   * Tests file usage deletion when files are made temporary.
+   */
+  function testRemoveUsageNonTemporary() {
+    $this->config('file.settings')
+      ->set('make_unused_managed_files_temporary', FALSE)
+      ->save();
+    $file = $this->doTestRemoveUsage();
+    $this->assertFalse($file->isTemporary());
+  }
+
+  /**
    * Tests \Drupal\file\FileUsage\DatabaseFileUsageBackend::delete().
    */
-  public function testRemoveUsage() {
+  public function doTestRemoveUsage() {
     $file = $this->createFile();
+    $file->setPermanent();
     $file_usage = $this->container->get('file.usage');
     db_insert('file_usage')
       ->fields([
@@ -116,6 +139,7 @@ public function testRemoveUsage() {
       ->execute()
       ->fetchField();
     $this->assertIdentical(FALSE, $count, 'Decrementing non-exist record complete.');
+    return $file;
   }
 
   /**
diff --git a/core/modules/image/src/Tests/ImageOnTranslatedEntityTest.php b/core/modules/image/src/Tests/ImageOnTranslatedEntityTest.php
index e1f70d7..c5f16cf 100644
--- a/core/modules/image/src/Tests/ImageOnTranslatedEntityTest.php
+++ b/core/modules/image/src/Tests/ImageOnTranslatedEntityTest.php
@@ -29,6 +29,9 @@ class ImageOnTranslatedEntityTest extends ImageFieldTestBase {
   protected function setUp() {
     parent::setUp();
 
+    // This test expects unused managed files to be marked as a temporary file.
+    $this->config('file.settings')->set('make_unused_managed_files_temporary', TRUE)->save();
+
     // Create the "Basic page" node type.
     // @todo Remove the disabling of new revision creation in
     //   https://www.drupal.org/node/1239558.
diff --git a/core/modules/system/src/Form/FileSystemForm.php b/core/modules/system/src/Form/FileSystemForm.php
index ff0b792..d3a6cae 100644
--- a/core/modules/system/src/Form/FileSystemForm.php
+++ b/core/modules/system/src/Form/FileSystemForm.php
@@ -125,10 +125,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $period[0] = t('Never');
     $form['temporary_maximum_age'] = [
       '#type' => 'select',
-      '#title' => t('Delete orphaned files after'),
+      '#title' => t('Delete temporary files after'),
       '#default_value' => $config->get('temporary_maximum_age'),
       '#options' => $period,
-      '#description' => t('Orphaned files are not referenced from any content but remain in the file system and may appear in administrative listings. <strong>Warning:</strong> If enabled, orphaned files will be permanently deleted and may not be recoverable.'),
+      '#description' => t('Temporary files are not referenced, but are in the file system and therefore may show up in administrative lists. <strong>Warning:</strong> If enabled, temporary files will be permanently deleted and may not be recoverable.'),
     ];
 
     return parent::buildForm($form, $form_state);
diff --git a/core/modules/user/src/Tests/UserPictureTest.php b/core/modules/user/src/Tests/UserPictureTest.php
index 6d546f0..d850413 100644
--- a/core/modules/user/src/Tests/UserPictureTest.php
+++ b/core/modules/user/src/Tests/UserPictureTest.php
@@ -33,6 +33,12 @@ class UserPictureTest extends WebTestBase {
   protected function setUp() {
     parent::setUp();
 
+    // This test expects unused managed files to be marked temporary and then
+    // cleaned up by file_cron().
+    $this->config('file.settings')
+      ->set('make_unused_managed_files_temporary', TRUE)
+      ->save();
+
     $this->webUser = $this->drupalCreateUser([
       'access content',
       'access comments',
