code: func (c *cinderPlugin) SnapshotRestore(snapshotData *crdv1.VolumeSnapshotData, pvc *v1.PersistentVolumeClaim, pvName string, parameters map[string]string) (*v1.PersistentVolumeSource, map[string]string, error) {
  	var tags = make(map[string]string)
  	var vType string
  	var zone string
  
  	if snapshotData == nil || snapshotData.Spec.CinderSnapshot == nil {
  		return nil, nil, fmt.Errorf("failed to retrieve Snapshot spec")
  	}
  	if pvc == nil {
  		return nil, nil, fmt.Errorf("no pvc specified")
  	}
  	snapID := snapshotData.Spec.CinderSnapshot.SnapshotID
  	volName := pvName
  	capacity := pvc.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
  	requestedSz := capacity.Value()
  	szGB := k8sVol.RoundUpSize(requestedSz, 1024*1024*1024)
  
  	for k, v := range parameters {
  		switch strings.ToLower(k) {
  		case "type":
  			vType = v
  		case "zone":
  			zone = v
  		default:
  			return nil, nil, fmt.Errorf("invalid option %q for volume plugin %s", k, GetPluginName())
  		}
  	}
  
  	// FIXME(j-griffith): Should probably use int64 in gophercloud?
  	volumeID, _, err := c.cloud.CreateVolume(volName, int(szGB), vType, zone, snapID, &tags)
  	if err != nil {
  		glog.Errorf("error create volume from snapshot: %v", err)
  		return nil, nil, err
  	}
  	glog.V(2).Infof("Successfully created Cinder Volume from Snapshot, Volume: %s", volumeID)
  	pv := &v1.PersistentVolumeSource{
  		Cinder: &v1.CinderPersistentVolumeSource{
  			VolumeID: volumeID,
  			FSType:   "ext4",
  			ReadOnly: false,
  		},
  	}
  	return pv, nil, nil
  }
docs: // SnapshotRestore creates a new Volume using the data on the specified Snapshot