github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/xl-storage-errors.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"errors"
    22  	"os"
    23  	"runtime"
    24  	"syscall"
    25  )
    26  
    27  // No space left on device error
    28  func isSysErrNoSpace(err error) bool {
    29  	return errors.Is(err, syscall.ENOSPC)
    30  }
    31  
    32  // Invalid argument, unsupported flags such as O_DIRECT
    33  func isSysErrInvalidArg(err error) bool {
    34  	return errors.Is(err, syscall.EINVAL)
    35  }
    36  
    37  // Input/output error
    38  func isSysErrIO(err error) bool {
    39  	return errors.Is(err, syscall.EIO)
    40  }
    41  
    42  // Check if the given error corresponds to EISDIR (is a directory).
    43  func isSysErrIsDir(err error) bool {
    44  	return errors.Is(err, syscall.EISDIR)
    45  }
    46  
    47  // Check if the given error corresponds to ENOTDIR (is not a directory).
    48  func isSysErrNotDir(err error) bool {
    49  	return errors.Is(err, syscall.ENOTDIR)
    50  }
    51  
    52  // Check if the given error corresponds to the ENAMETOOLONG (name too long).
    53  func isSysErrTooLong(err error) bool {
    54  	return errors.Is(err, syscall.ENAMETOOLONG)
    55  }
    56  
    57  // Check if the given error corresponds to the ELOOP (too many symlinks).
    58  func isSysErrTooManySymlinks(err error) bool {
    59  	return errors.Is(err, syscall.ELOOP)
    60  }
    61  
    62  // Check if the given error corresponds to ENOTEMPTY for unix,
    63  // EEXIST for solaris variants,
    64  // and ERROR_DIR_NOT_EMPTY for windows (directory not empty).
    65  func isSysErrNotEmpty(err error) bool {
    66  	if errors.Is(err, syscall.ENOTEMPTY) {
    67  		return true
    68  	}
    69  	if errors.Is(err, syscall.EEXIST) && runtime.GOOS == "solaris" {
    70  		return true
    71  	}
    72  	var pathErr *os.PathError
    73  	if errors.As(err, &pathErr) {
    74  		if runtime.GOOS == globalWindowsOSName {
    75  			var errno syscall.Errno
    76  			if errors.As(pathErr.Err, &errno) {
    77  				// ERROR_DIR_NOT_EMPTY
    78  				return errno == 0x91
    79  			}
    80  		}
    81  	}
    82  	return false
    83  }
    84  
    85  // Check if the given error corresponds to the specific ERROR_PATH_NOT_FOUND for windows
    86  func isSysErrPathNotFound(err error) bool {
    87  	if runtime.GOOS != globalWindowsOSName {
    88  		var pathErr *os.PathError
    89  		if errors.As(err, &pathErr) {
    90  			return pathErr.Err == syscall.ENOENT
    91  		}
    92  		return false
    93  	}
    94  	var pathErr *os.PathError
    95  	if errors.As(err, &pathErr) {
    96  		var errno syscall.Errno
    97  		if errors.As(pathErr.Err, &errno) {
    98  			// ERROR_PATH_NOT_FOUND
    99  			return errno == 0x03
   100  		}
   101  	}
   102  	return false
   103  }
   104  
   105  // Check if the given error corresponds to the specific ERROR_INVALID_HANDLE for windows
   106  func isSysErrHandleInvalid(err error) bool {
   107  	if runtime.GOOS != globalWindowsOSName {
   108  		return false
   109  	}
   110  	// Check if err contains ERROR_INVALID_HANDLE errno
   111  	var pathErr *os.PathError
   112  	if errors.As(err, &pathErr) {
   113  		var errno syscall.Errno
   114  		if errors.As(pathErr.Err, &errno) {
   115  			// ERROR_PATH_NOT_FOUND
   116  			return errno == 0x6
   117  		}
   118  	}
   119  	return false
   120  }
   121  
   122  func isSysErrCrossDevice(err error) bool {
   123  	return errors.Is(err, syscall.EXDEV)
   124  }
   125  
   126  // Check if given error corresponds to too many open files
   127  func isSysErrTooManyFiles(err error) bool {
   128  	return errors.Is(err, syscall.ENFILE) || errors.Is(err, syscall.EMFILE)
   129  }
   130  
   131  func osIsNotExist(err error) bool {
   132  	return errors.Is(err, os.ErrNotExist)
   133  }
   134  
   135  func osIsPermission(err error) bool {
   136  	return errors.Is(err, os.ErrPermission) || errors.Is(err, syscall.EROFS)
   137  }
   138  
   139  func osIsExist(err error) bool {
   140  	return errors.Is(err, os.ErrExist)
   141  }