github.com/dennwc/btrfs@v0.0.0-20221026161108-3097362dc072/uuid_tree.go (about)

     1  package btrfs
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"os"
     7  )
     8  
     9  func lookupUUIDSubvolItem(f *os.File, uuid UUID) (objectID, error) {
    10  	return uuidTreeLookupAny(f, uuid, uuidKeySubvol)
    11  }
    12  
    13  func lookupUUIDReceivedSubvolItem(f *os.File, uuid UUID) (objectID, error) {
    14  	return uuidTreeLookupAny(f, uuid, uuidKeyReceivedSubvol)
    15  }
    16  
    17  func (id UUID) toKey() (objID objectID, off uint64) {
    18  	objID = objectID(binary.LittleEndian.Uint64(id[:8]))
    19  	off = binary.LittleEndian.Uint64(id[8:16])
    20  	return
    21  }
    22  
    23  // uuidTreeLookupAny searches uuid tree for a given uuid in specified field.
    24  // It returns ErrNotFound if object was not found.
    25  func uuidTreeLookupAny(f *os.File, uuid UUID, typ treeKeyType) (objectID, error) {
    26  	objId, off := uuid.toKey()
    27  	args := btrfs_ioctl_search_key{
    28  		tree_id:      uuidTreeObjectid,
    29  		min_objectid: objId,
    30  		max_objectid: objId,
    31  		min_type:     typ,
    32  		max_type:     typ,
    33  		min_offset:   off,
    34  		max_offset:   off,
    35  		max_transid:  maxUint64,
    36  		nr_items:     1,
    37  	}
    38  	res, err := treeSearchRaw(f, args)
    39  	if err != nil {
    40  		return 0, err
    41  	} else if len(res) < 1 {
    42  		return 0, ErrNotFound
    43  	}
    44  	out := res[0]
    45  	if len(out.Data) != 8 {
    46  		return 0, fmt.Errorf("btrfs: uuid item with illegal size %d", len(out.Data))
    47  	}
    48  	return objectID(binary.LittleEndian.Uint64(out.Data)), nil
    49  }