You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							101 lines
						
					
					
						
							2.4 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							101 lines
						
					
					
						
							2.4 KiB
						
					
					
				| 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 | |
| }
 |