static int s3fs_chown_nocopy()

in src/s3fs.cpp [1892:1980]


static int s3fs_chown_nocopy(const char* _path, uid_t uid, gid_t gid)
{
    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][uid=%u][gid=%u]", path, (unsigned int)uid, (unsigned int)gid);

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

    if (is_readdir_optimize) {
        return 0;
    }

    if((uid_t)(-1) == uid){
        uid = stbuf.st_uid;
    }
    if((gid_t)(-1) == gid){
        gid = stbuf.st_gid;
    }

    // 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, stbuf.st_atime, stbuf.st_mtime, time(NULL), uid, 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;
        }

        struct timespec ts = {time(NULL), 0};
        ent->SetCtime(ts);

        // Change owner
        ent->SetUId(uid);
        ent->SetGId(gid);
  
        // 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;
}