code: func (devices *DeviceSet) ensureImage(name string, size int64) (string, error) {
  	dirname := devices.loopbackDir()
  	filename := path.Join(dirname, name)
  
  	uid, gid, err := idtools.GetRootUIDGID(devices.uidMaps, devices.gidMaps)
  	if err != nil {
  		return "", err
  	}
  	if err := idtools.MkdirAllAndChown(dirname, 0700, idtools.Identity{UID: uid, GID: gid}); err != nil {
  		return "", err
  	}
  
  	if fi, err := os.Stat(filename); err != nil {
  		if !os.IsNotExist(err) {
  			return "", err
  		}
  		logrus.WithField("storage-driver", "devicemapper").Debugf("Creating loopback file %s for device-manage use", filename)
  		file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0600)
  		if err != nil {
  			return "", err
  		}
  		defer file.Close()
  
  		if err := file.Truncate(size); err != nil {
  			return "", err
  		}
  	} else {
  		if fi.Size() < size {
  			file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0600)
  			if err != nil {
  				return "", err
  			}
  			defer file.Close()
  			if err := file.Truncate(size); err != nil {
  				return "", fmt.Errorf("devmapper: Unable to grow loopback file %s: %v", filename, err)
  			}
  		} else if fi.Size() > size {
  			logrus.WithField("storage-driver", "devicemapper").Warnf("Can't shrink loopback file %s", filename)
  		}
  	}
  	return filename, nil
  }
docs: // ensureImage creates a sparse file of <size> bytes at the path
  // <root>/devicemapper/<name>.
  // If the file already exists and new size is larger than its current size, it grows to the new size.
  // Either way it returns the full path.