diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index b9cdb6665..2a455089f 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -731,37 +731,11 @@ func (fs fsObjects) listDirFactory(isLeaf isLeafFunc) listDirFunc { // listDir - lists all the entries at a given prefix and given entry in the prefix. listDir := func(bucket, prefixDir, prefixEntry string) (entries []string, delayIsLeaf bool, err error) { entries, err = readDir(pathJoin(fs.fsPath, bucket, prefixDir)) - if err == nil { - // Listing needs to be sorted. - sort.Strings(entries) - - // Filter entries that have the prefix prefixEntry. - entries = filterMatchingPrefix(entries, prefixEntry) - - // Can isLeaf() check be delayed till when it has to be sent down the - // treeWalkResult channel? - delayIsLeaf = delayIsLeafCheck(entries) - if delayIsLeaf { - return entries, delayIsLeaf, nil - } - - // 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) - - // Succes. - return entries, delayIsLeaf, nil - } // Return error at the end. - - // Error. - return nil, false, err + if err != nil { + return nil, false, err + } + entries, delayIsLeaf = filterListEntries(bucket, prefixDir, entries, prefixEntry, isLeaf) + return entries, delayIsLeaf, nil } // Return list factory instance. diff --git a/cmd/tree-walk.go b/cmd/tree-walk.go index 92cfb8578..8993a96d0 100644 --- a/cmd/tree-walk.go +++ b/cmd/tree-walk.go @@ -95,53 +95,30 @@ type listDirFunc func(bucket, prefixDir, prefixEntry string) (entries []string, // 4. XL backend multipart listing - isLeaf is true if the entry is a directory and contains uploads.json type isLeafFunc func(string, string) bool -// Returns function "listDir" of the type listDirFunc. -// isLeaf - is used by listDir function to check if an entry is a leaf or non-leaf entry. -// disks - used for doing disk.ListDir(). FS passes single disk argument, XL passes a list of disks. -func listDirFactory(isLeaf isLeafFunc, treeWalkIgnoredErrs []error, disks ...StorageAPI) listDirFunc { - // listDir - lists all the entries at a given prefix and given entry in the prefix. - listDir := func(bucket, prefixDir, prefixEntry string) (entries []string, delayIsLeaf bool, err error) { - for _, disk := range disks { - if disk == nil { - continue - } - entries, err = disk.ListDir(bucket, prefixDir) - if err == nil { - // Listing needs to be sorted. - sort.Strings(entries) - - // Filter entries that have the prefix prefixEntry. - entries = filterMatchingPrefix(entries, prefixEntry) - - // Can isLeaf() check be delayed till when it has to be sent down the - // treeWalkResult channel? - delayIsLeaf = delayIsLeafCheck(entries) - if delayIsLeaf { - return entries, delayIsLeaf, nil - } +func filterListEntries(bucket, prefixDir string, entries []string, prefixEntry string, isLeaf isLeafFunc) ([]string, bool) { + // Listing needs to be sorted. + sort.Strings(entries) + + // Filter entries that have the prefix prefixEntry. + entries = filterMatchingPrefix(entries, prefixEntry) + + // Can isLeaf() check be delayed till when it has to be sent down the + // treeWalkResult channel? + delayIsLeaf := delayIsLeafCheck(entries) + if delayIsLeaf { + return entries, true + } - // 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) - return entries, delayIsLeaf, nil - } - // For any reason disk was deleted or goes offline, continue - // and list from other disks if possible. - if isErrIgnored(err, treeWalkIgnoredErrs...) { - continue - } - break + // 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) } - // Return error at the end. - return nil, false, traceError(err) } - return listDir + // Sort again after removing trailing "/" for objects as the previous sort + // does not hold good anymore. + sort.Strings(entries) + return entries, false } // treeWalk walks directory tree recursively pushing treeWalkResult into the channel as and when it encounters files. diff --git a/cmd/xl-v1-list-objects.go b/cmd/xl-v1-list-objects.go index 477c25768..b9fff36ee 100644 --- a/cmd/xl-v1-list-objects.go +++ b/cmd/xl-v1-list-objects.go @@ -18,6 +18,34 @@ package cmd import "strings" +// Returns function "listDir" of the type listDirFunc. +// isLeaf - is used by listDir function to check if an entry is a leaf or non-leaf entry. +// disks - used for doing disk.ListDir(). FS passes single disk argument, XL passes a list of disks. +func listDirFactory(isLeaf isLeafFunc, treeWalkIgnoredErrs []error, disks ...StorageAPI) listDirFunc { + // listDir - lists all the entries at a given prefix and given entry in the prefix. + listDir := func(bucket, prefixDir, prefixEntry string) (entries []string, delayIsLeaf bool, err error) { + for _, disk := range disks { + if disk == nil { + continue + } + entries, err = disk.ListDir(bucket, prefixDir) + if err == nil { + entries, delayIsLeaf = filterListEntries(bucket, prefixDir, entries, prefixEntry, isLeaf) + return entries, delayIsLeaf, nil + } + // For any reason disk was deleted or goes offline, continue + // and list from other disks if possible. + if isErrIgnored(err, treeWalkIgnoredErrs...) { + continue + } + break + } + // Return error at the end. + return nil, false, traceError(err) + } + return listDir +} + // listObjects - wrapper function implemented over file tree walk. func (xl xlObjects) listObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) { // Default is recursive, if delimiter is set then list non recursive.