dsl struct tags; wip
diff --git a/openstack/blockstorage/v1/volumes/requests.go b/openstack/blockstorage/v1/volumes/requests.go
index 1c6b635..7c063b2 100644
--- a/openstack/blockstorage/v1/volumes/requests.go
+++ b/openstack/blockstorage/v1/volumes/requests.go
@@ -15,94 +15,52 @@
 // the volumes.Create function. For more information about these parameters,
 // see the Volume object.
 type CreateOpts struct {
-	// OPTIONAL
-	Availability string
-	// OPTIONAL
-	Description string
-	// OPTIONAL
-	Metadata map[string]string
-	// OPTIONAL
-	Name string
-	// REQUIRED
-	Size int
-	// OPTIONAL
-	SnapshotID, SourceVolID, ImageID string
-	// OPTIONAL
-	VolumeType string
+	Size         int               `json:"size" required:"true"`
+	Availability string            `json:"availability,omitempty"`
+	Description  string            `json:"description,omitempty"`
+	Metadata     map[string]string `json:"metadata,omitempty"`
+	Name         string            `json:"name,omitempty"`
+	SnapshotID   string            `json:"snapshot_id,omitempty"`
+	SourceVolID  string            `json:"source_volid,omitempty"`
+	ImageID      string            `json:"imageRef,omitempty"`
+	VolumeType   string            `json:"volume_type,omitempty"`
 }
 
 // ToVolumeCreateMap assembles a request body based on the contents of a
 // CreateOpts.
 func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) {
-	v := make(map[string]interface{})
-
-	if opts.Size == 0 {
-		err := &gophercloud.ErrMissingInput{}
-		err.Argument = "CreateOpts.Size"
-		err.Function = "volumes.ToVolumeCreateMap"
-		return nil, err
-	}
-	v["size"] = opts.Size
-
-	if opts.Availability != "" {
-		v["availability_zone"] = opts.Availability
-	}
-	if opts.Description != "" {
-		v["display_description"] = opts.Description
-	}
-	if opts.ImageID != "" {
-		v["imageRef"] = opts.ImageID
-	}
-	if opts.Metadata != nil {
-		v["metadata"] = opts.Metadata
-	}
-	if opts.Name != "" {
-		v["display_name"] = opts.Name
-	}
-	if opts.SourceVolID != "" {
-		v["source_volid"] = opts.SourceVolID
-	}
-	if opts.SnapshotID != "" {
-		v["snapshot_id"] = opts.SnapshotID
-	}
-	if opts.VolumeType != "" {
-		v["volume_type"] = opts.VolumeType
-	}
-
-	return map[string]interface{}{"volume": v}, nil
+	return gophercloud.BuildRequestBody(opts, "volume")
 }
 
 // Create will create a new Volume based on the values in CreateOpts. To extract
 // the Volume object from the response, call the Extract method on the
 // CreateResult.
 func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
-	var res CreateResult
-
-	reqBody, err := opts.ToVolumeCreateMap()
+	var r CreateResult
+	b, err := opts.ToVolumeCreateMap()
 	if err != nil {
-		res.Err = err
-		return res
+		r.Err = err
+		return r
 	}
-
-	_, res.Err = client.Post(createURL(client), reqBody, &res.Body, &gophercloud.RequestOpts{
+	_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
 		OkCodes: []int{200, 201},
 	})
-	return res
+	return r
 }
 
 // Delete will delete the existing Volume with the provided ID.
 func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
-	var res DeleteResult
-	_, res.Err = client.Delete(deleteURL(client, id), nil)
-	return res
+	var r DeleteResult
+	_, r.Err = client.Delete(deleteURL(client, id), nil)
+	return r
 }
 
 // Get retrieves the Volume with the provided ID. To extract the Volume object
 // from the response, call the Extract method on the GetResult.
 func Get(client *gophercloud.ServiceClient, id string) GetResult {
-	var res GetResult
-	_, res.Err = client.Get(getURL(client, id), &res.Body, nil)
-	return res
+	var r GetResult
+	_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
+	return r
 }
 
 // ListOptsBuilder allows extensions to add additional parameters to the List
@@ -127,10 +85,7 @@
 // ToVolumeListQuery formats a ListOpts into a query string.
 func (opts ListOpts) ToVolumeListQuery() (string, error) {
 	q, err := gophercloud.BuildQueryString(opts)
-	if err != nil {
-		return "", err
-	}
-	return q.String(), nil
+	return q.String(), err
 }
 
 // List returns Volumes optionally limited by the conditions provided in ListOpts.
@@ -143,11 +98,9 @@
 		}
 		url += query
 	}
-	createPage := func(r pagination.PageResult) pagination.Page {
+	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
 		return VolumePage{pagination.SinglePageBase(r)}
-	}
-
-	return pagination.NewPager(client, url, createPage)
+	})
 }
 
 // UpdateOptsBuilder allows extensions to add additional parameters to the
@@ -161,59 +114,38 @@
 // the Volume object.
 type UpdateOpts struct {
 	// OPTIONAL
-	Name string
+	Name string `json:"name,omitempty"`
 	// OPTIONAL
-	Description string
+	Description string `json:"description,omitempty"`
 	// OPTIONAL
-	Metadata map[string]string
+	Metadata map[string]string `json:"metadata,omitempty"`
 }
 
 // ToVolumeUpdateMap assembles a request body based on the contents of an
 // UpdateOpts.
 func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) {
-	v := make(map[string]interface{})
-
-	if opts.Description != "" {
-		v["display_description"] = opts.Description
-	}
-	if opts.Metadata != nil {
-		v["metadata"] = opts.Metadata
-	}
-	if opts.Name != "" {
-		v["display_name"] = opts.Name
-	}
-
-	return map[string]interface{}{"volume": v}, nil
+	return gophercloud.BuildRequestBody(opts, "volume")
 }
 
 // Update will update the Volume with provided information. To extract the updated
 // Volume from the response, call the Extract method on the UpdateResult.
 func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
-	var res UpdateResult
-
-	reqBody, err := opts.ToVolumeUpdateMap()
+	var r UpdateResult
+	b, err := opts.ToVolumeUpdateMap()
 	if err != nil {
-		res.Err = err
-		return res
+		r.Err = err
+		return r
 	}
-
-	_, res.Err = client.Put(updateURL(client, id), reqBody, &res.Body, &gophercloud.RequestOpts{
+	_, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
 		OkCodes: []int{200},
 	})
-	return res
+	return r
 }
 
 // IDFromName is a convienience function that returns a server's ID given its name.
 func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
 	count := 0
 	id := ""
-	if name == "" {
-		err := &gophercloud.ErrMissingInput{}
-		err.Function = "volumes.IDFromName"
-		err.Argument = "name"
-		return "", err
-	}
-
 	pages, err := List(client, nil).AllPages()
 	if err != nil {
 		return "", err
@@ -233,19 +165,10 @@
 
 	switch count {
 	case 0:
-		err := &gophercloud.ErrResourceNotFound{}
-		err.Name = name
-		err.ResourceType = "volume"
-		err.Function = "volumes.IDFromName"
-		return "", err
+		return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "volume"}
 	case 1:
 		return id, nil
 	default:
-		err := &gophercloud.ErrMultipleResourcesFound{}
-		err.Count = count
-		err.Name = name
-		err.ResourceType = "volume"
-		err.Function = "volumes.IDFromName"
-		return "", err
+		return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "volume"}
 	}
 }