func (s *BlockVolume) OpenBlockFile() (file *BlockFile, err error) {
	if s.volume.Type != VolumeType {
		panic("Wrong type")
	}
	if err = s.mds.Lock(s.srv.Lease()); err != nil {
		return nil, err
	}
	defer func() {
		// If this function returns an error, attempt to release the lock.
		// TODO: Log unlock errors?
		if err != nil {
			s.mds.Unlock()
		}
	}()
	ref, err := s.mds.GetINode()
	if err != nil {
		return nil, err
	}
	inode, err := s.getOrCreateBlockINode(ref)
	if err != nil {
		return nil, err
	}
	bs, err := blockset.UnmarshalFromProto(inode.GetBlocks(), s.srv.Blocks)
	if err != nil {
		return nil, err
	}
	f, err := s.srv.CreateFile(s.volume, inode, bs)
	if err != nil {
		return nil, err
	}
	return &BlockFile{
		File: f,
		vol:  s,
	}, nil
}
func (b *blockvolGC) PrepVolume(vol *models.Volume) error {
	if vol.Type != VolumeType {
		return nil
	}
	mds, err := createBlockMetadata(b.srv.MDS, vol.Name, torus.VolumeID(vol.Id))
	if err != nil {
		return err
	}
	curRef, err := mds.GetINode()
	if err != nil {
		return err
	}
	b.highwaters[curRef.Volume()] = 0
	if curRef.INode <= 1 {
		return nil
	}

	snaps, err := mds.GetSnapshots()
	if err != nil {
		return err
	}

	curINodes := make([]torus.INodeRef, 0, len(snaps)+1)
	curINodes = append(curINodes, curRef)
	for _, x := range snaps {
		curINodes = append(curINodes, torus.INodeRefFromBytes(x.INodeRef))
	}

	for _, x := range curINodes {
		inode, err := b.inodes.GetINode(b.getContext(), x)
		if err != nil {
			return err
		}
		set, err := blockset.UnmarshalFromProto(inode.Blocks, nil)
		if err != nil {
			return err
		}
		refs := set.GetAllBlockRefs()
		for _, ref := range refs {
			if ref.IsZero() {
				continue
			}
			if ref.INode > b.highwaters[ref.Volume()] {
				b.highwaters[ref.Volume()] = ref.INode
			}
			b.set[ref] = true
		}
	}
	b.curINodes = append(b.curINodes, curINodes...)
	return nil
}
func (s *BlockVolume) OpenSnapshot(name string) (*BlockFile, error) {
	if s.volume.Type != VolumeType {
		panic("wrong type")
	}
	snaps, err := s.mds.GetSnapshots()
	if err != nil {
		return nil, err
	}
	var found Snapshot
	for _, x := range snaps {
		if x.Name == name {
			found = x
			break
		}
	}
	if found.Name != name {
		return nil, torus.ErrNotExist
	}
	ref := torus.INodeRefFromBytes(found.INodeRef)
	inode, err := s.getOrCreateBlockINode(ref)
	if err != nil {
		return nil, err
	}
	bs, err := blockset.UnmarshalFromProto(inode.GetBlocks(), s.srv.Blocks)
	if err != nil {
		return nil, err
	}
	f, err := s.srv.CreateFile(s.volume, inode, bs)
	if err != nil {
		return nil, err
	}
	f.ReadOnly = true
	return &BlockFile{
		File: f,
		vol:  s,
	}, nil
}