static int s3fs_utimens_nocopy()

in src/s3fs.cpp [2120:2216]


static int s3fs_utimens_nocopy(const char* _path, const struct timespec ts[2])
{
    WTF8_ENCODE(path)
    int         result;
    std::string strpath;
    std::string newpath;
    std::string nowcache;
    struct stat stbuf;
    dirtype     nDirType = DIRTYPE_UNKNOWN;

    S3FS_PRN_INFO1("[path=%s][mtime=%lld][atime/ctime=%lld]", path, static_cast<long long>(ts[1].tv_sec), static_cast<long long>(ts[0].tv_sec));

    if(0 == strcmp(path, "/")){
        S3FS_PRN_ERR("Could not change mtime for mount point.");
        return -EIO;
    }
    if(0 != (result = check_parent_object_access(path, X_OK))){
        return result;
    }
    if(0 != (result = check_object_access(path, W_OK, &stbuf))){
        if(0 != check_object_owner(path, &stbuf)){
            return result;
        }
    }

    struct timespec now;
    if(-1 == clock_gettime(static_cast<clockid_t>(CLOCK_REALTIME), &now)){
        abort();
    }
#if __APPLE__
    struct timespec actime = handle_utimens_special_values(ts[0], now, stbuf.st_ctimespec);
    struct timespec mtime = handle_utimens_special_values(ts[1], now, stbuf.st_mtimespec);
#else
    struct timespec actime = handle_utimens_special_values(ts[0], now, stbuf.st_ctim);
    struct timespec mtime = handle_utimens_special_values(ts[1], now, stbuf.st_mtim);
#endif

    // Get attributes
    if(S_ISDIR(stbuf.st_mode)){
        result = chk_dir_object_type(path, newpath, strpath, nowcache, NULL, &nDirType);
    }else{
        strpath  = path;
        nowcache = strpath;
        result   = get_object_attribute(strpath.c_str(), NULL, NULL);
    }
    if(0 != result){
        return result;
    }

    if(S_ISDIR(stbuf.st_mode)){
        // Should rebuild all directory object
        // Need to remove old dir("dir" etc) and make new dir("dir/")

        // At first, remove directory old object
        if(0 != (result = remove_old_type_dir(strpath, nDirType))){
            return result;
        }
        StatCache::getStatCacheData()->DelStat(nowcache);

        // Make new directory object("dir/")
        if(0 != (result = create_directory_object(newpath.c_str(), stbuf.st_mode, actime.tv_sec, mtime.tv_sec, actime.tv_sec, stbuf.st_uid, stbuf.st_gid))){
            return result;
        }
    }else{
        // normal object or directory object of newer version

        // open & load
        AutoFdEntity autoent;
        FdEntity*    ent;
        if(0 != (result = get_local_fent(autoent, &ent, strpath.c_str(), O_RDWR, true))){
            S3FS_PRN_ERR("could not open and read file(%s)", strpath.c_str());
            return result;
        }

        // set mtime/ctime
        if(0 != (result = ent->SetMCtime(mtime, actime))){
            S3FS_PRN_ERR("could not set mtime and ctime to file(%s): result=%d", strpath.c_str(), result);
            return result;
        }

        // set atime
        if(0 != (result = ent->SetAtime(actime))){
            S3FS_PRN_ERR("could not set atime to file(%s): result=%d", strpath.c_str(), result);
            return result;
        }

        // upload
        if(0 != (result = ent->Flush(autoent.GetPseudoFd(), true))){
            S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
            return result;
        }
        StatCache::getStatCacheData()->DelStat(nowcache);
    }
    S3FS_MALLOCTRIM(0);

    return result;
}