From 7658305c76c1152d9b1932bc1a793ee3425db89e Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Tue, 25 Aug 2026 22:56:33 -0700 Subject: [PATCH] mount: name the disk after the mounted path (#10958) * mount: name the disk after the mounted path Finder and Explorer labelled every mount with the filer address, so two mounts from one filer were indistinguishable. Use the mounted path's last segment, the way df already shows it, and keep the filer address only for a whole-tree mount. * mount: let a given mount option override the default The options from -o were placed before the ones this mount derives, so a volname or iosize given on the command line lost to the derived value. Append them last, matching the Windows adapter. * mount: document what labels the disk --- weed/command/mount.go | 4 +++ weed/command/mount_common.go | 11 ++++++ weed/command/mount_common_test.go | 58 +++++++++++++++++++++++++++++++ weed/command/mount_std.go | 6 ++-- weed/command/mount_windows.go | 2 +- 5 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 weed/command/mount_common_test.go diff --git a/weed/command/mount.go b/weed/command/mount.go index 8bbdca2da..c42dfcdcf 100644 --- a/weed/command/mount.go +++ b/weed/command/mount.go @@ -199,6 +199,10 @@ var cmdMount = &Command{ at the desktop; the network path form is reachable from every session, and each user can map their own drive letter to it. + 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. + RDMA Acceleration: For ultra-fast reads, enable RDMA acceleration with an RDMA sidecar: weed mount -filer=localhost:8888 -dir=/mnt/seaweedfs \ diff --git a/weed/command/mount_common.go b/weed/command/mount_common.go index c3ac11d3b..c61912955 100644 --- a/weed/command/mount_common.go +++ b/weed/command/mount_common.go @@ -283,3 +283,14 @@ func resolveCacheDirs(option *MountOptions) (string, string) { } return cacheDirForRead, cacheDirForWrite } + +// 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 == "." { + name = filer + } + return strings.ReplaceAll(name, ",", "+") +} diff --git a/weed/command/mount_common_test.go b/weed/command/mount_common_test.go new file mode 100644 index 000000000..b5b3226b7 --- /dev/null +++ b/weed/command/mount_common_test.go @@ -0,0 +1,58 @@ +//go:build linux || darwin || freebsd || windows + +package command + +import "testing" + +func Test_volumeName(t *testing.T) { + tests := []struct { + name string + filer string + filerMountRootPath string + expected string + }{ + { + name: "whole tree falls back to the filer", + filer: "127.0.0.1:8888", + filerMountRootPath: "/", + expected: "127.0.0.1:8888", + }, + { + name: "empty path falls back to the filer", + filer: "127.0.0.1:8888", + filerMountRootPath: "", + expected: "127.0.0.1:8888", + }, + { + name: "several filers stay parseable as one option", + filer: "127.0.0.1:8888,127.0.0.1:8889", + filerMountRootPath: "/", + expected: "127.0.0.1:8888+127.0.0.1:8889", + }, + { + name: "mounted directory names the disk", + filer: "127.0.0.1:8888", + filerMountRootPath: "/buckets/images", + expected: "images", + }, + { + name: "trailing slash is not a name", + filer: "127.0.0.1:8888", + filerMountRootPath: "/buckets/videos/", + expected: "videos", + }, + { + name: "spaces are kept, commas are not", + filer: "127.0.0.1:8888", + filerMountRootPath: "/Image, Disk", + expected: "Image+ Disk", + }, + } + 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) + } + }) + } +} diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go index b352aea95..f29c51ddd 100644 --- a/weed/command/mount_std.go +++ b/weed/command/mount_std.go @@ -134,7 +134,6 @@ func RunMount(option *MountOptions, umask os.FileMode) bool { // mount fuse fuseMountOptions := &fuse.MountOptions{ AllowOther: *option.allowOthers, - Options: option.extraOptions, MaxBackground: maxBackground, CongestionThreshold: congestionThreshold, MaxWrite: 1024 * 1024 * 2, @@ -180,9 +179,12 @@ 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="+serverFriendlyName) + fuseMountOptions.Options = append(fuseMountOptions.Options, "volname="+volumeName(*option.filer, filerMountRootPath)) 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 + // this mount picked for it. + fuseMountOptions.Options = append(fuseMountOptions.Options, option.extraOptions...) if option.writebackCache != nil { fuseMountOptions.EnableWriteback = *option.writebackCache diff --git a/weed/command/mount_windows.go b/weed/command/mount_windows.go index fe52e565f..e32019f2e 100644 --- a/weed/command/mount_windows.go +++ b/weed/command/mount_windows.go @@ -104,7 +104,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool { } host := winfsp.New(seaweedFileSystem, winfsp.Options{ - VolumeName: strings.ReplaceAll(*option.filer, ",", "+"), + VolumeName: volumeName(*option.filer, *option.filerMountRootPath), Uid: ownedByMounter, Gid: ownedByMounter, CacheTimeout: windowsCacheTimeout,