Skip to content

Commit

Permalink
fix sync: copying times, owner and mode not follow link (#4151)
Browse files Browse the repository at this point in the history
close #4150

---------

Signed-off-by: xixi <[email protected]>
  • Loading branch information
Hexilee authored Nov 15, 2023
1 parent a9d2ce1 commit 562c989
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 18 deletions.
4 changes: 2 additions & 2 deletions cmd/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ func (j *juiceFS) readDirSorted(dirname string, followLink bool) ([]*mEntry, sys
}

func (j *juiceFS) Chtimes(key string, mtime time.Time) error {
f, err := j.jfs.Open(ctx, j.path(key), 0)
f, err := j.jfs.Lopen(ctx, j.path(key), 0)
if err != 0 {
return err
}
Expand All @@ -318,7 +318,7 @@ func (j *juiceFS) Chmod(key string, mode os.FileMode) error {
func (j *juiceFS) Chown(key string, owner, group string) error {
uid := utils.LookupUser(owner)
gid := utils.LookupGroup(group)
f, err := j.jfs.Open(ctx, j.path(key), 0)
f, err := j.jfs.Lopen(ctx, j.path(key), 0)
if err != 0 {
return err
}
Expand Down
13 changes: 11 additions & 2 deletions pkg/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,16 @@ func (fs *FileSystem) StatFS(ctx meta.Context) (totalspace uint64, availspace ui
return
}

func (fs *FileSystem) Open(ctx meta.Context, path string, flags uint32) (f *File, err syscall.Errno) {
// open file without following symlink
func (fs *FileSystem) Lopen(ctx meta.Context, path string, flags uint32) (f *File, err syscall.Errno) {
return fs.open(ctx, path, flags, false)
}

func (fs *FileSystem) Open(ctx meta.Context, path string, flags uint32) (*File, syscall.Errno) {
return fs.open(ctx, path, flags, true)
}

func (fs *FileSystem) open(ctx meta.Context, path string, flags uint32, followLink bool) (f *File, err syscall.Errno) {
_, task := trace.NewTask(context.TODO(), "Open")
defer task.End()
l := vfs.NewLogContext(ctx)
Expand All @@ -356,7 +365,7 @@ func (fs *FileSystem) Open(ctx meta.Context, path string, flags uint32) (f *File
defer func() { fs.log(l, "Lookup (%s): %s", path, errstr(err)) }()
}
var fi *FileStat
fi, err = fs.resolve(ctx, path, true)
fi, err = fs.resolve(ctx, path, followLink)
if err != 0 {
return
}
Expand Down
8 changes: 1 addition & 7 deletions pkg/object/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"sort"
"strconv"
"strings"
"time"

"github.com/juicedata/juicefs/pkg/utils"
)
Expand Down Expand Up @@ -322,11 +321,6 @@ func (d *filestore) List(prefix, marker, delimiter string, limit int64, followLi
return objs, nil
}

func (d *filestore) Chtimes(key string, mtime time.Time) error {
p := d.path(key)
return os.Chtimes(p, mtime, mtime)
}

func (d *filestore) Chmod(key string, mode os.FileMode) error {
p := d.path(key)
return os.Chmod(p, mode)
Expand All @@ -336,7 +330,7 @@ func (d *filestore) Chown(key string, owner, group string) error {
p := d.path(key)
uid := utils.LookupUser(owner)
gid := utils.LookupGroup(group)
return os.Chown(p, uid, gid)
return os.Lchown(p, uid, gid)
}

func newDisk(root, accesskey, secretkey, token string) (ObjectStorage, error) {
Expand Down
22 changes: 22 additions & 0 deletions pkg/object/file_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ package object
import (
"os"
"syscall"
"time"

"github.com/juicedata/juicefs/pkg/utils"
"github.com/pkg/sftp"
"golang.org/x/sys/unix"
)

func getOwnerGroup(info os.FileInfo) (string, string) {
Expand All @@ -39,3 +41,23 @@ func getOwnerGroup(info os.FileInfo) (string, string) {
}
return owner, group
}

func (d *filestore) Chtimes(key string, mtime time.Time) error {
p := d.path(key)
return lchtimes(p, mtime, mtime)
}

func lchtimes(name string, atime time.Time, mtime time.Time) error {
var utimes [2]unix.Timeval
set := func(i int, t time.Time) {
if !t.IsZero() {
utimes[i] = unix.NsecToTimeval(t.UnixNano())
}
}
set(0, atime)
set(1, mtime)
if e := unix.Lutimes(name, utimes[0:]); e != nil {
return &os.PathError{Op: "lchtimes", Path: name, Err: e}
}
return nil
}
10 changes: 9 additions & 1 deletion pkg/object/file_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

package object

import "os"
import (
"os"
"time"
)

func getOwnerGroup(info os.FileInfo) (string, string) {
return "", ""
Expand All @@ -29,3 +32,8 @@ func lookupUser(name string) int {
func lookupGroup(name string) int {
return 0
}

func (d *filestore) Chtimes(key string, mtime time.Time) error {
p := d.path(key)
return os.Chtimes(p, mtime, mtime)
}
14 changes: 8 additions & 6 deletions pkg/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,14 @@ func needCopyPerms(o1, o2 object.Object) bool {
return f2.Mode() != f1.Mode() || f2.Owner() != f1.Owner() || f2.Group() != f1.Group()
}

func copyPerms(dst object.ObjectStorage, obj object.Object) {
func copyPerms(dst object.ObjectStorage, obj object.Object, config *Config) {
start := time.Now()
key := obj.Key()
fi := obj.(object.File)
if err := dst.(object.FileSystem).Chmod(key, fi.Mode()); err != nil {
logger.Warnf("Chmod %s to %o: %s", key, fi.Mode(), err)
if !fi.IsSymlink() || !config.Links {
if err := dst.(object.FileSystem).Chmod(key, fi.Mode()); err != nil {
logger.Warnf("Chmod %s to %o: %s", key, fi.Mode(), err)
}
}
if err := dst.(object.FileSystem).Chown(key, fi.Owner(), fi.Group()); err != nil {
logger.Warnf("Chown %s to (%s,%s): %s", key, fi.Owner(), fi.Group(), err)
Expand Down Expand Up @@ -554,7 +556,7 @@ func worker(tasks <-chan object.Object, src, dst object.ObjectStorage, config *C
if config.Dry {
logger.Debugf("Will copy permissions for %s", key)
} else {
copyPerms(dst, obj)
copyPerms(dst, obj, config)
}
copied.Increment()
case markChecksum:
Expand All @@ -573,7 +575,7 @@ func worker(tasks <-chan object.Object, src, dst object.ObjectStorage, config *C
} else if config.Perms {
if o, e := dst.Head(key); e == nil {
if needCopyPerms(obj, o) {
copyPerms(dst, obj)
copyPerms(dst, obj, config)
copied.Increment()
} else {
skipped.Increment()
Expand Down Expand Up @@ -618,7 +620,7 @@ func worker(tasks <-chan object.Object, src, dst object.ObjectStorage, config *C
}
}
if config.Perms {
copyPerms(dst, obj)
copyPerms(dst, obj, config)
}
copied.Increment()
} else {
Expand Down

0 comments on commit 562c989

Please sign in to comment.