mount: name the disk without changing what is mounted (#11114)

mount: name the disk after the mount point when the whole tree is mounted

The mounted path was the only thing that named the disk, so a mount of the
whole tree was labelled with the filer address and the only way to give it
a name was to mount a subtree under that name — which hides everything
outside it. Fall back to the mount point's own name first, so
-dir=\\seaweedfs\Images labels the disk while -filer.path stays "/".

Claude-Session: https://claude.ai/code/session_01Q9f8pWBXu1ceJvcQfYRQ7x
This commit is contained in:
Chris Lu
2026-09-02 21:36:40 -07:00
committed by GitHub
parent 7465b6a80f
commit 292145303f
5 changed files with 56 additions and 11 deletions
+3 -1
View File
@@ -201,7 +201,9 @@ var cmdMount = &Command{
Where the platform labels the disk, in Finder and in Explorer, the mounted
path names it: -filer.path="/Image Disk" shows up as "Image Disk". Mounting
the whole tree labels it with the filer address instead.
the whole tree takes the name from the mount point instead, so
-dir=\\seaweedfs\Images labels the disk "Images" while still mounting
everything, and only a bare drive letter falls back to the filer address.
RDMA Acceleration:
For ultra-fast reads, enable RDMA acceleration with an RDMA sidecar:
+18 -5
View File
@@ -285,12 +285,25 @@ func resolveCacheDirs(option *MountOptions) (string, string) {
}
// volumeName labels the mount where the platform shows one, in Finder and in
// Explorer. The mounted path names the disk; the filer address, which every
// mount from one filer shares, is only the whole-tree fallback.
func volumeName(filer, filerMountRootPath string) string {
name := path.Base(filerMountRootPath)
if name == "/" || name == "." {
// Explorer. The mounted path names the disk, then the mount point; the filer
// address, which every mount from one filer shares, is the last resort.
func volumeName(filer, filerMountRootPath, dir string) string {
name := lastSegment(filerMountRootPath)
if name == "" {
name = lastSegment(dir)
}
if name == "" {
name = filer
}
return strings.ReplaceAll(name, ",", "+")
}
// lastSegment is the name a path ends with, and "" for the ones that name no
// disk: the root, "." and a bare Windows drive letter.
func lastSegment(p string) string {
name := path.Base(strings.ReplaceAll(p, `\`, "/"))
if name == "/" || name == "." || strings.HasSuffix(name, ":") {
return ""
}
return name
}
+33 -3
View File
@@ -9,12 +9,14 @@ func Test_volumeName(t *testing.T) {
name string
filer string
filerMountRootPath string
dir string
expected string
}{
{
name: "whole tree falls back to the filer",
name: "a drive letter leaves only the filer to fall back on",
filer: "127.0.0.1:8888",
filerMountRootPath: "/",
dir: "S:",
expected: "127.0.0.1:8888",
},
{
@@ -29,6 +31,34 @@ func Test_volumeName(t *testing.T) {
filerMountRootPath: "/",
expected: "127.0.0.1:8888+127.0.0.1:8889",
},
{
name: "a whole-tree mount takes the name of its network share",
filer: "127.0.0.1:8888",
filerMountRootPath: "/",
dir: `\\seaweedfs\Images`,
expected: "Images",
},
{
name: "a whole-tree mount takes the name of its directory",
filer: "127.0.0.1:8888",
filerMountRootPath: "/",
dir: "/mnt/seaweedfs",
expected: "seaweedfs",
},
{
name: "the mounted path outranks the mount point",
filer: "127.0.0.1:8888",
filerMountRootPath: "/buckets/videos",
dir: "/mnt/seaweedfs",
expected: "videos",
},
{
name: "a relative mount point is not a name",
filer: "127.0.0.1:8888",
filerMountRootPath: "/",
dir: ".",
expected: "127.0.0.1:8888",
},
{
name: "mounted directory names the disk",
filer: "127.0.0.1:8888",
@@ -50,8 +80,8 @@ func Test_volumeName(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := volumeName(tt.filer, tt.filerMountRootPath); got != tt.expected {
t.Errorf("volumeName(%q, %q) = %q, want %q", tt.filer, tt.filerMountRootPath, got, tt.expected)
if got := volumeName(tt.filer, tt.filerMountRootPath, tt.dir); got != tt.expected {
t.Errorf("volumeName(%q, %q, %q) = %q, want %q", tt.filer, tt.filerMountRootPath, tt.dir, got, tt.expected)
}
})
}
+1 -1
View File
@@ -179,7 +179,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
fuseMountOptions.Options = append(fuseMountOptions.Options, "novncache")
}
fuseMountOptions.Options = append(fuseMountOptions.Options, "slow_statfs")
fuseMountOptions.Options = append(fuseMountOptions.Options, "volname="+volumeName(*option.filer, filerMountRootPath))
fuseMountOptions.Options = append(fuseMountOptions.Options, "volname="+volumeName(*option.filer, filerMountRootPath, dir))
fuseMountOptions.Options = append(fuseMountOptions.Options, fmt.Sprintf("iosize=%d", ioSizeMB*1024*1024))
}
// Last, so an option given on the command line wins over the default
+1 -1
View File
@@ -104,7 +104,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
}
host := winfsp.New(seaweedFileSystem, winfsp.Options{
VolumeName: volumeName(*option.filer, *option.filerMountRootPath),
VolumeName: volumeName(*option.filer, *option.filerMountRootPath, dir),
Uid: ownedByMounter,
Gid: ownedByMounter,
CacheTimeout: windowsCacheTimeout,