UpdateMetadata for snapshots
diff --git a/openstack/blockstorage/v1/snapshots/requests.go b/openstack/blockstorage/v1/snapshots/requests.go
index 0e4e8f8..fad5adf 100644
--- a/openstack/blockstorage/v1/snapshots/requests.go
+++ b/openstack/blockstorage/v1/snapshots/requests.go
@@ -104,35 +104,26 @@
 // UpdateOpts contain options for updating an existing Snapshot. This object is
 // passed to the snapshots.Update function. For more information about the
 // parameters, see the Snapshot object.
-type UpdateOpts struct {
-	Description string
-	Name        string
+type UpdateMetadataOpts struct {
+	Metadata map[string]interface{}
 }
 
 // Update will update the Snapshot with provided information. To extract the updated
-// Snapshot from the response, call the Extract method on the UpdateResult.
-func Update(client *gophercloud.ServiceClient, id string, opts *UpdateOpts) UpdateResult {
-	type update struct {
-		Description *string `json:"display_description,omitempty"`
-		Name        *string `json:"display_name,omitempty"`
-	}
-
+// Snapshot from the response, call the ExtractMetadata method on the UpdateResult.
+func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts *UpdateMetadataOpts) UpdateMetadataResult {
 	type request struct {
-		Volume update `json:"snapshot"`
+		Metadata map[string]interface{} `json:"metadata,omitempty"`
 	}
 
-	reqBody := request{
-		Volume: update{},
-	}
+	reqBody := request{}
 
-	reqBody.Volume.Description = utils.MaybeString(opts.Description)
-	reqBody.Volume.Name = utils.MaybeString(opts.Name)
+	reqBody.Metadata = opts.Metadata
 
-	var res UpdateResult
+	var res UpdateMetadataResult
 
-	_, res.Err = perigee.Request("PUT", updateURL(client, id), perigee.Options{
+	_, res.Err = perigee.Request("PUT", updateMetadataURL(client, id), perigee.Options{
 		MoreHeaders: client.Provider.AuthenticatedHeaders(),
-		OkCodes:     []int{202, 204},
+		OkCodes:     []int{200},
 		ReqBody:     &reqBody,
 		Results:     &res.Resp,
 	})
diff --git a/openstack/blockstorage/v1/snapshots/requests_test.go b/openstack/blockstorage/v1/snapshots/requests_test.go
index 4050990..d29cc0d 100644
--- a/openstack/blockstorage/v1/snapshots/requests_test.go
+++ b/openstack/blockstorage/v1/snapshots/requests_test.go
@@ -145,6 +145,44 @@
 	th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22")
 }
 
+func TestUpdateMetadata(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "PUT")
+		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "Content-Type", "application/json")
+		th.TestJSONRequest(t, r, `
+		{
+			"metadata": {
+				"key": "v1"
+			}
+		}
+		`)
+
+		fmt.Fprintf(w, `
+			{
+				"metadata": {
+					"key": "v1"
+				}
+			}
+		`)
+	})
+
+	expected := map[string]interface{}{"key": "v1"}
+
+	options := &UpdateMetadataOpts{
+		Metadata: map[string]interface{}{
+			"key": "v1",
+		},
+	}
+	actual, err := UpdateMetadata(ServiceClient(), "123", options).ExtractMetadata()
+
+	th.AssertNoErr(t, err)
+	th.AssertDeepEquals(t, actual, expected)
+}
+
 func TestDelete(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
diff --git a/openstack/blockstorage/v1/snapshots/results.go b/openstack/blockstorage/v1/snapshots/results.go
index 3a27592..9509bca 100644
--- a/openstack/blockstorage/v1/snapshots/results.go
+++ b/openstack/blockstorage/v1/snapshots/results.go
@@ -60,11 +60,22 @@
 	return response.Snapshots, err
 }
 
-// UpdateResult contains the response body and error from an Update request.
-type UpdateResult struct {
+// UpdateMetadataResult contains the response body and error from an UpdateMetadata request.
+type UpdateMetadataResult struct {
 	commonResult
 }
 
+// ExtractMetadata returns the metadata from a response from snapshots.UpdateMetadata.
+func (r UpdateMetadataResult) ExtractMetadata() (map[string]interface{}, error) {
+	if r.Err != nil {
+		return nil, r.Err
+	}
+
+	m := r.Resp["metadata"].(map[string]interface{})
+
+	return m, nil
+}
+
 type commonResult struct {
 	gophercloud.CommonResult
 }
diff --git a/openstack/blockstorage/v1/snapshots/urls.go b/openstack/blockstorage/v1/snapshots/urls.go
index fb324bb..4d635e8 100644
--- a/openstack/blockstorage/v1/snapshots/urls.go
+++ b/openstack/blockstorage/v1/snapshots/urls.go
@@ -22,6 +22,6 @@
 	return c.ServiceURL("snapshots", id, "metadata")
 }
 
-func updateURL(c *gophercloud.ServiceClient, id string) string {
+func updateMetadataURL(c *gophercloud.ServiceClient, id string) string {
 	return metadataURL(c, id)
 }
diff --git a/openstack/blockstorage/v1/snapshots/urls_test.go b/openstack/blockstorage/v1/snapshots/urls_test.go
index 8877580..feacf7f 100644
--- a/openstack/blockstorage/v1/snapshots/urls_test.go
+++ b/openstack/blockstorage/v1/snapshots/urls_test.go
@@ -43,8 +43,8 @@
 	th.AssertEquals(t, expected, actual)
 }
 
-func TestUpdateURL(t *testing.T) {
-	actual := updateURL(endpointClient(), "foo")
+func TestUpdateMetadataURL(t *testing.T) {
+	actual := updateMetadataURL(endpointClient(), "foo")
 	expected := endpoint + "snapshots/foo/metadata"
 	th.AssertEquals(t, expected, actual)
 }