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
							 | 
						|
								}
							 |