github.com/StarfishStorage/goofys@v0.23.2-0.20200415030923-535558486b34/internal/utils.go (about) 1 // Copyright 2015 - 2017 Ka-Hing Cheung 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // Copyright 2019-2020 15 // modifed by StarfishStorage for persistent hash-based inode 16 17 package internal 18 19 import ( 20 "fmt" 21 "time" 22 "unicode" 23 24 "github.com/jacobsa/fuse" 25 "github.com/shirou/gopsutil/process" 26 "hash/fnv" 27 ) 28 29 var TIME_MAX = time.Unix(1<<63-62135596801, 999999999) 30 31 func MaxInt(a, b int) int { 32 if a > b { 33 return a 34 } else { 35 return b 36 } 37 } 38 39 func MinInt(a, b int) int { 40 if a < b { 41 return a 42 } else { 43 return b 44 } 45 } 46 47 func MaxInt64(a, b int64) int64 { 48 if a > b { 49 return a 50 } else { 51 return b 52 } 53 } 54 55 func MinInt64(a, b int64) int64 { 56 if a < b { 57 return a 58 } else { 59 return b 60 } 61 } 62 63 func MaxUInt32(a, b uint32) uint32 { 64 if a > b { 65 return a 66 } else { 67 return b 68 } 69 } 70 71 func MinUInt32(a, b uint32) uint32 { 72 if a < b { 73 return a 74 } else { 75 return b 76 } 77 } 78 79 func MaxUInt64(a, b uint64) uint64 { 80 if a > b { 81 return a 82 } else { 83 return b 84 } 85 } 86 87 func MinUInt64(a, b uint64) uint64 { 88 if a < b { 89 return a 90 } else { 91 return b 92 } 93 } 94 95 func PBool(v bool) *bool { 96 return &v 97 } 98 99 func PInt32(v int32) *int32 { 100 return &v 101 } 102 103 func PUInt32(v uint32) *uint32 { 104 return &v 105 } 106 107 func PInt64(v int64) *int64 { 108 return &v 109 } 110 111 func PUInt64(v uint64) *uint64 { 112 return &v 113 } 114 115 func PString(v string) *string { 116 return &v 117 } 118 119 func PTime(v time.Time) *time.Time { 120 return &v 121 } 122 123 func xattrEscape(value []byte) (s string) { 124 for _, c := range value { 125 if c == '%' { 126 s += "%25" 127 } else if unicode.IsPrint(rune(c)) { 128 s += string(c) 129 } else { 130 s += "%" + fmt.Sprintf("%02X", c) 131 } 132 } 133 134 return 135 } 136 137 func Dup(value []byte) []byte { 138 ret := make([]byte, len(value)) 139 copy(ret, value) 140 return ret 141 } 142 143 func TryUnmount(mountPoint string) (err error) { 144 for i := 0; i < 20; i++ { 145 err = fuse.Unmount(mountPoint) 146 if err != nil { 147 time.Sleep(time.Second) 148 } else { 149 break 150 } 151 } 152 return 153 } 154 155 type empty struct{} 156 157 // TODO(dotslash/khc): Remove this semaphore in favor of 158 // https://godoc.org/golang.org/x/sync/semaphore 159 type semaphore chan empty 160 161 func (sem semaphore) P(n int) { 162 for i := 0; i < n; i++ { 163 sem <- empty{} 164 } 165 } 166 167 func (sem semaphore) V(n int) { 168 for i := 0; i < n; i++ { 169 <-sem 170 } 171 } 172 173 // GetTgid returns the tgid for the given pid. 174 func GetTgid(pid uint32) (tgid *int32, err error) { 175 p, err := process.NewProcess(int32(pid)) 176 if err != nil { 177 return nil, err 178 } 179 tgidVal, err := p.Tgid() 180 if err != nil { 181 return nil, err 182 } 183 return &tgidVal, nil 184 } 185 186 // use hash of name as inode modulo 2^63 187 func makeInodeID(path string) uint64 { 188 hash := fnv.New64a() 189 hash.Write([]byte(path)) 190 return hash.Sum64() 191 }