diff --git a/modules/file/file.field.inc b/modules/file/file.field.inc
index d592381..60b40bb 100644
--- a/modules/file/file.field.inc
+++ b/modules/file/file.field.inc
@@ -1009,6 +1009,30 @@ function file_field_formatter_view($entity_type, $entity, $field, $instance, $la
 }
 
 /**
+ * Determine whether a field references files stored in {file_managed}.
+ *
+ * @param array $field
+ *   A field array.
+ *
+ * @return
+ *   The field column if the field references {file_managed}.fid, typically
+ *   fid, FALSE if it doesn't.
+ */
+
+function file_field_find_file_reference_column($field) {
+  foreach ($field['foreign keys'] as $data) {
+    if ($data['table'] == 'file_managed') {
+      foreach ($data['columns'] as $field_column => $column) {
+        if ($column == 'fid') {
+          return $field_column;
+        }
+      }
+    }
+  }
+  return FALSE;
+}
+
+/**
  * Returns HTML for a file attachments table.
  *
  * @param $variables
diff --git a/modules/file/file.module b/modules/file/file.module
index 9e091af..a0cc7e4 100644
--- a/modules/file/file.module
+++ b/modules/file/file.module
@@ -148,7 +148,7 @@ function file_file_download($uri, $field_type = 'file') {
   // an image preview on a node/add form) in which case, allow download by the
   // file's owner.
   if (empty($references) && ($file->status == FILE_STATUS_PERMANENT || $file->uid != $user->uid)) {
-      return;
+    return;
   }
 
   // Default to allow access.
@@ -160,44 +160,24 @@ function file_file_download($uri, $field_type = 'file') {
   // and no reference denied access, access is granted as well. If at least one
   // reference denied access, access is denied.
   foreach ($references as $field_name => $field_references) {
-    foreach ($field_references as $entity_type => $type_references) {
-      foreach ($type_references as $id => $reference) {
-        // Try to load $entity and $field.
-        $entity = entity_load($entity_type, array($id));
-        $entity = reset($entity);
+    foreach ($field_references as $entity_type => $entities) {
+      foreach ($entities as $entity) {
         $field = field_info_field($field_name);
 
-        // Load the field item that references the file.
-        $field_item = NULL;
-        if ($entity) {
-          // Load all field items for that entity.
-          $field_items = field_get_items($entity_type, $entity, $field_name);
-
-          // Find the field item with the matching URI.
-          foreach ($field_items as $item) {
-            if ($item['uri'] == $uri) {
-              $field_item = $item;
-              break;
-            }
-          }
-        }
-
-        // Check that $entity, $field and $field_item were loaded successfully
-        // and check if access to that field is not disallowed. If any of these
-        // checks fail, stop checking access for this reference.
-        if (empty($entity) || empty($field) || empty($field_item) || !field_access('view', $field, $entity_type, $entity)) {
+        // Check if access to this field is not disallowed.
+        if (!field_access('view', $field, $entity_type, $entity)) {
           $denied = TRUE;
-          break;
+          continue;
         }
 
         // Invoke hook and collect grants/denies for download access.
         // Default to FALSE and let entities overrule this ruling.
         $grants = array('system' => FALSE);
         foreach (module_implements('file_download_access') as $module) {
-          $grants = array_merge($grants, array($module => module_invoke($module, 'file_download_access', $field_item, $entity_type, $entity)));
+          $grants = array_merge($grants, array($module => module_invoke($module, 'file_download_access', $field, $entity_type, $entity)));
         }
         // Allow other modules to alter the returned grants/denies.
-        drupal_alter('file_download_access', $grants, $field_item, $entity_type, $entity);
+        drupal_alter('file_download_access', $grants, $field, $entity_type, $entity);
 
         if (in_array(TRUE, $grants)) {
           // If TRUE is returned, access is granted and no further checks are
@@ -1042,27 +1022,84 @@ function file_icon_map($file) {
  *   FIELD_LOAD_CURRENT to retrieve references only in the current revisions.
  * @param $field_type
  *   (optional) The name of a field type. If given, limits the reference check
- *   to fields of the given type.
+ *   to fields of the given type. If both $field and $field_type is given but
+ *   $field is not the same type as $field_type, an empty array will be
+ *   returned.
  *
  * @return
- *   An integer value.
+ *   A multidimensional array. The keys are field_name, entity_type,
+ *   entity_id and the value is an entity referencing this file.
  */
 function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file') {
-  $references = drupal_static(__FUNCTION__, array());
-  $fields = isset($field) ? array($field['field_name'] => $field) : field_info_fields();
-
-  foreach ($fields as $field_name => $file_field) {
-    if ((empty($field_type) || $file_field['type'] == $field_type) && !isset($references[$field_name])) {
-      // Get each time this file is used within a field.
-      $query = new EntityFieldQuery();
-      $query
-        ->fieldCondition($file_field, 'fid', $file->fid)
-        ->age($age);
-      $references[$field_name] = $query->execute();
+  $references = &drupal_static(__FUNCTION__, array());
+  $field_columns = &drupal_static(__FUNCTION__ . ':field_columns', array());
+
+  // Fill the static cache, disregard $field and $field_type for now.
+  if (!isset($references[$file->fid][$age])) {
+    $references[$file->fid][$age] = array();
+    $usage_list = file_usage_list($file);
+    $file_usage_list = isset($usage_list['file']) ? $usage_list['file'] : array();
+    foreach ($file_usage_list as $entity_type => $entity_ids) {
+     $entity_ids = array_keys($entity_ids); 
+     $entity_info = entity_get_info($entity_type);
+      // The usage table contains usage of every revision. If we are looking
+      // for every revision or the entity does not support revisions then
+      // every usage is already a match.
+      $match_entity_type = $age == FIELD_LOAD_REVISION || !isset($entity_info['entity keys']['revision']);
+      $entities = entity_load($entity_type, $entity_ids);
+      foreach ($entities as $entity) {
+        list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
+        // We need to find file fields for this entity type and bundle.
+        if (!isset($file_fields[$entity_type][$bundle])) {
+          $file_fields[$entity_type][$bundle] = array();
+          // This contains the possible field names.
+          $instances = field_info_instances($entity_type, $bundle);
+          foreach ($instances as $field_name => $instance) {
+            $current_field = field_info_field($field_name);
+            // If this is the first time this field type is seen, check
+            // whether it references files.
+            if (!isset($field_columns[$current_field['type']])) {
+              $field_columns[$current_field['type']] = file_field_find_file_reference_column($current_field);
+            }
+            // If the field type does reference files then record it.
+            if ($field_columns[$current_field['type']]) {
+              $file_fields[$entity_type][$bundle][$field_name] = $field_columns[$current_field['type']];
+            }
+          }
+        }
+        foreach ($file_fields[$entity_type][$bundle] as $field_name => $field_column) {
+          $match = $match_entity_type;
+          // If we didn't match yet then iterate over the field items to find
+          // the referenced file. This will fail if the usage checked is in a
+          // non-current revision because field items are from the current
+          // revision.
+          if (!$match && ($field_items = field_get_items($entity_type, $entity, $field_name))) {
+            foreach ($field_items as $item) {
+              if ($file->fid == $item[$field_column]) {
+                $match = TRUE;
+                break;
+              }
+            }
+          }
+          if ($match) {
+            $references[$file->fid][$age][$field_name][$entity_type][$id] = $entity;
+          }
+        }
+      }
     }
   }
-
-  return isset($field) ? $references[$field['field_name']] : array_filter($references);
+  $return = $references[$file->fid][$age];
+  // Filter the static cache down to the requested entries. The usual static
+  // cache is very small so this will be very fast.
+  if ($field || $field_type) {
+    foreach ($return as $field_name => $data) {
+      $current_field = field_info_field($field_name);
+      if (($field_type && $current_field['type'] != $field_type) || ($field && $field['id'] != $current_field['id'])) {
+        unset($return[$field_name]);
+      }
+    }
+  }
+  return $return;
 }
 
 /**
