diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json
index b27589f30e2..59398788f2f 100644
--- a/api/openapi-spec/swagger.json
+++ b/api/openapi-spec/swagger.json
@@ -65287,6 +65287,13 @@
       "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata",
       "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
      },
+     "mountOptions": {
+      "description": "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.",
+      "type": "array",
+      "items": {
+       "type": "string"
+      }
+     },
      "parameters": {
       "description": "Parameters holds the parameters for the provisioner that should create volumes of this storage class.",
       "type": "object",
@@ -65363,6 +65370,13 @@
       "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata",
       "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
      },
+     "mountOptions": {
+      "description": "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.",
+      "type": "array",
+      "items": {
+       "type": "string"
+      }
+     },
      "parameters": {
       "description": "Parameters holds the parameters for the provisioner that should create volumes of this storage class.",
       "type": "object",
diff --git a/api/swagger-spec/storage.k8s.io_v1.json b/api/swagger-spec/storage.k8s.io_v1.json
index e914d98d2f1..3b0e9d7f78e 100644
--- a/api/swagger-spec/storage.k8s.io_v1.json
+++ b/api/swagger-spec/storage.k8s.io_v1.json
@@ -720,6 +720,13 @@
      "reclaimPolicy": {
       "$ref": "v1.PersistentVolumeReclaimPolicy",
       "description": "Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete."
+     },
+     "mountOptions": {
+      "type": "array",
+      "items": {
+       "type": "string"
+      },
+      "description": "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid."
      }
     }
    },
diff --git a/api/swagger-spec/storage.k8s.io_v1beta1.json b/api/swagger-spec/storage.k8s.io_v1beta1.json
index cd0e2b8c170..19bdf77630e 100644
--- a/api/swagger-spec/storage.k8s.io_v1beta1.json
+++ b/api/swagger-spec/storage.k8s.io_v1beta1.json
@@ -720,6 +720,13 @@
      "reclaimPolicy": {
       "$ref": "v1.PersistentVolumeReclaimPolicy",
       "description": "Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete."
+     },
+     "mountOptions": {
+      "type": "array",
+      "items": {
+       "type": "string"
+      },
+      "description": "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid."
      }
     }
    },
diff --git a/docs/api-reference/storage.k8s.io/v1/definitions.html b/docs/api-reference/storage.k8s.io/v1/definitions.html
index 63386fb87c7..c0ef082d300 100755
--- a/docs/api-reference/storage.k8s.io/v1/definitions.html
+++ b/docs/api-reference/storage.k8s.io/v1/definitions.html
@@ -975,6 +975,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
 
v1.PersistentVolumeReclaimPolicy  | 
  | 
 
+
+mountOptions  | 
+Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. ["ro", "soft"]. Not validated - mount of the PVs will simply fail if one is invalid.  | 
+false  | 
+string array  | 
+ | 
+
 
 
 
diff --git a/docs/api-reference/storage.k8s.io/v1beta1/definitions.html b/docs/api-reference/storage.k8s.io/v1beta1/definitions.html
index a8091346e9e..56a56484011 100755
--- a/docs/api-reference/storage.k8s.io/v1beta1/definitions.html
+++ b/docs/api-reference/storage.k8s.io/v1beta1/definitions.html
@@ -937,6 +937,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
 v1.PersistentVolumeReclaimPolicy  | 
  | 
 
+
+mountOptions  | 
+Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. ["ro", "soft"]. Not validated - mount of the PVs will simply fail if one is invalid.  | 
+false  | 
+string array  | 
+ | 
+
 
 
 
diff --git a/pkg/apis/storage/types.go b/pkg/apis/storage/types.go
index 26955afde3b..2a45e3557d1 100644
--- a/pkg/apis/storage/types.go
+++ b/pkg/apis/storage/types.go
@@ -54,6 +54,11 @@ type StorageClass struct {
 	// PersistentVolumes of this storage class are created with
 	// +optional
 	ReclaimPolicy *api.PersistentVolumeReclaimPolicy
+
+	// mountOptions are the mount options that dynamically provisioned
+	// PersistentVolumes of this storage class are created with
+	// +optional
+	MountOptions []string
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/pkg/apis/storage/v1/zz_generated.conversion.go b/pkg/apis/storage/v1/zz_generated.conversion.go
index 70472b1e9e8..d7d8f95860b 100644
--- a/pkg/apis/storage/v1/zz_generated.conversion.go
+++ b/pkg/apis/storage/v1/zz_generated.conversion.go
@@ -50,6 +50,7 @@ func autoConvert_v1_StorageClass_To_storage_StorageClass(in *v1.StorageClass, ou
 	out.Provisioner = in.Provisioner
 	out.Parameters = *(*map[string]string)(unsafe.Pointer(&in.Parameters))
 	out.ReclaimPolicy = (*api.PersistentVolumeReclaimPolicy)(unsafe.Pointer(in.ReclaimPolicy))
+	out.MountOptions = *(*[]string)(unsafe.Pointer(&in.MountOptions))
 	return nil
 }
 
@@ -63,6 +64,7 @@ func autoConvert_storage_StorageClass_To_v1_StorageClass(in *storage.StorageClas
 	out.Provisioner = in.Provisioner
 	out.Parameters = *(*map[string]string)(unsafe.Pointer(&in.Parameters))
 	out.ReclaimPolicy = (*core_v1.PersistentVolumeReclaimPolicy)(unsafe.Pointer(in.ReclaimPolicy))
+	out.MountOptions = *(*[]string)(unsafe.Pointer(&in.MountOptions))
 	return nil
 }
 
diff --git a/pkg/apis/storage/v1beta1/zz_generated.conversion.go b/pkg/apis/storage/v1beta1/zz_generated.conversion.go
index 7d259d1e324..4477999da79 100644
--- a/pkg/apis/storage/v1beta1/zz_generated.conversion.go
+++ b/pkg/apis/storage/v1beta1/zz_generated.conversion.go
@@ -50,6 +50,7 @@ func autoConvert_v1beta1_StorageClass_To_storage_StorageClass(in *v1beta1.Storag
 	out.Provisioner = in.Provisioner
 	out.Parameters = *(*map[string]string)(unsafe.Pointer(&in.Parameters))
 	out.ReclaimPolicy = (*api.PersistentVolumeReclaimPolicy)(unsafe.Pointer(in.ReclaimPolicy))
+	out.MountOptions = *(*[]string)(unsafe.Pointer(&in.MountOptions))
 	return nil
 }
 
@@ -63,6 +64,7 @@ func autoConvert_storage_StorageClass_To_v1beta1_StorageClass(in *storage.Storag
 	out.Provisioner = in.Provisioner
 	out.Parameters = *(*map[string]string)(unsafe.Pointer(&in.Parameters))
 	out.ReclaimPolicy = (*v1.PersistentVolumeReclaimPolicy)(unsafe.Pointer(in.ReclaimPolicy))
+	out.MountOptions = *(*[]string)(unsafe.Pointer(&in.MountOptions))
 	return nil
 }
 
diff --git a/pkg/apis/storage/zz_generated.deepcopy.go b/pkg/apis/storage/zz_generated.deepcopy.go
index e5fd6432cc8..e95da89445a 100644
--- a/pkg/apis/storage/zz_generated.deepcopy.go
+++ b/pkg/apis/storage/zz_generated.deepcopy.go
@@ -69,6 +69,11 @@ func (in *StorageClass) DeepCopyInto(out *StorageClass) {
 			**out = **in
 		}
 	}
+	if in.MountOptions != nil {
+		in, out := &in.MountOptions, &out.MountOptions
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 	return
 }
 
diff --git a/pkg/controller/volume/persistentvolume/framework_test.go b/pkg/controller/volume/persistentvolume/framework_test.go
index 629259c6502..d01a9dcc916 100644
--- a/pkg/controller/volume/persistentvolume/framework_test.go
+++ b/pkg/controller/volume/persistentvolume/framework_test.go
@@ -798,12 +798,13 @@ const operationDelete = "Delete"
 const operationRecycle = "Recycle"
 
 var (
-	classGold            string = "gold"
-	classSilver          string = "silver"
-	classEmpty           string = ""
-	classNonExisting     string = "non-existing"
-	classExternal        string = "external"
-	classUnknownInternal string = "unknown-internal"
+	classGold                    string = "gold"
+	classSilver                  string = "silver"
+	classEmpty                   string = ""
+	classNonExisting             string = "non-existing"
+	classExternal                string = "external"
+	classUnknownInternal         string = "unknown-internal"
+	classUnsupportedMountOptions string = "unsupported-mountoptions"
 )
 
 // wrapTestWithPluginCalls returns a testCall that:
diff --git a/pkg/controller/volume/persistentvolume/provision_test.go b/pkg/controller/volume/persistentvolume/provision_test.go
index ef7fa7e082a..db247b080ce 100644
--- a/pkg/controller/volume/persistentvolume/provision_test.go
+++ b/pkg/controller/volume/persistentvolume/provision_test.go
@@ -81,6 +81,18 @@ var storageClasses = []*storage.StorageClass{
 		Parameters:    class1Parameters,
 		ReclaimPolicy: &deleteReclaimPolicy,
 	},
+	{
+		TypeMeta: metav1.TypeMeta{
+			Kind: "StorageClass",
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name: "unsupported-mountoptions",
+		},
+		Provisioner:   mockPluginName,
+		Parameters:    class1Parameters,
+		ReclaimPolicy: &deleteReclaimPolicy,
+		MountOptions:  []string{"foo"},
+	},
 }
 
 // call to storageClass 1, returning an error
@@ -392,6 +404,17 @@ func TestProvisionSync(t *testing.T) {
 				testSyncClaim,
 			),
 		},
+		{
+			// No provisioning + warning event with unsupported storageClass.mountOptions
+			"11-20 - unsupported storageClass.mountOptions",
+			novolumes,
+			novolumes,
+			newClaimArray("claim11-20", "uid11-20", "1Gi", "", v1.ClaimPending, &classUnsupportedMountOptions),
+			newClaimArray("claim11-20", "uid11-20", "1Gi", "", v1.ClaimPending, &classUnsupportedMountOptions, annStorageProvisioner),
+			// Expect event to be prefixed with "Mount options" because saving PV will fail anyway
+			[]string{"Warning ProvisioningFailed Mount options"},
+			noerrors, wrapTestWithProvisionCalls([]provisionCall{}, testSyncClaim),
+		},
 	}
 	runSyncTests(t, tests, storageClasses)
 }
diff --git a/pkg/controller/volume/persistentvolume/pv_controller.go b/pkg/controller/volume/persistentvolume/pv_controller.go
index 5712b14f51a..58ad88cdfa1 100644
--- a/pkg/controller/volume/persistentvolume/pv_controller.go
+++ b/pkg/controller/volume/persistentvolume/pv_controller.go
@@ -1283,6 +1283,7 @@ func (ctrl *PersistentVolumeController) provisionClaimOperation(claimObj interfa
 
 	options := vol.VolumeOptions{
 		PersistentVolumeReclaimPolicy: *storageClass.ReclaimPolicy,
+		MountOptions:                  storageClass.MountOptions,
 		CloudTags:                     &tags,
 		ClusterName:                   ctrl.clusterName,
 		PVName:                        pvName,
@@ -1290,6 +1291,15 @@ func (ctrl *PersistentVolumeController) provisionClaimOperation(claimObj interfa
 		Parameters:                    storageClass.Parameters,
 	}
 
+	// Refuse to provision if the plugin doesn't support mount options, creation
+	// of PV would be rejected by validation anyway
+	if !plugin.SupportsMountOption() && len(options.MountOptions) > 0 {
+		strerr := fmt.Sprintf("Mount options are not supported by the provisioner but StorageClass %q has mount options %v", storageClass.Name, options.MountOptions)
+		glog.V(2).Infof("Mount options are not supported by the provisioner but claim %q's StorageClass %q has mount options %v", claimToClaimKey(claim), storageClass.Name, options.MountOptions)
+		ctrl.eventRecorder.Event(claim, v1.EventTypeWarning, events.ProvisioningFailed, strerr)
+		return
+	}
+
 	// Provision the volume
 	provisioner, err := plugin.NewProvisioner(options)
 	if err != nil {
diff --git a/pkg/volume/aws_ebs/aws_ebs.go b/pkg/volume/aws_ebs/aws_ebs.go
index 7a81f7605e7..5c9f2702c00 100644
--- a/pkg/volume/aws_ebs/aws_ebs.go
+++ b/pkg/volume/aws_ebs/aws_ebs.go
@@ -465,6 +465,7 @@ func (c *awsElasticBlockStoreProvisioner) Provision() (*v1.PersistentVolume, err
 					ReadOnly:  false,
 				},
 			},
+			MountOptions: c.options.MountOptions,
 		},
 	}
 
diff --git a/pkg/volume/azure_dd/azure_provision.go b/pkg/volume/azure_dd/azure_provision.go
index df27da4c584..d037f636d80 100644
--- a/pkg/volume/azure_dd/azure_provision.go
+++ b/pkg/volume/azure_dd/azure_provision.go
@@ -198,6 +198,7 @@ func (p *azureDiskProvisioner) Provision() (*v1.PersistentVolume, error) {
 					FSType:      &fsType,
 				},
 			},
+			MountOptions: p.options.MountOptions,
 		},
 	}
 	return pv, nil
diff --git a/pkg/volume/azure_file/azure_provision.go b/pkg/volume/azure_file/azure_provision.go
index bebec4599fb..882f496d122 100644
--- a/pkg/volume/azure_file/azure_provision.go
+++ b/pkg/volume/azure_file/azure_provision.go
@@ -196,6 +196,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) {
 					SecretNamespace: &secretNamespace,
 				},
 			},
+			MountOptions: a.options.MountOptions,
 		},
 	}
 	return pv, nil
diff --git a/pkg/volume/cinder/cinder.go b/pkg/volume/cinder/cinder.go
index 58bb713322e..45b8d32825b 100644
--- a/pkg/volume/cinder/cinder.go
+++ b/pkg/volume/cinder/cinder.go
@@ -499,6 +499,7 @@ func (c *cinderVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 					ReadOnly: false,
 				},
 			},
+			MountOptions: c.options.MountOptions,
 		},
 	}
 	if len(c.options.PVC.Spec.AccessModes) == 0 {
diff --git a/pkg/volume/gce_pd/gce_pd.go b/pkg/volume/gce_pd/gce_pd.go
index 25f7127fe84..9ddeb95787e 100644
--- a/pkg/volume/gce_pd/gce_pd.go
+++ b/pkg/volume/gce_pd/gce_pd.go
@@ -410,6 +410,7 @@ func (c *gcePersistentDiskProvisioner) Provision() (*v1.PersistentVolume, error)
 					FSType:    fstype,
 				},
 			},
+			MountOptions: c.options.MountOptions,
 		},
 	}
 	if len(c.options.PVC.Spec.AccessModes) == 0 {
diff --git a/pkg/volume/glusterfs/glusterfs.go b/pkg/volume/glusterfs/glusterfs.go
index cb62d07470a..2145fa63333 100644
--- a/pkg/volume/glusterfs/glusterfs.go
+++ b/pkg/volume/glusterfs/glusterfs.go
@@ -711,6 +711,7 @@ func (p *glusterfsVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 	if len(pv.Spec.AccessModes) == 0 {
 		pv.Spec.AccessModes = p.plugin.GetAccessModes()
 	}
+	pv.Spec.MountOptions = p.options.MountOptions
 
 	gidStr := strconv.FormatInt(int64(gid), 10)
 
diff --git a/pkg/volume/photon_pd/photon_pd.go b/pkg/volume/photon_pd/photon_pd.go
index daa0470893e..99965a775b1 100644
--- a/pkg/volume/photon_pd/photon_pd.go
+++ b/pkg/volume/photon_pd/photon_pd.go
@@ -375,6 +375,7 @@ func (p *photonPersistentDiskProvisioner) Provision() (*v1.PersistentVolume, err
 					FSType: fstype,
 				},
 			},
+			MountOptions: p.options.MountOptions,
 		},
 	}
 	if len(p.options.PVC.Spec.AccessModes) == 0 {
diff --git a/pkg/volume/plugins.go b/pkg/volume/plugins.go
index dccb99fce7d..b97f54af33b 100644
--- a/pkg/volume/plugins.go
+++ b/pkg/volume/plugins.go
@@ -50,6 +50,8 @@ type VolumeOptions struct {
 
 	// Reclamation policy for a persistent volume
 	PersistentVolumeReclaimPolicy v1.PersistentVolumeReclaimPolicy
+	// Mount options for a persistent volume
+	MountOptions []string
 	// Suggested PV.Name of the PersistentVolume to provision.
 	// This is a generated name guaranteed to be unique in Kubernetes cluster.
 	// If you choose not to use it as volume name, ensure uniqueness by either
diff --git a/pkg/volume/quobyte/quobyte.go b/pkg/volume/quobyte/quobyte.go
index c2cff8b7fde..8e6ec1f7d12 100644
--- a/pkg/volume/quobyte/quobyte.go
+++ b/pkg/volume/quobyte/quobyte.go
@@ -420,6 +420,7 @@ func (provisioner *quobyteVolumeProvisioner) Provision() (*v1.PersistentVolume,
 	pv.Spec.Capacity = v1.ResourceList{
 		v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)),
 	}
+	pv.Spec.MountOptions = provisioner.options.MountOptions
 	return pv, nil
 }
 
diff --git a/pkg/volume/rbd/rbd.go b/pkg/volume/rbd/rbd.go
index 4aa87d9db89..cc41c6fe0bd 100644
--- a/pkg/volume/rbd/rbd.go
+++ b/pkg/volume/rbd/rbd.go
@@ -383,6 +383,7 @@ func (r *rbdVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 	pv.Spec.Capacity = v1.ResourceList{
 		v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dMi", sizeMB)),
 	}
+	pv.Spec.MountOptions = r.options.MountOptions
 	return pv, nil
 }
 
diff --git a/pkg/volume/vsphere_volume/vsphere_volume.go b/pkg/volume/vsphere_volume/vsphere_volume.go
index 92322fa2ace..4963f179fe5 100644
--- a/pkg/volume/vsphere_volume/vsphere_volume.go
+++ b/pkg/volume/vsphere_volume/vsphere_volume.go
@@ -379,6 +379,7 @@ func (v *vsphereVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 					StoragePolicyID:   volSpec.StoragePolicyID,
 				},
 			},
+			MountOptions: v.options.MountOptions,
 		},
 	}
 	if len(v.options.PVC.Spec.AccessModes) == 0 {
diff --git a/staging/src/k8s.io/api/storage/v1/generated.pb.go b/staging/src/k8s.io/api/storage/v1/generated.pb.go
index 31e18f7f72f..9a024884bb0 100644
--- a/staging/src/k8s.io/api/storage/v1/generated.pb.go
+++ b/staging/src/k8s.io/api/storage/v1/generated.pb.go
@@ -121,6 +121,21 @@ func (m *StorageClass) MarshalTo(dAtA []byte) (int, error) {
 		i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ReclaimPolicy)))
 		i += copy(dAtA[i:], *m.ReclaimPolicy)
 	}
+	if len(m.MountOptions) > 0 {
+		for _, s := range m.MountOptions {
+			dAtA[i] = 0x2a
+			i++
+			l = len(s)
+			for l >= 1<<7 {
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+				l >>= 7
+				i++
+			}
+			dAtA[i] = uint8(l)
+			i++
+			i += copy(dAtA[i:], s)
+		}
+	}
 	return i, nil
 }
 
@@ -208,6 +223,12 @@ func (m *StorageClass) Size() (n int) {
 		l = len(*m.ReclaimPolicy)
 		n += 1 + l + sovGenerated(uint64(l))
 	}
+	if len(m.MountOptions) > 0 {
+		for _, s := range m.MountOptions {
+			l = len(s)
+			n += 1 + l + sovGenerated(uint64(l))
+		}
+	}
 	return n
 }
 
@@ -257,6 +278,7 @@ func (this *StorageClass) String() string {
 		`Provisioner:` + fmt.Sprintf("%v", this.Provisioner) + `,`,
 		`Parameters:` + mapStringForParameters + `,`,
 		`ReclaimPolicy:` + valueToStringGenerated(this.ReclaimPolicy) + `,`,
+		`MountOptions:` + fmt.Sprintf("%v", this.MountOptions) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -514,6 +536,35 @@ func (m *StorageClass) Unmarshal(dAtA []byte) error {
 			s := k8s_io_api_core_v1.PersistentVolumeReclaimPolicy(dAtA[iNdEx:postIndex])
 			m.ReclaimPolicy = &s
 			iNdEx = postIndex
+		case 5:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MountOptions", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.MountOptions = append(m.MountOptions, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -756,39 +807,40 @@ func init() {
 }
 
 var fileDescriptorGenerated = []byte{
-	// 529 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xcd, 0x8a, 0x13, 0x41,
-	0x10, 0xce, 0x24, 0x2e, 0xec, 0x76, 0x0c, 0x86, 0x51, 0x21, 0xe4, 0x30, 0x09, 0xeb, 0x25, 0x08,
-	0x76, 0x6f, 0x76, 0x55, 0x16, 0x41, 0x0f, 0x91, 0x05, 0x05, 0xc5, 0x30, 0x82, 0x07, 0xf1, 0x60,
-	0x67, 0x52, 0x4e, 0xda, 0xf9, 0xe9, 0xa1, 0xbb, 0x66, 0x20, 0x37, 0x1f, 0xc1, 0xe7, 0x11, 0x1f,
-	0x20, 0xc7, 0x3d, 0xee, 0x29, 0x98, 0xf1, 0x2d, 0x3c, 0xc9, 0xcc, 0xc4, 0xcc, 0xec, 0x26, 0x8b,
-	0x7b, 0xeb, 0xaa, 0xfa, 0xbe, 0xaf, 0xab, 0xea, 0x2b, 0xf2, 0xc2, 0x3b, 0xd5, 0x54, 0x48, 0xe6,
-	0xc5, 0x13, 0x50, 0x21, 0x20, 0x68, 0x96, 0x40, 0x38, 0x95, 0x8a, 0xad, 0x0b, 0x3c, 0x12, 0x4c,
-	0xa3, 0x54, 0xdc, 0x05, 0x96, 0x0c, 0x99, 0x0b, 0x21, 0x28, 0x8e, 0x30, 0xa5, 0x91, 0x92, 0x28,
-	0xcd, 0xfb, 0x05, 0x8c, 0xf2, 0x48, 0xd0, 0x35, 0x8c, 0x26, 0xc3, 0xee, 0x23, 0x57, 0xe0, 0x2c,
-	0x9e, 0x50, 0x47, 0x06, 0xcc, 0x95, 0xae, 0x64, 0x39, 0x7a, 0x12, 0x7f, 0xc9, 0xa3, 0x3c, 0xc8,
-	0x5f, 0x85, 0x4a, 0xf7, 0xe1, 0xce, 0xcf, 0x26, 0x80, 0x7c, 0xeb, 0xc7, 0xee, 0xe3, 0x12, 0x1b,
-	0x70, 0x67, 0x26, 0x42, 0x50, 0x73, 0x16, 0x79, 0x6e, 0x96, 0xd0, 0x2c, 0x00, 0xe4, 0x3b, 0xfa,
-	0xec, 0xb2, 0xeb, 0x58, 0x2a, 0x0e, 0x51, 0x04, 0xb0, 0x45, 0x78, 0xfa, 0x3f, 0x82, 0x76, 0x66,
-	0x10, 0xf0, 0x2d, 0xde, 0xc9, 0x75, 0xbc, 0x18, 0x85, 0xcf, 0x44, 0x88, 0x1a, 0xd5, 0x55, 0xd2,
-	0xe1, 0xcf, 0x06, 0xb9, 0xfd, 0xbe, 0x98, 0xfb, 0xa5, 0xcf, 0xb5, 0x36, 0x3f, 0x93, 0xfd, 0x6c,
-	0x92, 0x29, 0x47, 0xde, 0x31, 0xfa, 0xc6, 0xa0, 0x79, 0x7c, 0x44, 0xcb, 0x4d, 0x6f, 0x84, 0x69,
-	0xe4, 0xb9, 0x59, 0x42, 0xd3, 0x0c, 0x4d, 0x93, 0x21, 0x7d, 0x37, 0xf9, 0x0a, 0x0e, 0xbe, 0x05,
-	0xe4, 0x23, 0x73, 0xb1, 0xec, 0xd5, 0xd2, 0x65, 0x8f, 0x94, 0x39, 0x7b, 0xa3, 0x6a, 0x3e, 0x21,
-	0xcd, 0x48, 0xc9, 0x44, 0x68, 0x21, 0x43, 0x50, 0x9d, 0x7a, 0xdf, 0x18, 0x1c, 0x8c, 0xee, 0xae,
-	0x29, 0xcd, 0x71, 0x59, 0xb2, 0xab, 0x38, 0xd3, 0x25, 0x24, 0xe2, 0x8a, 0x07, 0x80, 0xa0, 0x74,
-	0xa7, 0xd1, 0x6f, 0x0c, 0x9a, 0xc7, 0x27, 0x74, 0xe7, 0x11, 0xd0, 0xea, 0x44, 0x74, 0xbc, 0x61,
-	0x9d, 0x85, 0xa8, 0xe6, 0x65, 0x77, 0x65, 0xc1, 0xae, 0x48, 0x9b, 0x1e, 0x69, 0x29, 0x70, 0x7c,
-	0x2e, 0x82, 0xb1, 0xf4, 0x85, 0x33, 0xef, 0xdc, 0xca, 0x3b, 0x3c, 0x4b, 0x97, 0xbd, 0x96, 0x5d,
-	0x2d, 0xfc, 0x59, 0xf6, 0x8e, 0x2a, 0xe7, 0xe3, 0x48, 0x95, 0xdd, 0x0e, 0x1d, 0x83, 0xd2, 0x42,
-	0x23, 0x84, 0xf8, 0x41, 0xfa, 0x71, 0x00, 0x97, 0x38, 0xf6, 0x65, 0xed, 0xee, 0x73, 0x72, 0xe7,
-	0x4a, 0x7f, 0x66, 0x9b, 0x34, 0x3c, 0x98, 0xe7, 0xcb, 0x3f, 0xb0, 0xb3, 0xa7, 0x79, 0x8f, 0xec,
-	0x25, 0xdc, 0x8f, 0xa1, 0xd8, 0x95, 0x5d, 0x04, 0xcf, 0xea, 0xa7, 0xc6, 0xe1, 0x0f, 0x83, 0xb4,
-	0xab, 0xc3, 0xbe, 0x11, 0x1a, 0xcd, 0x4f, 0x5b, 0x16, 0xd2, 0x9b, 0x59, 0x98, 0xb1, 0x73, 0x03,
-	0xdb, 0xeb, 0x15, 0xed, 0xff, 0xcb, 0x54, 0xec, 0x7b, 0x45, 0xf6, 0x04, 0x42, 0xa0, 0x3b, 0xf5,
-	0xdc, 0x82, 0x07, 0x37, 0xb0, 0x60, 0xd4, 0x5a, 0xeb, 0xed, 0xbd, 0xce, 0x98, 0x76, 0x21, 0x30,
-	0x1a, 0x2c, 0x56, 0x56, 0xed, 0x7c, 0x65, 0xd5, 0x2e, 0x56, 0x56, 0xed, 0x5b, 0x6a, 0x19, 0x8b,
-	0xd4, 0x32, 0xce, 0x53, 0xcb, 0xb8, 0x48, 0x2d, 0xe3, 0x57, 0x6a, 0x19, 0xdf, 0x7f, 0x5b, 0xb5,
-	0x8f, 0xf5, 0x64, 0xf8, 0x37, 0x00, 0x00, 0xff, 0xff, 0xd2, 0x64, 0xc7, 0x7e, 0x2c, 0x04, 0x00,
-	0x00,
+	// 558 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xcd, 0x6e, 0xd3, 0x40,
+	0x10, 0x8e, 0x13, 0x22, 0x35, 0x9b, 0x44, 0x44, 0x06, 0x24, 0x2b, 0x07, 0x27, 0x2a, 0x97, 0x08,
+	0x89, 0xdd, 0xa6, 0x2d, 0xa8, 0x42, 0x82, 0x43, 0x50, 0x25, 0x90, 0xa8, 0x1a, 0x19, 0x89, 0x03,
+	0xe2, 0xc0, 0xc6, 0x19, 0x9c, 0xc5, 0x3f, 0x6b, 0xed, 0xae, 0x2d, 0xe5, 0xc6, 0x23, 0xf0, 0x3c,
+	0x3c, 0x41, 0x8e, 0x3d, 0xf6, 0x14, 0x11, 0xf3, 0x06, 0x1c, 0x39, 0x21, 0xdb, 0x21, 0x76, 0x9a,
+	0x54, 0xf4, 0xb6, 0x33, 0xf3, 0x7d, 0xdf, 0xce, 0xcc, 0x37, 0xe8, 0x95, 0x7b, 0x26, 0x31, 0xe3,
+	0xc4, 0x8d, 0x26, 0x20, 0x02, 0x50, 0x20, 0x49, 0x0c, 0xc1, 0x94, 0x0b, 0xb2, 0x2e, 0xd0, 0x90,
+	0x11, 0xa9, 0xb8, 0xa0, 0x0e, 0x90, 0x78, 0x48, 0x1c, 0x08, 0x40, 0x50, 0x05, 0x53, 0x1c, 0x0a,
+	0xae, 0xb8, 0xfe, 0x28, 0x87, 0x61, 0x1a, 0x32, 0xbc, 0x86, 0xe1, 0x78, 0xd8, 0x7d, 0xea, 0x30,
+	0x35, 0x8b, 0x26, 0xd8, 0xe6, 0x3e, 0x71, 0xb8, 0xc3, 0x49, 0x86, 0x9e, 0x44, 0x5f, 0xb2, 0x28,
+	0x0b, 0xb2, 0x57, 0xae, 0xd2, 0x7d, 0xb2, 0xf7, 0xb3, 0x09, 0x28, 0xba, 0xf3, 0x63, 0xf7, 0xb4,
+	0xc0, 0xfa, 0xd4, 0x9e, 0xb1, 0x00, 0xc4, 0x9c, 0x84, 0xae, 0x93, 0x26, 0x24, 0xf1, 0x41, 0xd1,
+	0x3d, 0x7d, 0x76, 0xc9, 0x6d, 0x2c, 0x11, 0x05, 0x8a, 0xf9, 0xb0, 0x43, 0x78, 0xfe, 0x3f, 0x82,
+	0xb4, 0x67, 0xe0, 0xd3, 0x1d, 0xde, 0xc9, 0x6d, 0xbc, 0x48, 0x31, 0x8f, 0xb0, 0x40, 0x49, 0x25,
+	0x6e, 0x92, 0x0e, 0x7f, 0xd7, 0x50, 0xeb, 0x7d, 0x3e, 0xf7, 0x6b, 0x8f, 0x4a, 0xa9, 0x7f, 0x46,
+	0x07, 0xe9, 0x24, 0x53, 0xaa, 0xa8, 0xa1, 0xf5, 0xb5, 0x41, 0xf3, 0xf8, 0x08, 0x17, 0x9b, 0xde,
+	0x08, 0xe3, 0xd0, 0x75, 0xd2, 0x84, 0xc4, 0x29, 0x1a, 0xc7, 0x43, 0x7c, 0x39, 0xf9, 0x0a, 0xb6,
+	0xba, 0x00, 0x45, 0x47, 0xfa, 0x62, 0xd9, 0xab, 0x24, 0xcb, 0x1e, 0x2a, 0x72, 0xd6, 0x46, 0x55,
+	0x7f, 0x86, 0x9a, 0xa1, 0xe0, 0x31, 0x93, 0x8c, 0x07, 0x20, 0x8c, 0x6a, 0x5f, 0x1b, 0x34, 0x46,
+	0x0f, 0xd6, 0x94, 0xe6, 0xb8, 0x28, 0x59, 0x65, 0x9c, 0xee, 0x20, 0x14, 0x52, 0x41, 0x7d, 0x50,
+	0x20, 0xa4, 0x51, 0xeb, 0xd7, 0x06, 0xcd, 0xe3, 0x13, 0xbc, 0xf7, 0x08, 0x70, 0x79, 0x22, 0x3c,
+	0xde, 0xb0, 0xce, 0x03, 0x25, 0xe6, 0x45, 0x77, 0x45, 0xc1, 0x2a, 0x49, 0xeb, 0x2e, 0x6a, 0x0b,
+	0xb0, 0x3d, 0xca, 0xfc, 0x31, 0xf7, 0x98, 0x3d, 0x37, 0xee, 0x65, 0x1d, 0x9e, 0x27, 0xcb, 0x5e,
+	0xdb, 0x2a, 0x17, 0xfe, 0x2c, 0x7b, 0x47, 0xa5, 0xf3, 0xb1, 0xb9, 0x48, 0x6f, 0x07, 0x8f, 0x41,
+	0x48, 0x26, 0x15, 0x04, 0xea, 0x03, 0xf7, 0x22, 0x1f, 0xb6, 0x38, 0xd6, 0xb6, 0xb6, 0x7e, 0x8a,
+	0x5a, 0x3e, 0x8f, 0x02, 0x75, 0x19, 0x2a, 0xc6, 0x03, 0x69, 0xd4, 0xfb, 0xb5, 0x41, 0x63, 0xd4,
+	0x49, 0x96, 0xbd, 0xd6, 0x45, 0x29, 0x6f, 0x6d, 0xa1, 0xba, 0x2f, 0xd1, 0xfd, 0x1b, 0x53, 0xe9,
+	0x1d, 0x54, 0x73, 0x61, 0x9e, 0x59, 0xd6, 0xb0, 0xd2, 0xa7, 0xfe, 0x10, 0xd5, 0x63, 0xea, 0x45,
+	0x90, 0x6f, 0xd8, 0xca, 0x83, 0x17, 0xd5, 0x33, 0xed, 0xf0, 0x87, 0x86, 0x3a, 0xe5, 0x15, 0xbd,
+	0x63, 0x52, 0xe9, 0x9f, 0x76, 0x8c, 0xc7, 0x77, 0x33, 0x3e, 0x65, 0x67, 0xb6, 0x77, 0xd6, 0x8b,
+	0x3d, 0xf8, 0x97, 0x29, 0x99, 0xfe, 0x06, 0xd5, 0x99, 0x02, 0x5f, 0x1a, 0xd5, 0xcc, 0xb8, 0xc7,
+	0x77, 0x30, 0x6e, 0xd4, 0x5e, 0xeb, 0xd5, 0xdf, 0xa6, 0x4c, 0x2b, 0x17, 0x18, 0x0d, 0x16, 0x2b,
+	0xb3, 0x72, 0xb5, 0x32, 0x2b, 0xd7, 0x2b, 0xb3, 0xf2, 0x2d, 0x31, 0xb5, 0x45, 0x62, 0x6a, 0x57,
+	0x89, 0xa9, 0x5d, 0x27, 0xa6, 0xf6, 0x33, 0x31, 0xb5, 0xef, 0xbf, 0xcc, 0xca, 0xc7, 0x6a, 0x3c,
+	0xfc, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xb4, 0xf1, 0xb4, 0x62, 0x04, 0x00, 0x00,
 }
diff --git a/staging/src/k8s.io/api/storage/v1/generated.proto b/staging/src/k8s.io/api/storage/v1/generated.proto
index 7df04a0b2fa..b7143c12f58 100644
--- a/staging/src/k8s.io/api/storage/v1/generated.proto
+++ b/staging/src/k8s.io/api/storage/v1/generated.proto
@@ -53,6 +53,12 @@ message StorageClass {
   // created with this reclaimPolicy. Defaults to Delete.
   // +optional
   optional string reclaimPolicy = 4;
+
+  // Dynamically provisioned PersistentVolumes of this storage class are
+  // created with these mountOptions, e.g. ["ro", "soft"]. Not validated -
+  // mount of the PVs will simply fail if one is invalid.
+  // +optional
+  repeated string mountOptions = 5;
 }
 
 // StorageClassList is a collection of storage classes.
diff --git a/staging/src/k8s.io/api/storage/v1/types.generated.go b/staging/src/k8s.io/api/storage/v1/types.generated.go
index c6c8022474c..623a7ae00da 100644
--- a/staging/src/k8s.io/api/storage/v1/types.generated.go
+++ b/staging/src/k8s.io/api/storage/v1/types.generated.go
@@ -85,7 +85,7 @@ func (x *StorageClass) CodecEncodeSelf(e *codec1978.Encoder) {
 		} else {
 			yysep2 := !z.EncBinary()
 			yy2arr2 := z.EncBasicHandle().StructToArray
-			var yyq2 [6]bool
+			var yyq2 [7]bool
 			_, _, _ = yysep2, yyq2, yy2arr2
 			const yyr2 bool = false
 			yyq2[0] = x.Kind != ""
@@ -93,9 +93,10 @@ func (x *StorageClass) CodecEncodeSelf(e *codec1978.Encoder) {
 			yyq2[2] = true
 			yyq2[4] = len(x.Parameters) != 0
 			yyq2[5] = x.ReclaimPolicy != nil
+			yyq2[6] = len(x.MountOptions) != 0
 			var yynn2 int
 			if yyr2 || yy2arr2 {
-				r.EncodeArrayStart(6)
+				r.EncodeArrayStart(7)
 			} else {
 				yynn2 = 1
 				for _, b := range yyq2 {
@@ -264,6 +265,39 @@ func (x *StorageClass) CodecEncodeSelf(e *codec1978.Encoder) {
 					}
 				}
 			}
+			if yyr2 || yy2arr2 {
+				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
+				if yyq2[6] {
+					if x.MountOptions == nil {
+						r.EncodeNil()
+					} else {
+						yym26 := z.EncBinary()
+						_ = yym26
+						if false {
+						} else {
+							z.F.EncSliceStringV(x.MountOptions, false, e)
+						}
+					}
+				} else {
+					r.EncodeNil()
+				}
+			} else {
+				if yyq2[6] {
+					z.EncSendContainerState(codecSelfer_containerMapKey1234)
+					r.EncodeString(codecSelferC_UTF81234, string("mountOptions"))
+					z.EncSendContainerState(codecSelfer_containerMapValue1234)
+					if x.MountOptions == nil {
+						r.EncodeNil()
+					} else {
+						yym27 := z.EncBinary()
+						_ = yym27
+						if false {
+						} else {
+							z.F.EncSliceStringV(x.MountOptions, false, e)
+						}
+					}
+				}
+			}
 			if yyr2 || yy2arr2 {
 				z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
 			} else {
@@ -397,6 +431,18 @@ func (x *StorageClass) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
 				}
 				x.ReclaimPolicy.CodecDecodeSelf(d)
 			}
+		case "mountOptions":
+			if r.TryDecodeAsNil() {
+				x.MountOptions = nil
+			} else {
+				yyv15 := &x.MountOptions
+				yym16 := z.DecBinary()
+				_ = yym16
+				if false {
+				} else {
+					z.F.DecSliceStringX(yyv15, false, d)
+				}
+			}
 		default:
 			z.DecStructFieldNotFound(-1, yys3)
 		} // end switch yys3
@@ -408,16 +454,16 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	var h codecSelfer1234
 	z, r := codec1978.GenHelperDecoder(d)
 	_, _, _ = h, z, r
-	var yyj15 int
-	var yyb15 bool
-	var yyhl15 bool = l >= 0
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	var yyj17 int
+	var yyb17 bool
+	var yyhl17 bool = l >= 0
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -425,29 +471,7 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	if r.TryDecodeAsNil() {
 		x.Kind = ""
 	} else {
-		yyv16 := &x.Kind
-		yym17 := z.DecBinary()
-		_ = yym17
-		if false {
-		} else {
-			*((*string)(yyv16)) = r.DecodeString()
-		}
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
-		return
-	}
-	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
-	if r.TryDecodeAsNil() {
-		x.APIVersion = ""
-	} else {
-		yyv18 := &x.APIVersion
+		yyv18 := &x.Kind
 		yym19 := z.DecBinary()
 		_ = yym19
 		if false {
@@ -455,13 +479,35 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 			*((*string)(yyv18)) = r.DecodeString()
 		}
 	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
+		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
+		return
+	}
+	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
+	if r.TryDecodeAsNil() {
+		x.APIVersion = ""
+	} else {
+		yyv20 := &x.APIVersion
+		yym21 := z.DecBinary()
+		_ = yym21
+		if false {
+		} else {
+			*((*string)(yyv20)) = r.DecodeString()
+		}
+	}
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
+	} else {
+		yyb17 = r.CheckBreak()
+	}
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -469,22 +515,22 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	if r.TryDecodeAsNil() {
 		x.ObjectMeta = pkg1_v1.ObjectMeta{}
 	} else {
-		yyv20 := &x.ObjectMeta
-		yym21 := z.DecBinary()
-		_ = yym21
+		yyv22 := &x.ObjectMeta
+		yym23 := z.DecBinary()
+		_ = yym23
 		if false {
-		} else if z.HasExtensions() && z.DecExt(yyv20) {
+		} else if z.HasExtensions() && z.DecExt(yyv22) {
 		} else {
-			z.DecFallback(yyv20, false)
+			z.DecFallback(yyv22, false)
 		}
 	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -492,21 +538,21 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	if r.TryDecodeAsNil() {
 		x.Provisioner = ""
 	} else {
-		yyv22 := &x.Provisioner
-		yym23 := z.DecBinary()
-		_ = yym23
+		yyv24 := &x.Provisioner
+		yym25 := z.DecBinary()
+		_ = yym25
 		if false {
 		} else {
-			*((*string)(yyv22)) = r.DecodeString()
+			*((*string)(yyv24)) = r.DecodeString()
 		}
 	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -514,21 +560,21 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	if r.TryDecodeAsNil() {
 		x.Parameters = nil
 	} else {
-		yyv24 := &x.Parameters
-		yym25 := z.DecBinary()
-		_ = yym25
+		yyv26 := &x.Parameters
+		yym27 := z.DecBinary()
+		_ = yym27
 		if false {
 		} else {
-			z.F.DecMapStringStringX(yyv24, false, d)
+			z.F.DecMapStringStringX(yyv26, false, d)
 		}
 	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -543,18 +589,40 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 		}
 		x.ReclaimPolicy.CodecDecodeSelf(d)
 	}
-	for {
-		yyj15++
-		if yyhl15 {
-			yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
+	} else {
+		yyb17 = r.CheckBreak()
+	}
+	if yyb17 {
+		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
+		return
+	}
+	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
+	if r.TryDecodeAsNil() {
+		x.MountOptions = nil
+	} else {
+		yyv29 := &x.MountOptions
+		yym30 := z.DecBinary()
+		_ = yym30
+		if false {
 		} else {
-			yyb15 = r.CheckBreak()
+			z.F.DecSliceStringX(yyv29, false, d)
 		}
-		if yyb15 {
+	}
+	for {
+		yyj17++
+		if yyhl17 {
+			yyb17 = yyj17 > l
+		} else {
+			yyb17 = r.CheckBreak()
+		}
+		if yyb17 {
 			break
 		}
 		z.DecSendContainerState(codecSelfer_containerArrayElem1234)
-		z.DecStructFieldNotFound(yyj15-1, "")
+		z.DecStructFieldNotFound(yyj17-1, "")
 	}
 	z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 }
@@ -966,7 +1034,7 @@ func (x codecSelfer1234) decSliceStorageClass(v *[]StorageClass, d *codec1978.De
 
 			yyrg1 := len(yyv1) > 0
 			yyv21 := yyv1
-			yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 296)
+			yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 320)
 			if yyrt1 {
 				if yyrl1 <= cap(yyv1) {
 					yyv1 = yyv1[:yyrl1]
diff --git a/staging/src/k8s.io/api/storage/v1/types.go b/staging/src/k8s.io/api/storage/v1/types.go
index 02b17795bb0..e843c085a89 100644
--- a/staging/src/k8s.io/api/storage/v1/types.go
+++ b/staging/src/k8s.io/api/storage/v1/types.go
@@ -49,6 +49,12 @@ type StorageClass struct {
 	// created with this reclaimPolicy. Defaults to Delete.
 	// +optional
 	ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"`
+
+	// Dynamically provisioned PersistentVolumes of this storage class are
+	// created with these mountOptions, e.g. ["ro", "soft"]. Not validated -
+	// mount of the PVs will simply fail if one is invalid.
+	// +optional
+	MountOptions []string `json:"mountOptions,omitempty" protobuf:"bytes,5,opt,name=mountOptions"`
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go
index 82a5eb61646..7afb7c2265c 100644
--- a/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go
+++ b/staging/src/k8s.io/api/storage/v1/types_swagger_doc_generated.go
@@ -33,6 +33,7 @@ var map_StorageClass = map[string]string{
 	"provisioner":   "Provisioner indicates the type of the provisioner.",
 	"parameters":    "Parameters holds the parameters for the provisioner that should create volumes of this storage class.",
 	"reclaimPolicy": "Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete.",
+	"mountOptions":  "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.",
 }
 
 func (StorageClass) SwaggerDoc() map[string]string {
diff --git a/staging/src/k8s.io/api/storage/v1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/storage/v1/zz_generated.deepcopy.go
index 3f8d5771e41..838d2536cd7 100644
--- a/staging/src/k8s.io/api/storage/v1/zz_generated.deepcopy.go
+++ b/staging/src/k8s.io/api/storage/v1/zz_generated.deepcopy.go
@@ -69,6 +69,11 @@ func (in *StorageClass) DeepCopyInto(out *StorageClass) {
 			**out = **in
 		}
 	}
+	if in.MountOptions != nil {
+		in, out := &in.MountOptions, &out.MountOptions
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 	return
 }
 
diff --git a/staging/src/k8s.io/api/storage/v1beta1/generated.pb.go b/staging/src/k8s.io/api/storage/v1beta1/generated.pb.go
index 20ef9a29e17..1887e80f970 100644
--- a/staging/src/k8s.io/api/storage/v1beta1/generated.pb.go
+++ b/staging/src/k8s.io/api/storage/v1beta1/generated.pb.go
@@ -121,6 +121,21 @@ func (m *StorageClass) MarshalTo(dAtA []byte) (int, error) {
 		i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ReclaimPolicy)))
 		i += copy(dAtA[i:], *m.ReclaimPolicy)
 	}
+	if len(m.MountOptions) > 0 {
+		for _, s := range m.MountOptions {
+			dAtA[i] = 0x2a
+			i++
+			l = len(s)
+			for l >= 1<<7 {
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+				l >>= 7
+				i++
+			}
+			dAtA[i] = uint8(l)
+			i++
+			i += copy(dAtA[i:], s)
+		}
+	}
 	return i, nil
 }
 
@@ -208,6 +223,12 @@ func (m *StorageClass) Size() (n int) {
 		l = len(*m.ReclaimPolicy)
 		n += 1 + l + sovGenerated(uint64(l))
 	}
+	if len(m.MountOptions) > 0 {
+		for _, s := range m.MountOptions {
+			l = len(s)
+			n += 1 + l + sovGenerated(uint64(l))
+		}
+	}
 	return n
 }
 
@@ -257,6 +278,7 @@ func (this *StorageClass) String() string {
 		`Provisioner:` + fmt.Sprintf("%v", this.Provisioner) + `,`,
 		`Parameters:` + mapStringForParameters + `,`,
 		`ReclaimPolicy:` + valueToStringGenerated(this.ReclaimPolicy) + `,`,
+		`MountOptions:` + fmt.Sprintf("%v", this.MountOptions) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -514,6 +536,35 @@ func (m *StorageClass) Unmarshal(dAtA []byte) error {
 			s := k8s_io_api_core_v1.PersistentVolumeReclaimPolicy(dAtA[iNdEx:postIndex])
 			m.ReclaimPolicy = &s
 			iNdEx = postIndex
+		case 5:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MountOptions", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.MountOptions = append(m.MountOptions, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -756,38 +807,40 @@ func init() {
 }
 
 var fileDescriptorGenerated = []byte{
-	// 527 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xbb, 0x8e, 0x13, 0x3f,
-	0x14, 0xc6, 0xe3, 0xe4, 0x1f, 0xfd, 0x77, 0x1d, 0x22, 0xa2, 0x81, 0x22, 0x4a, 0x31, 0x89, 0x52,
-	0xa5, 0x59, 0x7b, 0xb3, 0x5c, 0x14, 0x21, 0xd1, 0x64, 0xb5, 0x05, 0x12, 0x2b, 0xa2, 0x41, 0xa2,
-	0x40, 0x14, 0x38, 0x93, 0xc3, 0xc4, 0xcc, 0xc5, 0x23, 0xdb, 0x33, 0x52, 0x3a, 0x1e, 0x81, 0x37,
-	0x42, 0x74, 0x29, 0xb7, 0xdc, 0x2a, 0x22, 0xc3, 0x5b, 0x50, 0xa1, 0xb9, 0x90, 0x99, 0x4d, 0x88,
-	0xd8, 0xce, 0x3e, 0xe7, 0xfb, 0x7d, 0xb6, 0xcf, 0x67, 0x7c, 0xe9, 0x4e, 0x14, 0xe1, 0x82, 0xba,
-	0xd1, 0x1c, 0x64, 0x00, 0x1a, 0x14, 0x8d, 0x21, 0x58, 0x08, 0x49, 0x8b, 0x06, 0x0b, 0x39, 0x55,
-	0x5a, 0x48, 0xe6, 0x00, 0x8d, 0xc7, 0x73, 0xd0, 0x6c, 0x4c, 0x1d, 0x08, 0x40, 0x32, 0x0d, 0x0b,
-	0x12, 0x4a, 0xa1, 0x85, 0xd1, 0xcb, 0xb5, 0x84, 0x85, 0x9c, 0x14, 0x5a, 0x52, 0x68, 0x7b, 0x67,
-	0x0e, 0xd7, 0xcb, 0x68, 0x4e, 0x6c, 0xe1, 0x53, 0x47, 0x38, 0x82, 0x66, 0xc8, 0x3c, 0xfa, 0x94,
-	0xed, 0xb2, 0x4d, 0xb6, 0xca, 0xad, 0x7a, 0xc3, 0xca, 0xb1, 0xb6, 0x90, 0xe9, 0x99, 0xfb, 0xc7,
-	0xf5, 0x9e, 0x96, 0x1a, 0x9f, 0xd9, 0x4b, 0x1e, 0x80, 0x5c, 0xd1, 0xd0, 0x75, 0xd2, 0x82, 0xa2,
-	0x3e, 0x68, 0xf6, 0x37, 0x8a, 0x1e, 0xa3, 0x64, 0x14, 0x68, 0xee, 0xc3, 0x01, 0xf0, 0xfc, 0x5f,
-	0x80, 0xb2, 0x97, 0xe0, 0xb3, 0x03, 0xee, 0xc9, 0x31, 0x2e, 0xd2, 0xdc, 0xa3, 0x3c, 0xd0, 0x4a,
-	0xcb, 0x7d, 0x68, 0xf8, 0xbd, 0x81, 0x1f, 0xbc, 0xcd, 0x47, 0x77, 0xe9, 0x31, 0xa5, 0x8c, 0x8f,
-	0xf8, 0x24, 0x7d, 0xc9, 0x82, 0x69, 0xd6, 0x45, 0x03, 0x34, 0x6a, 0x5d, 0x9c, 0x93, 0x72, 0xcc,
-	0x3b, 0x63, 0x12, 0xba, 0x4e, 0x5a, 0x50, 0x24, 0x55, 0x93, 0x78, 0x4c, 0xde, 0xcc, 0x3f, 0x83,
-	0xad, 0xaf, 0x41, 0xb3, 0xa9, 0xb1, 0xde, 0xf4, 0x6b, 0xc9, 0xa6, 0x8f, 0xcb, 0x9a, 0xb5, 0x73,
-	0x35, 0x9e, 0xe1, 0x56, 0x28, 0x45, 0xcc, 0x15, 0x17, 0x01, 0xc8, 0x6e, 0x7d, 0x80, 0x46, 0xa7,
-	0xd3, 0x47, 0x05, 0xd2, 0x9a, 0x95, 0x2d, 0xab, 0xaa, 0x33, 0x3c, 0x8c, 0x43, 0x26, 0x99, 0x0f,
-	0x1a, 0xa4, 0xea, 0x36, 0x06, 0x8d, 0x51, 0xeb, 0x62, 0x42, 0x8e, 0xff, 0x00, 0x52, 0x7d, 0x16,
-	0x99, 0xed, 0xd0, 0xab, 0x40, 0xcb, 0x55, 0x79, 0xc5, 0xb2, 0x61, 0x55, 0xfc, 0x0d, 0x17, 0xb7,
-	0x25, 0xd8, 0x1e, 0xe3, 0xfe, 0x4c, 0x78, 0xdc, 0x5e, 0x75, 0xff, 0xcb, 0xae, 0x79, 0x95, 0x6c,
-	0xfa, 0x6d, 0xab, 0xda, 0xf8, 0xb5, 0xe9, 0x9f, 0x1f, 0xfe, 0x1d, 0x32, 0x03, 0xa9, 0xb8, 0xd2,
-	0x10, 0xe8, 0x77, 0xc2, 0x8b, 0x7c, 0xb8, 0xc3, 0x58, 0x77, 0xbd, 0x7b, 0x2f, 0xf1, 0xc3, 0xbd,
-	0xfb, 0x19, 0x1d, 0xdc, 0x70, 0x61, 0x95, 0x25, 0x70, 0x6a, 0xa5, 0x4b, 0xe3, 0x31, 0x6e, 0xc6,
-	0xcc, 0x8b, 0x20, 0x1f, 0x98, 0x95, 0x6f, 0x5e, 0xd4, 0x27, 0x68, 0xf8, 0x0d, 0xe1, 0x4e, 0xf5,
-	0xb1, 0xaf, 0xb9, 0xd2, 0xc6, 0x87, 0x83, 0x1c, 0xc9, 0xfd, 0x72, 0x4c, 0xe9, 0x2c, 0xc5, 0x4e,
-	0x31, 0xa2, 0x93, 0x3f, 0x95, 0x4a, 0x86, 0xd7, 0xb8, 0xc9, 0x35, 0xf8, 0xaa, 0x5b, 0xcf, 0x72,
-	0x18, 0xdd, 0x37, 0x87, 0x69, 0xbb, 0x30, 0x6d, 0xbe, 0x4a, 0x71, 0x2b, 0x77, 0x99, 0x9e, 0xad,
-	0xb7, 0x66, 0xed, 0x66, 0x6b, 0xd6, 0x6e, 0xb7, 0x66, 0xed, 0x4b, 0x62, 0xa2, 0x75, 0x62, 0xa2,
-	0x9b, 0xc4, 0x44, 0xb7, 0x89, 0x89, 0x7e, 0x24, 0x26, 0xfa, 0xfa, 0xd3, 0xac, 0xbd, 0xff, 0xbf,
-	0x70, 0xfc, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x94, 0xc8, 0xc6, 0xb6, 0x3d, 0x04, 0x00, 0x00,
+	// 554 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3f, 0x8f, 0x12, 0x41,
+	0x18, 0xc6, 0xd9, 0x43, 0xe2, 0xdd, 0x00, 0x91, 0xac, 0x16, 0x1b, 0x8a, 0x85, 0x50, 0xd1, 0xdc,
+	0xcc, 0x71, 0x9e, 0x86, 0x98, 0xd8, 0x70, 0xb9, 0xc2, 0x44, 0x72, 0x64, 0x4d, 0x2c, 0x8c, 0x85,
+	0xc3, 0xf2, 0xba, 0x8c, 0xfb, 0x67, 0x36, 0x33, 0xb3, 0x24, 0x74, 0x7e, 0x04, 0xbf, 0x91, 0x2d,
+	0xe5, 0x95, 0x57, 0x11, 0x59, 0x3f, 0x84, 0x89, 0x95, 0xd9, 0x3f, 0xb2, 0x0b, 0x48, 0xbc, 0x6e,
+	0xe6, 0x7d, 0x9f, 0xdf, 0x33, 0x33, 0xef, 0x33, 0xe8, 0xda, 0x1d, 0x4a, 0xcc, 0x38, 0x71, 0xa3,
+	0x29, 0x88, 0x00, 0x14, 0x48, 0xb2, 0x80, 0x60, 0xc6, 0x05, 0xc9, 0x1b, 0x34, 0x64, 0x44, 0x2a,
+	0x2e, 0xa8, 0x03, 0x64, 0x31, 0x98, 0x82, 0xa2, 0x03, 0xe2, 0x40, 0x00, 0x82, 0x2a, 0x98, 0xe1,
+	0x50, 0x70, 0xc5, 0xf5, 0x76, 0xa6, 0xc5, 0x34, 0x64, 0x38, 0xd7, 0xe2, 0x5c, 0xdb, 0x3e, 0x77,
+	0x98, 0x9a, 0x47, 0x53, 0x6c, 0x73, 0x9f, 0x38, 0xdc, 0xe1, 0x24, 0x45, 0xa6, 0xd1, 0xe7, 0x74,
+	0x97, 0x6e, 0xd2, 0x55, 0x66, 0xd5, 0xee, 0x95, 0x8e, 0xb5, 0xb9, 0x48, 0xce, 0xdc, 0x3f, 0xae,
+	0x7d, 0x55, 0x68, 0x7c, 0x6a, 0xcf, 0x59, 0x00, 0x62, 0x49, 0x42, 0xd7, 0x49, 0x0a, 0x92, 0xf8,
+	0xa0, 0xe8, 0xbf, 0x28, 0x72, 0x8c, 0x12, 0x51, 0xa0, 0x98, 0x0f, 0x07, 0xc0, 0xcb, 0xff, 0x01,
+	0xd2, 0x9e, 0x83, 0x4f, 0x0f, 0xb8, 0xe7, 0xc7, 0xb8, 0x48, 0x31, 0x8f, 0xb0, 0x40, 0x49, 0x25,
+	0xf6, 0xa1, 0xde, 0xaf, 0x2a, 0x6a, 0xbc, 0xcb, 0x46, 0x77, 0xed, 0x51, 0x29, 0xf5, 0x4f, 0xe8,
+	0x34, 0x79, 0xc9, 0x8c, 0x2a, 0x6a, 0x68, 0x5d, 0xad, 0x5f, 0xbf, 0xbc, 0xc0, 0xc5, 0x98, 0xb7,
+	0xc6, 0x38, 0x74, 0x9d, 0xa4, 0x20, 0x71, 0xa2, 0xc6, 0x8b, 0x01, 0xbe, 0x9d, 0x7e, 0x01, 0x5b,
+	0x8d, 0x41, 0xd1, 0x91, 0xbe, 0x5a, 0x77, 0x2a, 0xf1, 0xba, 0x83, 0x8a, 0x9a, 0xb5, 0x75, 0xd5,
+	0x5f, 0xa0, 0x7a, 0x28, 0xf8, 0x82, 0x49, 0xc6, 0x03, 0x10, 0xc6, 0x49, 0x57, 0xeb, 0x9f, 0x8d,
+	0x9e, 0xe6, 0x48, 0x7d, 0x52, 0xb4, 0xac, 0xb2, 0x4e, 0xf7, 0x10, 0x0a, 0xa9, 0xa0, 0x3e, 0x28,
+	0x10, 0xd2, 0xa8, 0x76, 0xab, 0xfd, 0xfa, 0xe5, 0x10, 0x1f, 0xff, 0x01, 0xb8, 0xfc, 0x2c, 0x3c,
+	0xd9, 0xa2, 0x37, 0x81, 0x12, 0xcb, 0xe2, 0x8a, 0x45, 0xc3, 0x2a, 0xf9, 0xeb, 0x2e, 0x6a, 0x0a,
+	0xb0, 0x3d, 0xca, 0xfc, 0x09, 0xf7, 0x98, 0xbd, 0x34, 0x1e, 0xa5, 0xd7, 0xbc, 0x89, 0xd7, 0x9d,
+	0xa6, 0x55, 0x6e, 0xfc, 0x5e, 0x77, 0x2e, 0x0e, 0xff, 0x0e, 0x9e, 0x80, 0x90, 0x4c, 0x2a, 0x08,
+	0xd4, 0x7b, 0xee, 0x45, 0x3e, 0xec, 0x30, 0xd6, 0xae, 0xb7, 0x7e, 0x85, 0x1a, 0x3e, 0x8f, 0x02,
+	0x75, 0x1b, 0x2a, 0xc6, 0x03, 0x69, 0xd4, 0xba, 0xd5, 0xfe, 0xd9, 0xa8, 0x15, 0xaf, 0x3b, 0x8d,
+	0x71, 0xa9, 0x6e, 0xed, 0xa8, 0xda, 0xaf, 0xd1, 0x93, 0xbd, 0x57, 0xe9, 0x2d, 0x54, 0x75, 0x61,
+	0x99, 0xe6, 0x76, 0x66, 0x25, 0x4b, 0xfd, 0x19, 0xaa, 0x2d, 0xa8, 0x17, 0x41, 0x36, 0x66, 0x2b,
+	0xdb, 0xbc, 0x3a, 0x19, 0x6a, 0xbd, 0xef, 0x1a, 0x6a, 0x95, 0x47, 0xf4, 0x96, 0x49, 0xa5, 0x7f,
+	0x3c, 0x48, 0x1f, 0x3f, 0x2c, 0xfd, 0x84, 0x4e, 0xb3, 0x6f, 0xe5, 0x83, 0x3d, 0xfd, 0x5b, 0x29,
+	0x25, 0x3f, 0x46, 0x35, 0xa6, 0xc0, 0x97, 0xc6, 0x49, 0x9a, 0x5e, 0xff, 0xa1, 0xe9, 0x8d, 0x9a,
+	0xb9, 0x69, 0xed, 0x4d, 0x82, 0x5b, 0x99, 0xcb, 0xe8, 0x7c, 0xb5, 0x31, 0x2b, 0x77, 0x1b, 0xb3,
+	0x72, 0xbf, 0x31, 0x2b, 0x5f, 0x63, 0x53, 0x5b, 0xc5, 0xa6, 0x76, 0x17, 0x9b, 0xda, 0x7d, 0x6c,
+	0x6a, 0x3f, 0x62, 0x53, 0xfb, 0xf6, 0xd3, 0xac, 0x7c, 0x78, 0x9c, 0x3b, 0xfe, 0x09, 0x00, 0x00,
+	0xff, 0xff, 0x2a, 0xfd, 0x7a, 0x0a, 0x73, 0x04, 0x00, 0x00,
 }
diff --git a/staging/src/k8s.io/api/storage/v1beta1/generated.proto b/staging/src/k8s.io/api/storage/v1beta1/generated.proto
index a5978d2438a..4332d3fbcd5 100644
--- a/staging/src/k8s.io/api/storage/v1beta1/generated.proto
+++ b/staging/src/k8s.io/api/storage/v1beta1/generated.proto
@@ -53,6 +53,12 @@ message StorageClass {
   // created with this reclaimPolicy. Defaults to Delete.
   // +optional
   optional string reclaimPolicy = 4;
+
+  // Dynamically provisioned PersistentVolumes of this storage class are
+  // created with these mountOptions, e.g. ["ro", "soft"]. Not validated -
+  // mount of the PVs will simply fail if one is invalid.
+  // +optional
+  repeated string mountOptions = 5;
 }
 
 // StorageClassList is a collection of storage classes.
diff --git a/staging/src/k8s.io/api/storage/v1beta1/types.generated.go b/staging/src/k8s.io/api/storage/v1beta1/types.generated.go
index 3caaac55851..7aad7bb166d 100644
--- a/staging/src/k8s.io/api/storage/v1beta1/types.generated.go
+++ b/staging/src/k8s.io/api/storage/v1beta1/types.generated.go
@@ -85,7 +85,7 @@ func (x *StorageClass) CodecEncodeSelf(e *codec1978.Encoder) {
 		} else {
 			yysep2 := !z.EncBinary()
 			yy2arr2 := z.EncBasicHandle().StructToArray
-			var yyq2 [6]bool
+			var yyq2 [7]bool
 			_, _, _ = yysep2, yyq2, yy2arr2
 			const yyr2 bool = false
 			yyq2[0] = x.Kind != ""
@@ -93,9 +93,10 @@ func (x *StorageClass) CodecEncodeSelf(e *codec1978.Encoder) {
 			yyq2[2] = true
 			yyq2[4] = len(x.Parameters) != 0
 			yyq2[5] = x.ReclaimPolicy != nil
+			yyq2[6] = len(x.MountOptions) != 0
 			var yynn2 int
 			if yyr2 || yy2arr2 {
-				r.EncodeArrayStart(6)
+				r.EncodeArrayStart(7)
 			} else {
 				yynn2 = 1
 				for _, b := range yyq2 {
@@ -264,6 +265,39 @@ func (x *StorageClass) CodecEncodeSelf(e *codec1978.Encoder) {
 					}
 				}
 			}
+			if yyr2 || yy2arr2 {
+				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
+				if yyq2[6] {
+					if x.MountOptions == nil {
+						r.EncodeNil()
+					} else {
+						yym26 := z.EncBinary()
+						_ = yym26
+						if false {
+						} else {
+							z.F.EncSliceStringV(x.MountOptions, false, e)
+						}
+					}
+				} else {
+					r.EncodeNil()
+				}
+			} else {
+				if yyq2[6] {
+					z.EncSendContainerState(codecSelfer_containerMapKey1234)
+					r.EncodeString(codecSelferC_UTF81234, string("mountOptions"))
+					z.EncSendContainerState(codecSelfer_containerMapValue1234)
+					if x.MountOptions == nil {
+						r.EncodeNil()
+					} else {
+						yym27 := z.EncBinary()
+						_ = yym27
+						if false {
+						} else {
+							z.F.EncSliceStringV(x.MountOptions, false, e)
+						}
+					}
+				}
+			}
 			if yyr2 || yy2arr2 {
 				z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
 			} else {
@@ -397,6 +431,18 @@ func (x *StorageClass) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
 				}
 				x.ReclaimPolicy.CodecDecodeSelf(d)
 			}
+		case "mountOptions":
+			if r.TryDecodeAsNil() {
+				x.MountOptions = nil
+			} else {
+				yyv15 := &x.MountOptions
+				yym16 := z.DecBinary()
+				_ = yym16
+				if false {
+				} else {
+					z.F.DecSliceStringX(yyv15, false, d)
+				}
+			}
 		default:
 			z.DecStructFieldNotFound(-1, yys3)
 		} // end switch yys3
@@ -408,16 +454,16 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	var h codecSelfer1234
 	z, r := codec1978.GenHelperDecoder(d)
 	_, _, _ = h, z, r
-	var yyj15 int
-	var yyb15 bool
-	var yyhl15 bool = l >= 0
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	var yyj17 int
+	var yyb17 bool
+	var yyhl17 bool = l >= 0
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -425,29 +471,7 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	if r.TryDecodeAsNil() {
 		x.Kind = ""
 	} else {
-		yyv16 := &x.Kind
-		yym17 := z.DecBinary()
-		_ = yym17
-		if false {
-		} else {
-			*((*string)(yyv16)) = r.DecodeString()
-		}
-	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
-	} else {
-		yyb15 = r.CheckBreak()
-	}
-	if yyb15 {
-		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
-		return
-	}
-	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
-	if r.TryDecodeAsNil() {
-		x.APIVersion = ""
-	} else {
-		yyv18 := &x.APIVersion
+		yyv18 := &x.Kind
 		yym19 := z.DecBinary()
 		_ = yym19
 		if false {
@@ -455,13 +479,35 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 			*((*string)(yyv18)) = r.DecodeString()
 		}
 	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
+		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
+		return
+	}
+	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
+	if r.TryDecodeAsNil() {
+		x.APIVersion = ""
+	} else {
+		yyv20 := &x.APIVersion
+		yym21 := z.DecBinary()
+		_ = yym21
+		if false {
+		} else {
+			*((*string)(yyv20)) = r.DecodeString()
+		}
+	}
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
+	} else {
+		yyb17 = r.CheckBreak()
+	}
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -469,22 +515,22 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	if r.TryDecodeAsNil() {
 		x.ObjectMeta = pkg1_v1.ObjectMeta{}
 	} else {
-		yyv20 := &x.ObjectMeta
-		yym21 := z.DecBinary()
-		_ = yym21
+		yyv22 := &x.ObjectMeta
+		yym23 := z.DecBinary()
+		_ = yym23
 		if false {
-		} else if z.HasExtensions() && z.DecExt(yyv20) {
+		} else if z.HasExtensions() && z.DecExt(yyv22) {
 		} else {
-			z.DecFallback(yyv20, false)
+			z.DecFallback(yyv22, false)
 		}
 	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -492,21 +538,21 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	if r.TryDecodeAsNil() {
 		x.Provisioner = ""
 	} else {
-		yyv22 := &x.Provisioner
-		yym23 := z.DecBinary()
-		_ = yym23
+		yyv24 := &x.Provisioner
+		yym25 := z.DecBinary()
+		_ = yym25
 		if false {
 		} else {
-			*((*string)(yyv22)) = r.DecodeString()
+			*((*string)(yyv24)) = r.DecodeString()
 		}
 	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -514,21 +560,21 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 	if r.TryDecodeAsNil() {
 		x.Parameters = nil
 	} else {
-		yyv24 := &x.Parameters
-		yym25 := z.DecBinary()
-		_ = yym25
+		yyv26 := &x.Parameters
+		yym27 := z.DecBinary()
+		_ = yym27
 		if false {
 		} else {
-			z.F.DecMapStringStringX(yyv24, false, d)
+			z.F.DecMapStringStringX(yyv26, false, d)
 		}
 	}
-	yyj15++
-	if yyhl15 {
-		yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
 	} else {
-		yyb15 = r.CheckBreak()
+		yyb17 = r.CheckBreak()
 	}
-	if yyb15 {
+	if yyb17 {
 		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 		return
 	}
@@ -543,18 +589,40 @@ func (x *StorageClass) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 		}
 		x.ReclaimPolicy.CodecDecodeSelf(d)
 	}
-	for {
-		yyj15++
-		if yyhl15 {
-			yyb15 = yyj15 > l
+	yyj17++
+	if yyhl17 {
+		yyb17 = yyj17 > l
+	} else {
+		yyb17 = r.CheckBreak()
+	}
+	if yyb17 {
+		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
+		return
+	}
+	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
+	if r.TryDecodeAsNil() {
+		x.MountOptions = nil
+	} else {
+		yyv29 := &x.MountOptions
+		yym30 := z.DecBinary()
+		_ = yym30
+		if false {
 		} else {
-			yyb15 = r.CheckBreak()
+			z.F.DecSliceStringX(yyv29, false, d)
 		}
-		if yyb15 {
+	}
+	for {
+		yyj17++
+		if yyhl17 {
+			yyb17 = yyj17 > l
+		} else {
+			yyb17 = r.CheckBreak()
+		}
+		if yyb17 {
 			break
 		}
 		z.DecSendContainerState(codecSelfer_containerArrayElem1234)
-		z.DecStructFieldNotFound(yyj15-1, "")
+		z.DecStructFieldNotFound(yyj17-1, "")
 	}
 	z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 }
@@ -966,7 +1034,7 @@ func (x codecSelfer1234) decSliceStorageClass(v *[]StorageClass, d *codec1978.De
 
 			yyrg1 := len(yyv1) > 0
 			yyv21 := yyv1
-			yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 296)
+			yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 320)
 			if yyrt1 {
 				if yyrl1 <= cap(yyv1) {
 					yyv1 = yyv1[:yyrl1]
diff --git a/staging/src/k8s.io/api/storage/v1beta1/types.go b/staging/src/k8s.io/api/storage/v1beta1/types.go
index aa828172a44..d5e2fe585e2 100644
--- a/staging/src/k8s.io/api/storage/v1beta1/types.go
+++ b/staging/src/k8s.io/api/storage/v1beta1/types.go
@@ -49,6 +49,12 @@ type StorageClass struct {
 	// created with this reclaimPolicy. Defaults to Delete.
 	// +optional
 	ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"`
+
+	// Dynamically provisioned PersistentVolumes of this storage class are
+	// created with these mountOptions, e.g. ["ro", "soft"]. Not validated -
+	// mount of the PVs will simply fail if one is invalid.
+	// +optional
+	MountOptions []string `json:"mountOptions,omitempty" protobuf:"bytes,5,opt,name=mountOptions"`
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go
index 7a4942e437b..ca5c041a03b 100644
--- a/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go
+++ b/staging/src/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go
@@ -33,6 +33,7 @@ var map_StorageClass = map[string]string{
 	"provisioner":   "Provisioner indicates the type of the provisioner.",
 	"parameters":    "Parameters holds the parameters for the provisioner that should create volumes of this storage class.",
 	"reclaimPolicy": "Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete.",
+	"mountOptions":  "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.",
 }
 
 func (StorageClass) SwaggerDoc() map[string]string {
diff --git a/staging/src/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go
index e89661c18f5..cca5a200b02 100644
--- a/staging/src/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go
+++ b/staging/src/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go
@@ -69,6 +69,11 @@ func (in *StorageClass) DeepCopyInto(out *StorageClass) {
 			**out = **in
 		}
 	}
+	if in.MountOptions != nil {
+		in, out := &in.MountOptions, &out.MountOptions
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 	return
 }