From: dave-p Date: Mon, 4 Apr 2022 09:49:37 +0000 (+0100) Subject: dvr_disk_space_cleanup() - do not return error if called again too soon (#1) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a1f0b41b7e4eaf36e91f410141a473a2a9738bed;p=thirdparty%2Ftvheadend.git dvr_disk_space_cleanup() - do not return error if called again too soon (#1) * Rework disk space check and cleanup * Update dvr.h * Update dvr_vfsmgr.c --- diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 755b14cfb..e2e4fd1c4 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -666,7 +666,7 @@ void dvr_spawn_fetch_artwork(dvr_entry_t *de); void dvr_vfs_refresh_entry(dvr_entry_t *de); void dvr_vfs_remove_entry(dvr_entry_t *de); int64_t dvr_vfs_update_filename(const char *filename, htsmsg_t *fdata); -int64_t dvr_vfs_rec_start_check(dvr_config_t *cfg); +int dvr_vfs_rec_start_check(dvr_config_t *cfg); void dvr_disk_space_boot(void); void dvr_disk_space_init(void); diff --git a/src/dvr/dvr_vfsmgr.c b/src/dvr/dvr_vfsmgr.c index 59eeb9a5b..6be735d1c 100644 --- a/src/dvr/dvr_vfsmgr.c +++ b/src/dvr/dvr_vfsmgr.c @@ -179,6 +179,7 @@ dvr_vfs_update_filename(const char *filename, htsmsg_t *fdata) /** * Cleanup old recordings for this config until the dvr_cleanup_threshold is reached * Only "Keep until space needed" recordings are deleted, starting with the oldest one + * Return -1 on failure, -2 if disk stats unstable (no action taken), otherwise number of bytes cleaned */ static int64_t dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) @@ -203,6 +204,14 @@ dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) dvfs = dvr_vfs_find(NULL, &fsid); + /* When deleting a file from the disk, the system needs some time to actually do this */ + /* If calling this function too soon after the previous call, statvfs might be wrong/not updated yet */ + /* So return a "disk stats unreliable" status */ + if (dvr_disk_space_config_lastdelete + sec2mono(10) > mclk()) { + tvhtrace(LS_DVR,"disk space cleanup called <10s after last call - ignoring"); + return -2; + } + availBytes = diskdata.f_frsize * (int64_t)diskdata.f_bavail; requiredBytes = MIB(cfg->dvr_cleanup_threshold_free); diskBytes = diskdata.f_frsize * (int64_t)diskdata.f_blocks; @@ -210,14 +219,6 @@ dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) maximalBytes = MIB(cfg->dvr_cleanup_threshold_used); configName = cfg != dvr_config_find_by_name(NULL) ? cfg->dvr_config_name : "Default profile"; - /* When deleting a file from the disk, the system needs some time to actually do this */ - /* If calling this function to fast after the previous call, statvfs might be wrong/not updated yet */ - /* So we are risking to delete more files than needed, so allow 10s for the system to handle previous deletes */ - if (dvr_disk_space_config_lastdelete + sec2mono(10) > mclk()) { - tvhwarn(LS_DVR,"disk space cleanup for config \"%s\" is not allowed now", configName); - return -1; - } - if (diskBytes < requiredBytes) { tvhwarn(LS_DVR,"disk space cleanup for config \"%s\", required free space \"%"PRId64" MiB\" is smaller than the total disk size!", configName, TOMIB(requiredBytes)); @@ -445,10 +446,10 @@ dvr_get_disk_space_cb(void *aux) } /** - * Returns the available disk space for a new recording. - * If '0' (= below configured minimum), a new recording should not be started. + * Check the available disk space for a new recording. + * If '0' (= error or below configured minimum), a new recording should not be started. */ -int64_t +int dvr_vfs_rec_start_check(dvr_config_t *cfg) { struct statvfs diskdata; @@ -471,12 +472,16 @@ dvr_vfs_rec_start_check(dvr_config_t *cfg) if (availBytes < requiredBytes || ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) { /* Not enough space to start recording, check if cleanup helps */ cleanedBytes = dvr_disk_space_cleanup(cfg, 0); + if (cleanedBytes == -1) + return 0; + else if (cleanedBytes == -2) // Disk stats may be unreliable, continue anyway + return 1; availBytes += cleanedBytes; usedBytes -= cleanedBytes; if (availBytes < requiredBytes || ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) return 0; } - return availBytes; + return 1; } /**