Merge pull request #2584 from greatroar/mount-cache-uid-gid

Cache uid and gid for top directories in internal/fuse
This commit is contained in:
MichaelEischer 2020-04-18 17:45:14 +02:00 committed by GitHub
commit f77477129f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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{ return &dir{
root: root, root: root,
node: &restic.Node{ node: &restic.Node{
UID: uint32(os.Getuid()),
GID: uint32(os.Getgid()),
AccessTime: snapshot.Time, AccessTime: snapshot.Time,
ModTime: snapshot.Time, ModTime: snapshot.Time,
ChangeTime: snapshot.Time, ChangeTime: snapshot.Time,
@ -114,11 +112,8 @@ func (d *dir) Attr(ctx context.Context, a *fuse.Attr) error {
debug.Log("called") debug.Log("called")
a.Inode = d.inode a.Inode = d.inode
a.Mode = os.ModeDir | d.node.Mode a.Mode = os.ModeDir | d.node.Mode
a.Uid = d.root.uid
if !d.root.cfg.OwnerIsRoot { a.Gid = d.root.gid
a.Uid = d.node.UID
a.Gid = d.node.GID
}
a.Atime = d.node.AccessTime a.Atime = d.node.AccessTime
a.Ctime = d.node.ChangeTime a.Ctime = d.node.ChangeTime
a.Mtime = d.node.ModTime a.Mtime = d.node.ModTime

View file

@ -8,6 +8,7 @@ package fuse
import ( import (
"bytes" "bytes"
"math/rand" "math/rand"
"os"
"testing" "testing"
"time" "time"
@ -152,3 +153,44 @@ func TestFuseFile(t *testing.T) {
rtest.OK(t, f.Release(ctx, nil)) 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 { func (d *MetaDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555 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) debug.Log("attr: %v", attr)
return nil return nil
} }

View file

@ -6,6 +6,7 @@
package fuse package fuse
import ( import (
"os"
"time" "time"
"github.com/restic/restic/internal/debug" "github.com/restic/restic/internal/debug"
@ -37,6 +38,8 @@ type Root struct {
lastCheck time.Time lastCheck time.Time
*MetaDir *MetaDir
uid, gid uint32
} }
// ensure that *Root implements these interfaces // 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()), blobSizeCache: NewBlobSizeCache(ctx, repo.Index()),
} }
if !cfg.OwnerIsRoot {
root.uid = uint32(os.Getuid())
root.gid = uint32(os.Getgid())
}
entries := map[string]fs.Node{ entries := map[string]fs.Node{
"snapshots": NewSnapshotsDir(root, fs.GenerateDynamicInode(root.inode, "snapshots"), "", ""), "snapshots": NewSnapshotsDir(root, fs.GenerateDynamicInode(root.inode, "snapshots"), "", ""),
"tags": NewTagsDir(root, fs.GenerateDynamicInode(root.inode, "tags")), "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 { func (d *SnapshotsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555 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) debug.Log("attr: %v", attr)
return nil 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 { func (d *SnapshotsIDSDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555 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) debug.Log("attr: %v", attr)
return nil 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 { func (d *HostsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555 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) debug.Log("attr: %v", attr)
return nil 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 { func (d *TagsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Inode = d.inode attr.Inode = d.inode
attr.Mode = os.ModeDir | 0555 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) debug.Log("attr: %v", attr)
return nil 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 { func (l *snapshotLink) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = l.inode a.Inode = l.inode
a.Mode = os.ModeSymlink | 0777 a.Mode = os.ModeSymlink | 0777
a.Uid = l.root.uid
if !l.root.cfg.OwnerIsRoot { a.Gid = l.root.gid
a.Uid = uint32(os.Getuid())
a.Gid = uint32(os.Getgid())
}
a.Atime = l.snapshot.Time a.Atime = l.snapshot.Time
a.Ctime = l.snapshot.Time a.Ctime = l.snapshot.Time
a.Mtime = l.snapshot.Time a.Mtime = l.snapshot.Time