2
2
mirror of https://github.com/octoleo/restic.git synced 2024-12-26 20:30:19 +00:00

Cache uid and gid for top directories in internal/fuse

This commit is contained in:
greatroar 2020-02-17 16:26:53 +01:00
parent f2bf06a419
commit 1b502fa9ef
5 changed files with 64 additions and 32 deletions

View File

@ -98,8 +98,6 @@ func newDirFromSnapshot(ctx context.Context, root *Root, inode uint64, snapshot
return &dir{
root: root,
node: &restic.Node{
UID: uint32(os.Getuid()),
GID: uint32(os.Getgid()),
AccessTime: snapshot.Time,
ModTime: snapshot.Time,
ChangeTime: snapshot.Time,
@ -114,11 +112,8 @@ func (d *dir) Attr(ctx context.Context, a *fuse.Attr) error {
debug.Log("called")
a.Inode = d.inode
a.Mode = os.ModeDir | d.node.Mode
if !d.root.cfg.OwnerIsRoot {
a.Uid = d.node.UID
a.Gid = d.node.GID
}
a.Uid = d.root.uid
a.Gid = d.root.gid
a.Atime = d.node.AccessTime
a.Ctime = d.node.ChangeTime
a.Mtime = d.node.ModTime

View File

@ -8,6 +8,7 @@ package fuse
import (
"bytes"
"math/rand"
"os"
"testing"
"time"
@ -152,3 +153,44 @@ func TestFuseFile(t *testing.T) {
rtest.OK(t, f.Release(ctx, nil))
}
// Test top-level directories for their UID and GID.
func TestTopUidGid(t *testing.T) {
repo, cleanup := repository.TestRepository(t)
defer cleanup()
restic.TestCreateSnapshot(t, repo, time.Unix(1460289341, 207401672), 0, 0)
testTopUidGid(t, Config{}, repo, uint32(os.Getuid()), uint32(os.Getgid()))
testTopUidGid(t, Config{OwnerIsRoot: true}, repo, 0, 0)
}
func testTopUidGid(t *testing.T, cfg Config, repo restic.Repository, uid, gid uint32) {
t.Helper()
ctx := context.Background()
root, err := NewRoot(ctx, repo, cfg)
rtest.OK(t, err)
var attr fuse.Attr
err = root.Attr(ctx, &attr)
rtest.OK(t, err)
rtest.Equals(t, uid, attr.Uid)
rtest.Equals(t, gid, attr.Gid)
idsdir, err := root.Lookup(ctx, "ids")
rtest.OK(t, err)
err = idsdir.Attr(ctx, &attr)
rtest.OK(t, err)
rtest.Equals(t, uid, attr.Uid)
rtest.Equals(t, gid, attr.Gid)
snapID := loadFirstSnapshot(t, repo).ID().Str()
snapshotdir, err := idsdir.(fs.NodeStringLookuper).Lookup(ctx, snapID)
err = snapshotdir.Attr(ctx, &attr)
rtest.OK(t, err)
rtest.Equals(t, uid, attr.Uid)
rtest.Equals(t, gid, attr.Gid)
}

View File

@ -42,11 +42,9 @@ func NewMetaDir(root *Root, inode uint64, entries map[string]fs.Node) *MetaDir {
func (d *MetaDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555
attr.Uid = d.root.uid
attr.Gid = d.root.gid
if !d.root.cfg.OwnerIsRoot {
attr.Uid = uint32(os.Getuid())
attr.Gid = uint32(os.Getgid())
}
debug.Log("attr: %v", attr)
return nil
}

View File

@ -6,6 +6,7 @@
package fuse
import (
"os"
"time"
"github.com/restic/restic/internal/debug"
@ -37,6 +38,8 @@ type Root struct {
lastCheck time.Time
*MetaDir
uid, gid uint32
}
// ensure that *Root implements these interfaces
@ -56,6 +59,11 @@ func NewRoot(ctx context.Context, repo restic.Repository, cfg Config) (*Root, er
blobSizeCache: NewBlobSizeCache(ctx, repo.Index()),
}
if !cfg.OwnerIsRoot {
root.uid = uint32(os.Getuid())
root.gid = uint32(os.Getgid())
}
entries := map[string]fs.Node{
"snapshots": NewSnapshotsDir(root, fs.GenerateDynamicInode(root.inode, "snapshots"), "", ""),
"tags": NewTagsDir(root, fs.GenerateDynamicInode(root.inode, "tags")),

View File

@ -168,11 +168,9 @@ func NewTagsDir(root *Root, inode uint64) *TagsDir {
func (d *SnapshotsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555
attr.Uid = d.root.uid
attr.Gid = d.root.gid
if !d.root.cfg.OwnerIsRoot {
attr.Uid = uint32(os.Getuid())
attr.Gid = uint32(os.Getgid())
}
debug.Log("attr: %v", attr)
return nil
}
@ -181,11 +179,9 @@ func (d *SnapshotsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
func (d *SnapshotsIDSDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555
attr.Uid = d.root.uid
attr.Gid = d.root.gid
if !d.root.cfg.OwnerIsRoot {
attr.Uid = uint32(os.Getuid())
attr.Gid = uint32(os.Getgid())
}
debug.Log("attr: %v", attr)
return nil
}
@ -194,11 +190,9 @@ func (d *SnapshotsIDSDir) Attr(ctx context.Context, attr *fuse.Attr) error {
func (d *HostsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555
attr.Uid = d.root.uid
attr.Gid = d.root.gid
if !d.root.cfg.OwnerIsRoot {
attr.Uid = uint32(os.Getuid())
attr.Gid = uint32(os.Getgid())
}
debug.Log("attr: %v", attr)
return nil
}
@ -207,11 +201,9 @@ func (d *HostsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
func (d *TagsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555
attr.Uid = d.root.uid
attr.Gid = d.root.gid
if !d.root.cfg.OwnerIsRoot {
attr.Uid = uint32(os.Getuid())
attr.Gid = uint32(os.Getgid())
}
debug.Log("attr: %v", attr)
return nil
}
@ -437,11 +429,8 @@ func (l *snapshotLink) Readlink(ctx context.Context, req *fuse.ReadlinkRequest)
func (l *snapshotLink) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = l.inode
a.Mode = os.ModeSymlink | 0777
if !l.root.cfg.OwnerIsRoot {
a.Uid = uint32(os.Getuid())
a.Gid = uint32(os.Getgid())
}
a.Uid = l.root.uid
a.Gid = l.root.gid
a.Atime = l.snapshot.Time
a.Ctime = l.snapshot.Time
a.Mtime = l.snapshot.Time