int async_fs_mkdir_sync(const char* path, int mode) { async_pool_enter(NULL); int rc = async_fs_mkdir_nosync(path, mode); if(rc >= 0) { rc = async_fs_sync_dirname(path); } async_pool_leave(NULL); return rc; }
int SLNSubmissionEnd(SLNSubmissionRef const sub) { if(!sub) return 0; if(sub->size <= 0) return UV_EINVAL; assert(sub->tmppath); assert(sub->tmpfile >= 0); assert(sub->type); sub->URIs = SLNHasherEnd(sub->hasher); sub->internalHash = strdup(SLNHasherGetInternalHash(sub->hasher)); SLNHasherFree(&sub->hasher); if(!sub->URIs || !sub->internalHash) return UV_ENOMEM; SLNRepoRef const repo = SLNSubmissionGetRepo(sub); str_t *internalPath = NULL; bool worker = false; int rc = 0; rc = verify(sub); if(rc < 0) goto cleanup; internalPath = SLNRepoCopyInternalPath(repo, sub->internalHash); if(!internalPath) rc = UV_ENOMEM; if(rc < 0) goto cleanup; async_pool_enter(NULL); worker = true; rc = async_fs_fdatasync(sub->tmpfile); if(rc < 0) goto cleanup; // We use link(2) rather than rename(2) because link gives an error // if there's a name collision, rather than overwriting. We want to // keep the oldest file for any given hash, rather than the newest. rc = async_fs_link_mkdirp(sub->tmppath, internalPath); if(UV_EEXIST == rc) { rc = 0; goto cleanup; } if(rc < 0) { alogf("SLNSubmission couldn't move '%s' to '%s' (%s)\n", sub->tmppath, internalPath, sln_strerror(rc)); goto cleanup; } rc = async_fs_sync_dirname(internalPath); cleanup: if(worker) { async_pool_leave(NULL); worker = false; } FREE(&internalPath); async_fs_unlink(sub->tmppath); FREE(&sub->tmppath); return rc; }