Skip to content

Commit bf17c3e

Browse files
committed
filesystem: add back the mountsByPath map
Add back the mountsByPath map, which indexes all Mounts by mountpoint. This is needed again. To avoid confusion, also rename two local variables named mountsByPath. mountsByPath won't contain nil entries, so also make AllFilesystems() use it instead of mountsByDevice. This shouldn't change its behavior. Update #339
1 parent 8f619f9 commit bf17c3e

2 files changed

Lines changed: 32 additions & 21 deletions

File tree

filesystem/mountpoint.go

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ import (
3838
)
3939

4040
var (
41-
// This map holds data about the state of the system's filesystems.
41+
// These maps hold data about the state of the system's filesystems.
4242
//
43-
// It only contains one Mount per filesystem, even if there are
43+
// They only contain one Mount per filesystem, even if there are
4444
// additional bind mounts, since we want to store fscrypt metadata in
45-
// only one place per filesystem. If it is ambiguous which Mount should
46-
// be used, an explicit nil entry is stored.
45+
// only one place per filesystem. When it is ambiguous which Mount
46+
// should be used for a filesystem, mountsByDevice will contain an
47+
// explicit nil entry, and mountsByPath won't contain an entry.
4748
mountsByDevice map[DeviceNumber]*Mount
49+
mountsByPath map[string]*Mount
4850
// Used to make the mount functions thread safe
4951
mountMutex sync.Mutex
5052
// True if the maps have been successfully initialized.
@@ -197,18 +199,18 @@ func findMainMount(filesystemMounts []*Mount) *Mount {
197199
// since non-last mounts were already excluded earlier.
198200
//
199201
// Also build the set of all mounted subtrees.
200-
mountsByPath := make(map[string]*mountpointTreeNode)
202+
filesystemMountsByPath := make(map[string]*mountpointTreeNode)
201203
allSubtrees := make(map[string]bool)
202204
for _, mnt := range filesystemMounts {
203-
mountsByPath[mnt.Path] = &mountpointTreeNode{mount: mnt}
205+
filesystemMountsByPath[mnt.Path] = &mountpointTreeNode{mount: mnt}
204206
allSubtrees[mnt.Subtree] = true
205207
}
206208

207209
// Divide the mounts into non-overlapping trees of mountpoints.
208-
for path, mntNode := range mountsByPath {
210+
for path, mntNode := range filesystemMountsByPath {
209211
for path != "/" && mntNode.parent == nil {
210212
path = filepath.Dir(path)
211-
if parent := mountsByPath[path]; parent != nil {
213+
if parent := filesystemMountsByPath[path]; parent != nil {
212214
mntNode.parent = parent
213215
parent.children = append(parent.children, mntNode)
214216
}
@@ -233,7 +235,7 @@ func findMainMount(filesystemMounts []*Mount) *Mount {
233235
// *all* mounted subtrees. Equivalently, select a mountpoint tree in
234236
// which every uncontained subtree is mounted.
235237
var mainMount *Mount
236-
for _, mntNode := range mountsByPath {
238+
for _, mntNode := range filesystemMountsByPath {
237239
mnt := mntNode.mount
238240
if mntNode.parent != nil {
239241
continue
@@ -260,8 +262,10 @@ func findMainMount(filesystemMounts []*Mount) *Mount {
260262

261263
// This is separate from loadMountInfo() only for unit testing.
262264
func readMountInfo(r io.Reader) error {
263-
mountsByPath := make(map[string]*Mount)
264265
mountsByDevice = make(map[DeviceNumber]*Mount)
266+
mountsByPath = make(map[string]*Mount)
267+
allMountsByDevice := make(map[DeviceNumber][]*Mount)
268+
allMountsByPath := make(map[string]*Mount)
265269

266270
scanner := bufio.NewScanner(r)
267271
for scanner.Scan() {
@@ -281,19 +285,22 @@ func readMountInfo(r io.Reader) error {
281285
// Note this overrides the info if we have seen the mountpoint
282286
// earlier in the file. This is correct behavior because the
283287
// mountpoints are listed in mount order.
284-
mountsByPath[mnt.Path] = mnt
288+
allMountsByPath[mnt.Path] = mnt
285289
}
286290
// For each filesystem, choose a "main" Mount and discard any additional
287291
// bind mounts. fscrypt only cares about the main Mount, since it's
288-
// where the fscrypt metadata is stored. Store all main Mounts in
289-
// mountsByDevice so that they can be found by device number later.
290-
allMountsByDevice := make(map[DeviceNumber][]*Mount)
291-
for _, mnt := range mountsByPath {
292+
// where the fscrypt metadata is stored. Store all the main Mounts in
293+
// mountsByDevice and mountsByPath so that they can be found later.
294+
for _, mnt := range allMountsByPath {
292295
allMountsByDevice[mnt.DeviceNumber] =
293296
append(allMountsByDevice[mnt.DeviceNumber], mnt)
294297
}
295298
for deviceNumber, filesystemMounts := range allMountsByDevice {
296-
mountsByDevice[deviceNumber] = findMainMount(filesystemMounts)
299+
mnt := findMainMount(filesystemMounts)
300+
mountsByDevice[deviceNumber] = mnt // may store an explicit nil entry
301+
if mnt != nil {
302+
mountsByPath[mnt.Path] = mnt
303+
}
297304
}
298305
return nil
299306
}
@@ -329,11 +336,9 @@ func AllFilesystems() ([]*Mount, error) {
329336
return nil, err
330337
}
331338

332-
mounts := make([]*Mount, 0, len(mountsByDevice))
333-
for _, mount := range mountsByDevice {
334-
if mount != nil {
335-
mounts = append(mounts, mount)
336-
}
339+
mounts := make([]*Mount, 0, len(mountsByPath))
340+
for _, mount := range mountsByPath {
341+
mounts = append(mounts, mount)
337342
}
338343

339344
sort.Sort(PathSorter(mounts))

filesystem/mountpoint_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ func TestLoadMountInfoBasic(t *testing.T) {
9090
if mnt.ReadOnly {
9191
t.Error("Wrong readonly flag")
9292
}
93+
if len(mountsByPath) != 1 {
94+
t.Error("mountsByPath doesn't contain exactly one entry")
95+
}
96+
if mountsByPath[mnt.Path] != mnt {
97+
t.Error("mountsByPath doesn't contain the correct entry")
98+
}
9399
}
94100

95101
// Test that Mount.Device is set to the mountpoint's source device if

0 commit comments

Comments
 (0)