in component/libfuse/libfuse2_handler.go [867:937]
func libfuse2_rename(src *C.char, dst *C.char) C.int {
srcPath := trimFusePath(src)
srcPath = common.NormalizeObjectName(srcPath)
dstPath := trimFusePath(dst)
dstPath = common.NormalizeObjectName(dstPath)
log.Trace("Libfuse::libfuse2_rename : %s -> %s", srcPath, dstPath)
// Note: When running other commands from the command line, a lot of them seemed to handle some cases like ENOENT themselves.
// Rename did not, so we manually check here.
// ENOENT. Not covered: a directory component in dst does not exist
if srcPath == "" || dstPath == "" {
log.Err("Libfuse::libfuse2_rename : src: [%s] or dst: [%s] is an empty string", srcPath, dstPath)
return -C.ENOENT
}
srcAttr, srcErr := fuseFS.NextComponent().GetAttr(internal.GetAttrOptions{Name: srcPath})
if os.IsNotExist(srcErr) {
log.Err("Libfuse::libfuse2_rename : Failed to get attributes of %s [%s]", srcPath, srcErr.Error())
return -C.ENOENT
}
dstAttr, dstErr := fuseFS.NextComponent().GetAttr(internal.GetAttrOptions{Name: dstPath})
// EISDIR
if (dstErr == nil || os.IsExist(dstErr)) && dstAttr.IsDir() && !srcAttr.IsDir() {
log.Err("Libfuse::libfuse2_rename : dst [%s] is an existing directory but src [%s] is not a directory", dstPath, srcPath)
return -C.EISDIR
}
// ENOTDIR
if (dstErr == nil || os.IsExist(dstErr)) && !dstAttr.IsDir() && srcAttr.IsDir() {
log.Err("Libfuse::libfuse2_rename : dst [%s] is an existing file but src [%s] is a directory", dstPath, srcPath)
return -C.ENOTDIR
}
if srcAttr.IsDir() {
// ENOTEMPTY
if dstErr == nil || os.IsExist(dstErr) {
empty := fuseFS.NextComponent().IsDirEmpty(internal.IsDirEmptyOptions{Name: dstPath})
if !empty {
return -C.ENOTEMPTY
}
}
err := fuseFS.NextComponent().RenameDir(internal.RenameDirOptions{Src: srcPath, Dst: dstPath})
if err != nil {
log.Err("Libfuse::libfuse2_rename : error renaming directory %s -> %s [%s]", srcPath, dstPath, err.Error())
return -C.EIO
}
libfuseStatsCollector.PushEvents(renameDir, srcPath, map[string]interface{}{source: srcPath, dest: dstPath})
libfuseStatsCollector.UpdateStats(stats_manager.Increment, renameDir, (int64)(1))
} else {
err := fuseFS.NextComponent().RenameFile(internal.RenameFileOptions{
Src: srcPath,
Dst: dstPath,
SrcAttr: srcAttr,
DstAttr: dstAttr,
})
if err != nil {
log.Err("Libfuse::libfuse2_rename : error renaming file %s -> %s [%s]", srcPath, dstPath, err.Error())
return -C.EIO
}
libfuseStatsCollector.PushEvents(renameFile, srcPath, map[string]interface{}{source: srcPath, dest: dstPath})
libfuseStatsCollector.UpdateStats(stats_manager.Increment, renameFile, (int64)(1))
}
return 0
}