XL: ListDir should return each List from a random disk in the set. (#1613)

Fixes #1609
master
Harshavardhana 9 years ago committed by Anand Babu (AB) Periasamy
parent 8099396ff0
commit 0e4e9c4bc1
  1. 37
      xl-erasure-v1.go

@ -18,6 +18,7 @@ package main
import ( import (
"fmt" "fmt"
"math/rand"
"os" "os"
slashpath "path" slashpath "path"
"strings" "strings"
@ -479,24 +480,32 @@ func (xl XL) ListDir(volume, dirPath string) (entries []string, err error) {
if !isValidVolname(volume) { if !isValidVolname(volume) {
return nil, errInvalidArgument return nil, errInvalidArgument
} }
// FIXME: need someway to figure out which disk has the latest namespace
// so that Listing can be done there. One option is always do Listing from
// the "local" disk - if it is down user has to list using another XL server.
// This way user knows from which disk he is listing from.
for _, disk := range xl.storageDisks { // Count for list errors encountered.
if entries, err = disk.ListDir(volume, dirPath); err != nil { var listErrCount = 0
continue
} // Loop through and return the first success entry based on the
for i, entry := range entries { // selected random disk.
if strings.HasSuffix(entry, slashSeparator) && isLeafDirectoryXL(disk, volume, path.Join(dirPath, entry)) { for listErrCount < len(xl.storageDisks) {
entries[i] = strings.TrimSuffix(entry, slashSeparator) // Choose a random disk on each attempt, do not hit the same disk all the time.
randIndex := rand.Intn(len(xl.storageDisks) - 1)
disk := xl.storageDisks[randIndex] // Pick a random disk.
// Initiate a list operation, if successful filter and return quickly.
if entries, err = disk.ListDir(volume, dirPath); err == nil {
for i, entry := range entries {
isLeaf := isLeafDirectoryXL(disk, volume, path.Join(dirPath, entry))
isDir := strings.HasSuffix(entry, slashSeparator)
if isDir && isLeaf {
entries[i] = strings.TrimSuffix(entry, slashSeparator)
}
} }
// We got the entries successfully return.
return entries, nil
} }
// We have list from one of the disks hence break the loop. listErrCount++ // Update list error count.
break
} }
return // Return error at the end.
return nil, err
} }
// Object API. // Object API.

Loading…
Cancel
Save