github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/client-fs_linux.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  // Copyright (c) 2015-2021 MinIO, Inc.
     5  //
     6  // This file is part of MinIO Object Storage stack
     7  //
     8  // This program is free software: you can redistribute it and/or modify
     9  // it under the terms of the GNU Affero General Public License as published by
    10  // the Free Software Foundation, either version 3 of the License, or
    11  // (at your option) any later version.
    12  //
    13  // This program is distributed in the hope that it will be useful
    14  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  // GNU Affero General Public License for more details.
    17  //
    18  // You should have received a copy of the GNU Affero General Public License
    19  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20  
    21  package cmd
    22  
    23  import (
    24  	"encoding/hex"
    25  	"strings"
    26  	"unicode/utf8"
    27  
    28  	"github.com/pkg/xattr"
    29  	"github.com/rjeczalik/notify"
    30  )
    31  
    32  var (
    33  	// EventTypePut contains the notify events that will cause a put (write)
    34  	EventTypePut = []notify.Event{notify.InCloseWrite | notify.InMovedTo}
    35  	// EventTypeDelete contains the notify events that will cause a delete (remove)
    36  	EventTypeDelete = []notify.Event{notify.InDelete | notify.InDeleteSelf | notify.InMovedFrom}
    37  	// EventTypeGet contains the notify events that will cause a get (read)
    38  	EventTypeGet = []notify.Event{notify.InAccess | notify.InOpen}
    39  )
    40  
    41  // IsGetEvent checks if the event return is a get event.
    42  func IsGetEvent(event notify.Event) bool {
    43  	for _, ev := range EventTypeGet {
    44  		if event&ev != 0 {
    45  			return true
    46  		}
    47  	}
    48  	return false
    49  }
    50  
    51  // IsPutEvent checks if the event returned is a put event
    52  func IsPutEvent(event notify.Event) bool {
    53  	for _, ev := range EventTypePut {
    54  		if event&ev != 0 {
    55  			return true
    56  		}
    57  	}
    58  	return false
    59  }
    60  
    61  // IsDeleteEvent checks if the event returned is a delete event
    62  func IsDeleteEvent(event notify.Event) bool {
    63  	for _, ev := range EventTypeDelete {
    64  		if event&ev != 0 {
    65  			return true
    66  		}
    67  	}
    68  	return false
    69  }
    70  
    71  // getXAttr fetches the extended attribute for a particular key on file
    72  func getXAttr(path, key string) (string, error) {
    73  	data, e := xattr.Get(path, key)
    74  	if e != nil {
    75  		return "", e
    76  	}
    77  	if utf8.ValidString(string(data)) {
    78  		return string(data), nil
    79  	}
    80  	return hex.EncodeToString(data), nil
    81  }
    82  
    83  // getAllXattrs returns the extended attributes for a file if supported by the OS
    84  func getAllXattrs(path string) (map[string]string, error) {
    85  	xMetadata := make(map[string]string)
    86  	list, e := xattr.List(path)
    87  	if e != nil {
    88  		if isNotSupported(e) {
    89  			return nil, nil
    90  		}
    91  		return nil, e
    92  	}
    93  	for _, key := range list {
    94  		// filter out system specific xattr
    95  		if strings.HasPrefix(key, "system.") {
    96  			continue
    97  		}
    98  		xMetadata[key], e = getXAttr(path, key)
    99  		if e != nil {
   100  			if isNotSupported(e) {
   101  				return nil, nil
   102  			}
   103  			return nil, e
   104  		}
   105  	}
   106  	return xMetadata, nil
   107  }