Chris Lu
4 years ago
10 changed files with 154 additions and 5 deletions
-
4weed/command/mount.go
-
9weed/command/mount_std.go
-
10weed/filesys/dir.go
-
4weed/filesys/dir_link.go
-
3weed/filesys/file.go
-
3weed/filesys/filehandle.go
-
101weed/filesys/meta_cache/id_mapper.go
-
12weed/filesys/meta_cache/meta_cache.go
-
2weed/filesys/meta_cache/meta_cache_subscribe.go
-
11weed/filesys/wfs.go
@ -0,0 +1,101 @@ |
|||||
|
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 %d: %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 |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue