mirror of
https://github.com/minio/minio.git
synced 2025-11-20 18:06:10 -05:00
fix: Bring support for symlink on regular files on NAS (#11383)
fixes #11203
This commit is contained in:
@@ -42,6 +42,15 @@ func readDirFn(dirPath string, filter func(name string, typ os.FileMode) error)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Check if file or dir. This is the quickest way.
|
||||
// Do not remove this check, on windows syscall.FindNextFile
|
||||
// would throw an exception if Fd() points to a file
|
||||
// instead of a directory, we need to quickly fail
|
||||
// in such situations - this workadound is expected.
|
||||
if _, err = f.Seek(0, io.SeekStart); err == nil {
|
||||
return errFileNotFound
|
||||
}
|
||||
|
||||
data := &syscall.Win32finddata{}
|
||||
for {
|
||||
e := syscall.FindNextFile(syscall.Handle(f.Fd()), data)
|
||||
@@ -63,13 +72,33 @@ func readDirFn(dirPath string, filter func(name string, typ os.FileMode) error)
|
||||
if name == "" || name == "." || name == ".." { // Useless names
|
||||
continue
|
||||
}
|
||||
if data.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
var typ os.FileMode = 0 // regular file
|
||||
if data.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
|
||||
switch {
|
||||
case data.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0:
|
||||
// Reparse point is a symlink
|
||||
fi, err := os.Stat(pathJoin(dirPath, string(name)))
|
||||
if err != nil {
|
||||
// It got deleted in the meantime, not found
|
||||
// or returns too many symlinks ignore this
|
||||
// file/directory.
|
||||
if osIsNotExist(err) || isSysErrPathNotFound(err) ||
|
||||
isSysErrTooManySymlinks(err) {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
// Ignore symlinked directories.
|
||||
continue
|
||||
}
|
||||
|
||||
typ = fi.Mode()
|
||||
case data.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0:
|
||||
typ = os.ModeDir
|
||||
}
|
||||
|
||||
if e = filter(name, typ); e == errDoneForNow {
|
||||
// filtering requested to return by caller.
|
||||
return nil
|
||||
@@ -88,10 +117,14 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
|
||||
defer f.Close()
|
||||
|
||||
// Check if file or dir. This is the quickest way.
|
||||
_, err = f.Seek(0, io.SeekStart)
|
||||
if err == nil {
|
||||
// Do not remove this check, on windows syscall.FindNextFile
|
||||
// would throw an exception if Fd() points to a file
|
||||
// instead of a directory, we need to quickly fail
|
||||
// in such situations - this workadound is expected.
|
||||
if _, err = f.Seek(0, io.SeekStart); err == nil {
|
||||
return nil, errFileNotFound
|
||||
}
|
||||
|
||||
data := &syscall.Win32finddata{}
|
||||
handle := syscall.Handle(f.Fd())
|
||||
|
||||
@@ -113,15 +146,33 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
|
||||
if name == "" || name == "." || name == ".." { // Useless names
|
||||
continue
|
||||
}
|
||||
|
||||
switch {
|
||||
case data.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0:
|
||||
continue
|
||||
// Reparse point is a symlink
|
||||
fi, err := os.Stat(pathJoin(dirPath, string(name)))
|
||||
if err != nil {
|
||||
// It got deleted in the meantime, not found
|
||||
// or returns too many symlinks ignore this
|
||||
// file/directory.
|
||||
if osIsNotExist(err) || isSysErrPathNotFound(err) ||
|
||||
isSysErrTooManySymlinks(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
// directory symlinks are ignored.
|
||||
continue
|
||||
}
|
||||
case data.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0:
|
||||
entries = append(entries, name+SlashSeparator)
|
||||
default:
|
||||
entries = append(entries, name)
|
||||
name = name + SlashSeparator
|
||||
}
|
||||
|
||||
count--
|
||||
entries = append(entries, name)
|
||||
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
|
||||
Reference in New Issue
Block a user