mirror of
https://github.com/restic/restic.git
synced 2026-05-14 22:35:23 +00:00
Merge pull request #21784 from jtru/fuse-mount-hardlink-count
mount: Ensure a hard link count > 0 for all files
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
Bugfix: Support exporting a `restic mount` of a Windows system via Samba
|
||||
|
||||
A repository mounted using `restic mount` on a POSIX system, could not use
|
||||
Samba to export files from restic backups of Windows systems. Backups of
|
||||
other systems were not affected. This has been fixed.
|
||||
|
||||
https://github.com/restic/restic/pull/21784
|
||||
https://github.com/restic/restic/issues/2034
|
||||
https://github.com/restic/restic/issues/4382
|
||||
@@ -55,7 +55,10 @@ func (f *file) Attr(_ context.Context, a *fuse.Attr) error {
|
||||
a.Size = f.node.Size
|
||||
a.Blocks = (f.node.Size + blockSize - 1) / blockSize
|
||||
a.BlockSize = blockSize
|
||||
a.Nlink = uint32(f.node.Links)
|
||||
// Windows (and other non-POSIX) backups may store a link count of 0.
|
||||
// FUSE must still report a positive nlink so tools that validate stat()
|
||||
// (e.g. Samba) accept the file.
|
||||
a.Nlink = max(uint32(1), uint32(f.node.Links))
|
||||
|
||||
if !f.root.cfg.OwnerIsRoot {
|
||||
a.Uid = f.node.UID
|
||||
|
||||
@@ -5,6 +5,7 @@ package fuse
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -277,6 +278,28 @@ func TestBlocks(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Windows (and other non-POSIX) backups may store a link count of 0; FUSE
|
||||
// must still report a positive nlink so tools that validate stat() (e.g.
|
||||
// Samba) accept the file.
|
||||
func TestFileAttrNlink(t *testing.T) {
|
||||
root := &Root{}
|
||||
for _, tc := range []struct {
|
||||
links uint64
|
||||
want uint32
|
||||
}{
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{42, 42},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("links_%d", tc.links), func(t *testing.T) {
|
||||
f := &file{root: root, node: &data.Node{Links: tc.links}}
|
||||
var a fuse.Attr
|
||||
rtest.OK(t, f.Attr(context.TODO(), &a))
|
||||
rtest.Equals(t, tc.want, a.Nlink)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInodeFromNode(t *testing.T) {
|
||||
node := &data.Node{Name: "foo.txt", Type: data.NodeTypeCharDev, Links: 2}
|
||||
ino1 := inodeFromNode(1, node)
|
||||
|
||||
Reference in New Issue
Block a user