fuse: Properly set uid/gid for directories

In #2584 this was changed to use the uid/gid of the root node. This
would be okay for the top-level directory of a snapshot, however, this
change also applied to normal directories within a snapshot. This
change reverts the problematic part and adds a test that directory
attributes are represented correctly.
This commit is contained in:
Michael Eischer 2020-11-30 23:24:28 +01:00
parent 058b102db0
commit d05c88a5d6
3 changed files with 47 additions and 4 deletions

View file

@ -0,0 +1,8 @@
Bugfix: Use correct directory owner in fuse mount
Restic 0.10.0 changed the fuse mount to always report the current user
as the owner of directories within the fuse mount, which is incorrect.
We have changed this back to use the correct owner of a directory.
https://github.com/restic/restic/issues/2563
https://github.com/restic/restic/pull/3141

View file

@ -111,8 +111,11 @@ func (d *dir) Attr(ctx context.Context, a *fuse.Attr) error {
debug.Log("Attr()")
a.Inode = d.inode
a.Mode = os.ModeDir | d.node.Mode
a.Uid = d.root.uid
a.Gid = d.root.gid
if !d.root.cfg.OwnerIsRoot {
a.Uid = d.node.UID
a.Gid = d.node.GID
}
a.Atime = d.node.AccessTime
a.Ctime = d.node.ChangeTime
a.Mtime = d.node.ModTime

View file

@ -187,6 +187,37 @@ func TestFuseFile(t *testing.T) {
}
}
func TestFuseDir(t *testing.T) {
repo, cleanup := repository.TestRepository(t)
defer cleanup()
root := &Root{repo: repo, blobCache: newBlobCache(blobCacheSize)}
node := &restic.Node{
Mode: 0755,
UID: 42,
GID: 43,
AccessTime: time.Unix(1606773731, 0),
ChangeTime: time.Unix(1606773732, 0),
ModTime: time.Unix(1606773733, 0),
}
parentInode := fs.GenerateDynamicInode(0, "parent")
inode := fs.GenerateDynamicInode(1, "foo")
d, err := newDir(context.TODO(), root, inode, parentInode, node)
rtest.OK(t, err)
// don't open the directory as that would require setting up a proper tree blob
attr := fuse.Attr{}
rtest.OK(t, d.Attr(context.TODO(), &attr))
rtest.Equals(t, inode, attr.Inode)
rtest.Equals(t, node.UID, attr.Uid)
rtest.Equals(t, node.GID, attr.Gid)
rtest.Equals(t, node.AccessTime, attr.Atime)
rtest.Equals(t, node.ChangeTime, attr.Ctime)
rtest.Equals(t, node.ModTime, attr.Mtime)
}
// Test top-level directories for their UID and GID.
func TestTopUidGid(t *testing.T) {
repo, cleanup := repository.TestRepository(t)
@ -222,8 +253,9 @@ func testTopUidGid(t *testing.T, cfg Config, repo restic.Repository, uid, gid ui
snapshotdir, err := idsdir.(fs.NodeStringLookuper).Lookup(ctx, snapID)
rtest.OK(t, err)
// restic.TestCreateSnapshot does not set the UID/GID thus it must be always zero
err = snapshotdir.Attr(ctx, &attr)
rtest.OK(t, err)
rtest.Equals(t, uid, attr.Uid)
rtest.Equals(t, gid, attr.Gid)
rtest.Equals(t, uint32(0), attr.Uid)
rtest.Equals(t, uint32(0), attr.Gid)
}