Rendering: check return value of mkdir before using directory

When rendering to an image/video file, check whether the recursive
directory creation actually succeeded. If not, log an error and stop,
instead of trying to write the file.

This results in easier to understand error messages, and will help to
triage some (what we think are) race conditions with the Blender Studio
render farm.

Pull Request: https://projects.blender.org/blender/blender/pulls/145118
This commit is contained in:
Sybren A. Stüvel
2025-08-25 16:30:40 +02:00
parent aeeb771a80
commit 00abaa571a
3 changed files with 27 additions and 11 deletions

View File

@@ -2555,9 +2555,12 @@ bool BKE_imbuf_alpha_test(ImBuf *ibuf)
bool BKE_imbuf_write(ImBuf *ibuf, const char *filepath, const ImageFormatData *imf)
{
BKE_image_format_to_imbuf(ibuf, imf);
if (!BLI_file_ensure_parent_dir_exists(filepath)) {
CLOG_ERROR(&LOG, "Couldn't create directory for file %s: %s", filepath, std::strerror(errno));
return false;
}
BLI_file_ensure_parent_dir_exists(filepath);
BKE_image_format_to_imbuf(ibuf, imf);
const bool ok = IMB_save_image(ibuf, filepath, IB_byte_data);
if (ok == 0) {

View File

@@ -1516,7 +1516,10 @@ static bool ffmpeg_filepath_get(MovieWriter *context,
BLI_path_abs(filepath, BKE_main_blendfile_path_from_global());
BLI_file_ensure_parent_dir_exists(filepath);
if (!BLI_file_ensure_parent_dir_exists(filepath)) {
CLOG_ERROR(&LOG, "Couldn't create directory for file %s: %s", filepath, std::strerror(errno));
return false;
}
autosplit[0] = '\0';

View File

@@ -2400,6 +2400,22 @@ static void re_movie_free_all(Render *re)
re->movie_writers.clear_and_shrink();
}
static void touch_file(const char *filepath)
{
if (BLI_exists(filepath)) {
return;
}
if (!BLI_file_ensure_parent_dir_exists(filepath)) {
CLOG_ERROR(&LOG, "Couldn't create directory for file %s: %s", filepath, std::strerror(errno));
return;
}
if (!BLI_file_touch(filepath)) {
CLOG_ERROR(&LOG, "Couldn't touch file %s: %s", filepath, std::strerror(errno));
return;
}
}
void RE_RenderAnim(Render *re,
Main *bmain,
Scene *scene,
@@ -2581,10 +2597,7 @@ void RE_RenderAnim(Render *re,
if (rd.mode & R_TOUCH) {
if (!is_multiview_name) {
if (!BLI_exists(filepath)) {
BLI_file_ensure_parent_dir_exists(filepath);
BLI_file_touch(filepath);
}
touch_file(filepath);
}
else {
char filepath_view[FILE_MAX];
@@ -2596,10 +2609,7 @@ void RE_RenderAnim(Render *re,
BKE_scene_multiview_filepath_get(srv, filepath, filepath_view);
if (!BLI_exists(filepath_view)) {
BLI_file_ensure_parent_dir_exists(filepath_view);
BLI_file_touch(filepath_view);
}
touch_file(filepath);
}
}
}