|
|
package meta_cache
import ( "fmt" "strconv" "strings" )
type UidGidMapper struct { uidMapper *IdMapper gidMapper *IdMapper }
type IdMapper struct { localToFiler map[uint32]uint32 filerToLocal map[uint32]uint32 }
// UidGidMapper translates local uid/gid to filer uid/gid
// The local storage always persists the same as the filer.
// The local->filer translation happens when updating the filer first and later saving to meta_cache.
// And filer->local happens when reading from the meta_cache.
func NewUidGidMapper(uidPairsStr, gidPairStr string) (*UidGidMapper, error) { uidMapper, err := newIdMapper(uidPairsStr) if err != nil { return nil, err } gidMapper, err := newIdMapper(gidPairStr) if err != nil { return nil, err }
return &UidGidMapper{ uidMapper: uidMapper, gidMapper: gidMapper, }, nil }
func (m *UidGidMapper) LocalToFiler(uid, gid uint32) (uint32, uint32) { return m.uidMapper.LocalToFiler(uid), m.gidMapper.LocalToFiler(gid) } func (m *UidGidMapper) FilerToLocal(uid, gid uint32) (uint32, uint32) { return m.uidMapper.FilerToLocal(uid), m.gidMapper.FilerToLocal(gid) }
func (m *IdMapper) LocalToFiler(id uint32) uint32 { value, found := m.localToFiler[id] if found { return value } return id } func (m *IdMapper) FilerToLocal(id uint32) uint32 { value, found := m.filerToLocal[id] if found { return value } return id }
func newIdMapper(pairsStr string) (*IdMapper, error) {
localToFiler, filerToLocal, err := parseUint32Pairs(pairsStr) if err != nil { return nil, err }
return &IdMapper{ localToFiler: localToFiler, filerToLocal: filerToLocal, }, nil
}
func parseUint32Pairs(pairsStr string) (localToFiler, filerToLocal map[uint32]uint32, err error) {
if pairsStr == "" { return }
localToFiler = make(map[uint32]uint32) filerToLocal = make(map[uint32]uint32) for _, pairStr := range strings.Split(pairsStr, ",") { pair := strings.Split(pairStr, ":") localUidStr, filerUidStr := pair[0], pair[1] localUid, localUidErr := strconv.Atoi(localUidStr) if localUidErr != nil { err = fmt.Errorf("failed to parse local %s: %v", localUidStr, localUidErr) return } filerUid, filerUidErr := strconv.Atoi(filerUidStr) if filerUidErr != nil { err = fmt.Errorf("failed to parse remote %s: %v", filerUidStr, filerUidErr) return } localToFiler[uint32(localUid)] = uint32(filerUid) filerToLocal[uint32(filerUid)] = uint32(localUid) }
return }
|