]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvr_disk_space_cleanup() - do not return error if called again too soon (#1)
authordave-p <gh@pickles.me.uk>
Mon, 4 Apr 2022 09:49:37 +0000 (10:49 +0100)
committerFlole998 <Flole998@users.noreply.github.com>
Tue, 5 Apr 2022 05:01:55 +0000 (07:01 +0200)
* Rework disk space check and cleanup

* Update dvr.h

* Update dvr_vfsmgr.c

src/dvr/dvr.h
src/dvr/dvr_vfsmgr.c

index 755b14cfbc2fdce7bbfc4477d68c265cf26ef4c6..e2e4fd1c48ab66994267091e059f776ebeb2cd81 100644 (file)
@@ -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);
index 59eeb9a5bc8ebd8f0c3116f3cb40b2d986a67aeb..6be735d1c9e1e9c0e7df94a9661018eb32d8c0d3 100644 (file)
@@ -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;
 }
 
 /**