code: func (s *VolumesService) Prune(ctx context.Context, filter filters.Args) (*types.VolumesPruneReport, error) {
  	if !atomic.CompareAndSwapInt32(&s.pruneRunning, 0, 1) {
  		return nil, errdefs.Conflict(errors.New("a prune operation is already running"))
  	}
  	defer atomic.StoreInt32(&s.pruneRunning, 0)
  
  	by, err := filtersToBy(filter, acceptedPruneFilters)
  	if err != nil {
  		return nil, err
  	}
  	ls, _, err := s.vs.Find(ctx, And(ByDriver(volume.DefaultDriverName), ByReferenced(false), by, CustomFilter(func(v volume.Volume) bool {
  		dv, ok := v.(volume.DetailedVolume)
  		return ok && len(dv.Options()) == 0
  	})))
  	if err != nil {
  		return nil, err
  	}
  
  	rep := &types.VolumesPruneReport{VolumesDeleted: make([]string, 0, len(ls))}
  	for _, v := range ls {
  		select {
  		case <-ctx.Done():
  			err := ctx.Err()
  			if err == context.Canceled {
  				err = nil
  			}
  			return rep, err
  		default:
  		}
  
  		vSize, err := directory.Size(ctx, v.Path())
  		if err != nil {
  			logrus.WithField("volume", v.Name()).WithError(err).Warn("could not determine size of volume")
  		}
  		if err := s.vs.Remove(ctx, v); err != nil {
  			logrus.WithError(err).WithField("volume", v.Name()).Warnf("Could not determine size of volume")
  			continue
  		}
  		rep.SpaceReclaimed += uint64(vSize)
  		rep.VolumesDeleted = append(rep.VolumesDeleted, v.Name())
  	}
  	return rep, nil
  }
docs: // Prune removes (local) volumes which match the past in filter arguments.
  // Note that this intentionally skips volumes with mount options as there would
  // be no space reclaimed in this case.