diff --git a/pkg/meta/redis.go b/pkg/meta/redis.go index 3563ceae555d..1dc82165477b 100644 --- a/pkg/meta/redis.go +++ b/pkg/meta/redis.go @@ -1745,6 +1745,16 @@ func (m *redisMeta) doRename(ctx Context, parentSrc Ino, nameSrc string, parentD if err := tx.Watch(ctx, keys...).Err(); err != nil { return err } + if dino > 0 { + if ino == dino { + return errno(nil) + } + if typ == TypeDirectory && dtyp != TypeDirectory { + return syscall.ENOTDIR + } else if typ != TypeDirectory && dtyp == TypeDirectory { + return syscall.EISDIR + } + } keys = []string{m.inodeKey(parentSrc), m.inodeKey(parentDst), m.inodeKey(ino)} if dino > 0 { diff --git a/pkg/meta/sql.go b/pkg/meta/sql.go index 2a1267d06a8f..0026f4ff1dbe 100644 --- a/pkg/meta/sql.go +++ b/pkg/meta/sql.go @@ -290,8 +290,8 @@ func retriveUrlConnsOptions(murl string) (string, int, int, int, int) { var vOpenConns int = 0 var vIdleConns int = runtime.GOMAXPROCS(-1) * 2 - var vIdleTime int = 300 - var vLifeTime int = 0 + var vIdleTime int = 300 + var vLifeTime int = 0 if optIndex != -1 { baseurl := murl[:optIndex] @@ -307,11 +307,11 @@ func retriveUrlConnsOptions(murl string) (string, int, int, int, int) { } if vals.Has("max_idle_time") { vIdleTime, _ = strconv.Atoi(vals.Get("max_idle_time")) - vals.Del("max_idle_time"); + vals.Del("max_idle_time") } if vals.Has("max_life_time") { vLifeTime, _ = strconv.Atoi(vals.Get("max_life_time")) - vals.Del("max_life_time"); + vals.Del("max_life_time") } optsurl = vals.Encode() } @@ -1245,17 +1245,17 @@ func (m *dbMeta) upsertSlice(s *xorm.Session, inode Ino, indx uint32, buf []byte driver := m.Name() if driver == "sqlite3" || driver == "postgres" { _, err = s.Exec(` - INSERT INTO jfs_chunk (inode, indx, slices) - VALUES (?, ?, ?) - ON CONFLICT (inode, indx) - DO UPDATE SET slices=jfs_chunk.slices || ?`, inode, indx, buf, buf) + INSERT INTO jfs_chunk (inode, indx, slices) + VALUES (?, ?, ?) + ON CONFLICT (inode, indx) + DO UPDATE SET slices=jfs_chunk.slices || ?`, inode, indx, buf, buf) } else { var r sql.Result r, err = s.Exec(` - INSERT INTO jfs_chunk (inode, indx, slices) - VALUES (?, ?, ?) - ON DUPLICATE KEY UPDATE - slices=concat(slices, ?)`, inode, indx, buf, buf) + INSERT INTO jfs_chunk (inode, indx, slices) + VALUES (?, ?, ?) + ON DUPLICATE KEY UPDATE + slices=concat(slices, ?)`, inode, indx, buf, buf) n, _ := r.RowsAffected() *insert = n == 1 // https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html } @@ -2052,31 +2052,36 @@ func (m *dbMeta) doRename(ctx Context, parentSrc Ino, nameSrc string, parentDst dn.Parent = parentSrc } } + } else if de.Inode == se.Inode { + return nil + } else if se.Type == TypeDirectory && de.Type != TypeDirectory { + return syscall.ENOTDIR + } else if de.Type == TypeDirectory { + if se.Type != TypeDirectory { + return syscall.EISDIR + } + exist, err := s.Exist(&edge{Parent: de.Inode}) + if err != nil { + return err + } + if exist { + return syscall.ENOTEMPTY + } + dpn.Nlink-- + dstnlink-- + dupdate = true + if trash > 0 { + dn.Parent = trash + } } else { - if de.Type == TypeDirectory { - exist, err := s.Exist(&edge{Parent: de.Inode}) - if err != nil { - return err - } - if exist { - return syscall.ENOTEMPTY - } - dpn.Nlink-- - dstnlink-- - dupdate = true - if trash > 0 { - dn.Parent = trash - } - } else { - if trash == 0 { - dn.Nlink-- - if de.Type == TypeFile && dn.Nlink == 0 { - opened = m.of.IsOpen(dn.Inode) - } - defer func() { m.of.InvalidateChunk(dino, invalidateAttrOnly) }() - } else if dn.Parent > 0 { - dn.Parent = trash + if trash == 0 { + dn.Nlink-- + if de.Type == TypeFile && dn.Nlink == 0 { + opened = m.of.IsOpen(dn.Inode) } + defer func() { m.of.InvalidateChunk(dino, invalidateAttrOnly) }() + } else if dn.Parent > 0 { + dn.Parent = trash } } if ctx.Uid() != 0 && dpn.Mode&01000 != 0 && ctx.Uid() != dpn.Uid && ctx.Uid() != dn.Uid { diff --git a/pkg/meta/tkv.go b/pkg/meta/tkv.go index 010b7cf298ef..47bb156630b5 100644 --- a/pkg/meta/tkv.go +++ b/pkg/meta/tkv.go @@ -1592,6 +1592,12 @@ func (m *kvMeta) doRename(ctx Context, parentSrc Ino, nameSrc string, parentDst tattr.Parent = parentSrc } } + } else if dino == ino { + return nil + } else if typ == TypeDirectory && dtyp != TypeDirectory { + return syscall.ENOTDIR + } else if typ != TypeDirectory && dtyp == TypeDirectory { + return syscall.EISDIR } else { if dtyp == TypeDirectory { if tx.exist(m.entryKey(dino, "")) { diff --git a/sdk/java/libjfs/main.go b/sdk/java/libjfs/main.go index 08698e6aac74..e5b31b3152b5 100644 --- a/sdk/java/libjfs/main.go +++ b/sdk/java/libjfs/main.go @@ -869,12 +869,12 @@ func jfs_rmr(pid int64, h int64, cpath *C.char) int32 { } //export jfs_rename -func jfs_rename(pid int64, h int64, oldpath *C.char, newpath *C.char) int32 { +func jfs_rename(pid int64, h int64, oldpath *C.char, newpath *C.char, flags uint32) int32 { w := F(h) if w == nil { return EINVAL } - return errno(w.Rename(w.withPid(pid), C.GoString(oldpath), C.GoString(newpath), meta.RenameNoReplace)) + return errno(w.Rename(w.withPid(pid), C.GoString(oldpath), C.GoString(newpath), flags)) } //export jfs_truncate