Index: modules/file/file.field.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/file/file.field.inc,v
retrieving revision 1.34
diff -u -p -r1.34 file.field.inc
--- modules/file/file.field.inc	9 Sep 2010 23:28:16 -0000	1.34
+++ modules/file/file.field.inc	30 Sep 2010 08:10:12 -0000
@@ -441,7 +441,6 @@ function file_field_widget_settings_form
  * Implements hook_field_widget_form().
  */
 function file_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
-  $form['#attributes'] = array('enctype' => 'multipart/form-data');
 
   $defaults = array(
     'fid' => 0,
Index: modules/file/file.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/file/file.module,v
retrieving revision 1.40
diff -u -p -r1.40 file.module
--- modules/file/file.module	13 Sep 2010 01:09:25 -0000	1.40
+++ modules/file/file.module	30 Sep 2010 08:10:13 -0000
@@ -390,7 +390,11 @@ function file_managed_file_process($elem
     '#value' => t('Upload'),
     '#validate' => array(),
     '#submit' => array('file_managed_file_submit'),
-    '#limit_validation_errors' => array($element['#parents']),
+    // Limit validation errors to the file field only. The entire field is
+    // needed later by file_field_widget_form(), so the last element is sliced
+    // off the #parents array to avoid removing too much from
+    // $form_state['values'].
+    '#limit_validation_errors' => array(array_slice($element['#parents'], 0, -1)),
     '#ajax' => $ajax_settings,
     '#weight' => -5,
   );
@@ -404,7 +408,11 @@ function file_managed_file_process($elem
     '#value' => t('Remove'),
     '#validate' => array(),
     '#submit' => array('file_managed_file_submit'),
-    '#limit_validation_errors' => array($element['#parents']),
+    // Limit validation errors to the file field only. The entire field is
+    // needed later by file_field_widget_form(), so the last element is sliced
+    // off the #parents array to avoid removing too much from
+    // $form_state['values'].
+    '#limit_validation_errors' => array(array_slice($element['#parents'], 0, -1)),
     '#ajax' => $ajax_settings,
     '#weight' => -5,
   );
Index: modules/file/tests/file.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/file/tests/file.test,v
retrieving revision 1.25
diff -u -p -r1.25 file.test
--- modules/file/tests/file.test	11 Sep 2010 21:14:31 -0000	1.25
+++ modules/file/tests/file.test	30 Sep 2010 08:10:15 -0000
@@ -114,8 +114,8 @@ class FileFieldTestCase extends DrupalWe
     );
 
     if (is_numeric($nid_or_type)) {
-      $node = node_load($nid_or_type);
-      $delta = isset($node->$field_name) ? count($node->$field_name) : 0;
+      $node = node_load($nid_or_type, NULL, TRUE);
+      $delta = isset($node->{$field_name}[LANGUAGE_NONE]) ? count($node->{$field_name}[LANGUAGE_NONE]) : 0;
       $edit['files[' . $field_name . '_' . LANGUAGE_NONE . '_' . $delta . ']'] = drupal_realpath($file->uri);
       $this->drupalPost('node/' . $nid_or_type . '/edit', $edit, t('Save'));
     }
@@ -280,6 +280,17 @@ class FileFieldWidgetTestCase extends Fi
       $this->assertTrue(empty($node->{$field_name}[LANGUAGE_NONE][0]['fid']), t('File was successfully removed from the node.'));
     }
 
+    // Test partial form submissions using the Upload button on a multivalue field.
+    field_delete_field($field_name);
+    $this->createFileField($field_name, $type_name, array('cardinality' => 3));
+
+    $this->drupalGet("node/add/$type_name");
+    for ($delta = 0; $delta < 3; $delta++) {
+      $edit = array('files[' . $field_name . '_' . LANGUAGE_NONE . '_' . $delta . ']' => drupal_realpath($test_file->uri));
+      $this->drupalPost(NULL, $edit, t('Upload'));
+    }
+    $this->assertNoFieldByXpath('//input[@type="submit"]', t('Upload'), t('After uploading 3 files, the "Upload" button is no longer displayed.'));
+
     // Test private download method.
     $edit = array('field[settings][uri_scheme]' => 'private');
     $this->drupalPost("admin/structure/types/manage/$type_name/fields/$field_name", $edit, t('Save settings'));
