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;
}