From 4e92b2ecb8b7fb7206faad64eaaca4d6ad35e749 Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Thu, 23 Mar 2017 20:54:59 +0530 Subject: [PATCH] Fix listDirHealFactory merging of entries across disks (#3959) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For listing of objects needing heal, we list all objects present on all the disks and return the set union. We were incorrectly dropping objects that weren't already seen in disks so far. Sample directory layout of disks in a 4-disk setup: `/tmp/1`, `/tmp/2`, `/tmp/3`, `/tmp/4` are directories used as disks here. `test` is the bucket, `obj1` and obj2` are the objects. ``` /tmp/1/test └── obj2 ├── part.1 ├── part.2 └── xl.json /tmp/2/test └── obj1 ├── part.1 ├── part.2 └── xl.json /tmp/3/test ├── obj1 │ ├── part.1 │ ├── part.2 │ └── xl.json └── obj2 ├── part.1 ├── part.2 └── xl.json /tmp/4/test [This is empty] ``` --- cmd/xl-v1-list-objects-heal.go | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/cmd/xl-v1-list-objects-heal.go b/cmd/xl-v1-list-objects-heal.go index cc6426584..949e95c44 100644 --- a/cmd/xl-v1-list-objects-heal.go +++ b/cmd/xl-v1-list-objects-heal.go @@ -35,37 +35,28 @@ func listDirHealFactory(isLeaf isLeafFunc, disks ...StorageAPI) listDirFunc { if err != nil { continue } - // Listing needs to be sorted. - sort.Strings(entries) // Filter entries that have the prefix prefixEntry. entries = filterMatchingPrefix(entries, prefixEntry) - // isLeaf() check has to happen here so that trailing "/" for objects can be removed. + // isLeaf() check has to happen here so that + // trailing "/" for objects can be removed. for i, entry := range entries { if isLeaf(bucket, pathJoin(prefixDir, entry)) { entries[i] = strings.TrimSuffix(entry, slashSeparator) } } - // Sort again after removing trailing "/" for objects as the previous sort - // does not hold good anymore. - sort.Strings(entries) - if len(mergedEntries) == 0 { - // For the first successful disk.ListDir() - mergedEntries = entries - sort.Strings(mergedEntries) - continue - } - // find elements in entries which are not in mergedentries + + // Find elements in entries which are not in mergedEntries for _, entry := range entries { idx := sort.SearchStrings(mergedEntries, entry) - // idx different from len(mergedEntries) means entry is not found - // in mergedEntries - if idx < len(mergedEntries) { + // if entry is already present in mergedEntries don't add. + if idx < len(mergedEntries) && mergedEntries[idx] == entry { continue } newEntries = append(newEntries, entry) } + if len(newEntries) > 0 { // Merge the entries and sort it. mergedEntries = append(mergedEntries, newEntries...)