static int rename_object()

in src/s3fs.cpp [1214:1297]


static int rename_object(const char* from, const char* to, bool update_ctime)
{
    int         result;
    std::string s3_realpath;
    headers_t   meta;
    struct stat buf;

    S3FS_PRN_INFO1("[from=%s][to=%s]", from , to);

    if(0 != (result = check_parent_object_access(to, W_OK | X_OK))){
        // not permit writing "to" object parent dir.
        return result;
    }
    if(0 != (result = check_parent_object_access(from, W_OK | X_OK))){
        // not permit removing "from" object parent dir.
        return result;
    }
    if(0 != (result = get_object_attribute(from, &buf, &meta, true, NULL, false, is_refresh_fakemeta))){
        return result;
    }
    s3_realpath = get_realpath(from);

    if(update_ctime){
        meta["x-oss-meta-ctime"]     = str(time(NULL));
    }
    meta["x-oss-copy-source"]        = urlEncode(service_path + S3fsCred::GetBucket() + s3_realpath);
    meta["Content-Type"]             = S3fsCurl::LookupMimeType(std::string(to));
    meta["x-oss-metadata-directive"] = "REPLACE";

    // [NOTE]
    // If it has a cache, open it first and leave it open until rename.
    // The cache is renamed after put_header, because it must be open
    // at the time of renaming.
    {
        // update time
        AutoFdEntity autoent;
        FdEntity*    ent;
        if(NULL == (ent = autoent.OpenExistFdEntity(from))){
            // no opened fd
            if(FdManager::IsCacheDir()){
                // create cache file if be needed
                ent = autoent.Open(from, &meta, buf.st_size, -1, O_RDONLY, false, true, false, AutoLock::NONE);
            }
            if(ent){
                struct timespec mtime = get_mtime(meta);
                struct timespec ctime = get_ctime(meta);
                struct timespec atime = get_atime(meta);
                if(mtime.tv_sec < 0){
                    mtime.tv_sec = 0L;
                    mtime.tv_nsec = 0L;
                }
                if(ctime.tv_sec < 0){
                    ctime.tv_sec = 0L;
                    ctime.tv_nsec = 0L;
                }
                if(atime.tv_sec < 0){
                    atime.tv_sec = 0L;
                    atime.tv_nsec = 0L;
                }
                ent->SetMCtime(mtime, ctime);
                ent->SetAtime(atime);
            }
        }
        if(ent) ent->CheckAndExitDirectReadIfNeeded();

        // copy
        if(0 != (result = put_headers(to, meta, true, /* use_st_size= */ false))){
            return result;
        }

        // rename
        FdManager::get()->Rename(from, to);
    }

    // Remove file
    result = s3fs_unlink(from);

    StatCache::getStatCacheData()->DelStat(to);
    if (S_ISLNK(buf.st_mode)) {
        StatCache::getStatCacheData()->DelSymlink(to);
    }

    return result;
}