1// +build !windows 2 3package fsutil 4 5import ( 6 "os" 7 "syscall" 8 9 "github.com/containerd/continuity/sysx" 10 "github.com/pkg/errors" 11) 12 13func loadXattr(origpath string, stat *Stat) error { 14 xattrs, err := sysx.LListxattr(origpath) 15 if err != nil { 16 return errors.Wrapf(err, "failed to xattr %s", origpath) 17 } 18 if len(xattrs) > 0 { 19 m := make(map[string][]byte) 20 for _, key := range xattrs { 21 v, err := sysx.LGetxattr(origpath, key) 22 if err == nil { 23 m[key] = v 24 } 25 } 26 stat.Xattrs = m 27 } 28 return nil 29} 30 31func setUnixOpt(fi os.FileInfo, stat *Stat, path string, seenFiles map[uint64]string) { 32 s := fi.Sys().(*syscall.Stat_t) 33 34 stat.Uid = s.Uid 35 stat.Gid = s.Gid 36 37 if !fi.IsDir() { 38 if s.Mode&syscall.S_IFBLK != 0 || 39 s.Mode&syscall.S_IFCHR != 0 { 40 stat.Devmajor = int64(major(uint64(s.Rdev))) 41 stat.Devminor = int64(minor(uint64(s.Rdev))) 42 } 43 44 ino := s.Ino 45 if s.Nlink > 1 { 46 if oldpath, ok := seenFiles[ino]; ok { 47 stat.Linkname = oldpath 48 stat.Size_ = 0 49 } 50 } 51 seenFiles[ino] = path 52 } 53} 54 55func major(device uint64) uint64 { 56 return (device >> 8) & 0xfff 57} 58 59func minor(device uint64) uint64 { 60 return (device & 0xff) | ((device >> 12) & 0xfff00) 61} 62