]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
DVR: enhance dvr_get_filesize()
authorJaroslav Kysela <perex@perex.cz>
Fri, 11 Dec 2015 15:06:05 +0000 (16:06 +0100)
committerJaroslav Kysela <perex@perex.cz>
Fri, 11 Dec 2015 15:18:20 +0000 (16:18 +0100)
src/api/api_dvr.c
src/dvr/dvr.h
src/dvr/dvr_autorec.c
src/dvr/dvr_db.c
src/dvr/dvr_rec.c
src/dvr/dvr_vfsmgr.c
src/htsp_server.c
src/webui/webui.c

index 0354d81f1df0d84ec4a605675a74994bc7deaae0..2b0ee597597993e8bfef9adbb7bd0b4584e65765 100644 (file)
@@ -66,7 +66,7 @@ api_dvr_config_create
 static int is_dvr_entry_finished(dvr_entry_t *entry)
 {
   dvr_entry_sched_state_t state = entry->de_sched_state;
-  return state == DVR_COMPLETED && !entry->de_last_error && dvr_get_filesize(entry) != -1;
+  return state == DVR_COMPLETED && !entry->de_last_error && dvr_get_filesize(entry, 0) != -1;
 }
 
 static int is_dvr_entry_upcoming(dvr_entry_t *entry)
index cf99e944f0ce3653a35d3c802146132a1da40152..8dd4d2344d4206ffa776e8837b2681923838c484 100644 (file)
@@ -28,6 +28,9 @@
 #include "lang_str.h"
 #include "tvhvfs.h"
 
+#define DVR_FILESIZE_UPDATE     (1<<0)
+#define DVR_FILESIZE_TOTAL      (1<<1)
+
 typedef struct dvr_vfs {
   LIST_ENTRY(dvr_vfs) link;
   tvh_fsid_t fsid;
@@ -557,7 +560,7 @@ dvr_entry_t *dvr_entry_find_by_event_fuzzy(epg_broadcast_t *e);
 
 const char *dvr_get_filename(dvr_entry_t *de);
 
-int64_t dvr_get_filesize(dvr_entry_t *de);
+int64_t dvr_get_filesize(dvr_entry_t *de, int flags);
 
 int64_t dvr_entry_claenup(dvr_entry_t *de, int64_t requiredBytes);
 
@@ -588,6 +591,7 @@ void dvr_spawn_postcmd(dvr_entry_t *de, const char *postcmd, const char *filenam
 
 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);
 
 void dvr_disk_space_boot(void);
 void dvr_disk_space_init(void);
index 46e96ab04fbc063ed4cf163e1c1cc80ae175346a..1829d1c0ef8dfd9efd3542f614ec65d67ee32d4e 100644 (file)
@@ -113,7 +113,7 @@ dvr_autorec_completed(dvr_entry_t *de, int error_code)
     de_prev = NULL;
     LIST_FOREACH(de, &dae->dae_spawns, de_autorec_link) {
       if (de->de_sched_state != DVR_COMPLETED) continue;
-      if (dvr_get_filesize(de) < 0) continue;
+      if (dvr_get_filesize(de, 0) < 0) continue;
       if (de_prev && de_prev->de_start > de->de_start)
         de_prev = de;
       count++;
index e8f2d33c67093250785bd2b42383c4215ecf7b9b..0f10531c0936fcccb515a8dd9f8e8796cc9a043e 100644 (file)
@@ -499,7 +499,7 @@ dvr_entry_status(dvr_entry_t *de)
       default:
         break;
     }
-    if(dvr_get_filesize(de) == -1)
+    if(dvr_get_filesize(de, 0) == -1)
       return N_("File missing");
     if(de->de_last_error)
       return streaming_code2txt(de->de_last_error);
@@ -535,7 +535,7 @@ dvr_entry_schedstatus(dvr_entry_t *de)
     break;
   case DVR_COMPLETED:
     s = "completed";
-    if(de->de_last_error || dvr_get_filesize(de) == -1)
+    if(de->de_last_error || dvr_get_filesize(de, 0) == -1)
       s = "completedError";
     rerecord = de->de_dont_rerecord ? 0 : dvr_entry_get_rerecord_errors(de);
     if(rerecord && (de->de_errors || de->de_data_errors > rerecord))
@@ -974,15 +974,15 @@ dvr_entry_rerecord(dvr_entry_t *de)
     if (de->de_sched_state == DVR_COMPLETED &&
         de->de_errors == 0 &&
         de->de_data_errors < de->de_parent->de_data_errors) {
-      fsize1 = dvr_get_filesize(de);
-      fsize2 = dvr_get_filesize(de2);
+      fsize1 = dvr_get_filesize(de, DVR_FILESIZE_TOTAL);
+      fsize2 = dvr_get_filesize(de2, DVR_FILESIZE_TOTAL);
       if (fsize1 / 5 < fsize2 / 6) {
         goto not_so_good;
       } else {
         dvr_entry_cancel_delete(de2, 1);
       }
     } else if (de->de_sched_state == DVR_COMPLETED) {
-      if(dvr_get_filesize(de) == -1) {
+      if(dvr_get_filesize(de, 0) == -1) {
 delete_me:
         dvr_entry_cancel_delete(de, 0);
         dvr_entry_rerecord(de2);
@@ -2542,7 +2542,7 @@ dvr_entry_class_filesize_get(void *o)
   dvr_entry_t *de = (dvr_entry_t *)o;
   if (de->de_sched_state == DVR_COMPLETED ||
       de->de_sched_state == DVR_RECORDING) {
-    size = dvr_get_filesize(de);
+    size = dvr_get_filesize(de, DVR_FILESIZE_UPDATE);
     if (size < 0)
       size = 0;
   } else
@@ -3079,20 +3079,31 @@ dvr_get_filename(dvr_entry_t *de)
  *
  */
 int64_t
-dvr_get_filesize(dvr_entry_t *de)
+dvr_get_filesize(dvr_entry_t *de, int flags)
 {
+  htsmsg_field_t *f;
+  htsmsg_t *m;
   const char *filename;
-  struct stat st;
+  int first = 1;
+  int64_t res = 0, size;
 
-  filename = dvr_get_filename(de);
-
-  if(filename == NULL)
+  if (de->de_files == NULL)
     return -1;
 
-  if(stat(filename, &st) != 0)
-    return -1;
+  HTSMSG_FOREACH(f, de->de_files)
+    if ((m = htsmsg_field_get_map(f)) != NULL) {
+      filename = htsmsg_get_str(m, "filename");
+      if (flags & DVR_FILESIZE_UPDATE)
+        size = dvr_vfs_update_filename(filename, m);
+      else
+        size = htsmsg_get_s64_or_default(m, "size", -1);
+      if (filename && size >= 0) {
+        res = (flags & DVR_FILESIZE_TOTAL) ? (res + size) : size;
+        first = 0;
+      }
+    }
 
-  return st.st_size;
+  return first ? -1 : res;
 }
 
 /**
index 48047bdd08200e4f08a5679ed0089e42ab0d4d0d..c9d85ef49b47359ac56033de2171d5e516db5625 100644 (file)
@@ -806,7 +806,6 @@ cut1:
   m = htsmsg_create_map();
   htsmsg_add_str(m, "filename", path);
   htsmsg_add_msg(de->de_files, NULL, m);
-  dvr_vfs_refresh_entry(de);
 
   return 0;
 }
@@ -904,6 +903,8 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss)
     return -1;
   }
 
+  dvr_vfs_refresh_entry(de);
+
   ss_copy = streaming_start_copy(ss);
 
   if(muxer_init(muxer, ss_copy, lang_str_get(de->de_title, NULL))) {
index 882ce462f60fba0cb1f04d84b1236bcde0c5936f..20d91b71a907cd19913d528d0e8a53c311dea678 100644 (file)
@@ -87,22 +87,24 @@ dvr_vfs_refresh_entry(dvr_entry_t *de)
   HTSMSG_FOREACH(f, de->de_files)
     if ((m = htsmsg_field_get_map(f)) != NULL) {
       filename = htsmsg_get_str(m, "filename");
-      vfs = dvr_vfs_find(vfs, htsmsg_get_s64(m, "fsid", 0));
+      vfs = dvr_vfs_find(vfs, htsmsg_get_s64_or_default(m, "fsid", 0));
       if (vfs) {
-        size = htsmsg_get_s64(m, "size", 0);
+        size = htsmsg_get_s64_or_default(m, "size", 0);
         vfs->used_size = size <= vfs->used_size ? vfs->used_size - size : 0;
       }
       if(statvfs(filename, &vst) < 0 || stat(filename, &st) < 0) {
         tvhlog(LOG_ERR, "dvr", "unable to stat file '%s'", filename);
-        htsmsg_delete_field(m, "fsid");
-        htsmsg_delete_field(m, "size");
-        continue;
+        goto rem;
       }
       vfs = dvr_vfs_find(vfs, tvh_fsid(vst.f_fsid));
-      if (vfs && st.st_size > 0) {
+      if (vfs && st.st_size >= 0) {
         htsmsg_set_s64(m, "fsid", tvh_fsid(vst.f_fsid));
         htsmsg_set_s64(m, "size", st.st_size);
         vfs->used_size += st.st_size;
+      } else {
+rem:
+        htsmsg_delete_field(m, "fsid");
+        htsmsg_delete_field(m, "size");
       }
     }
 }
@@ -121,9 +123,9 @@ dvr_vfs_remove_entry(dvr_entry_t *de)
   lock_assert(&global_lock);
   HTSMSG_FOREACH(f, de->de_files)
     if ((m = htsmsg_field_get_map(f)) != NULL) {
-      vfs = dvr_vfs_find(vfs, htsmsg_get_s64(m, "fsid", 0));
+      vfs = dvr_vfs_find(vfs, htsmsg_get_s64_or_default(m, "fsid", 0));
       if (vfs) {
-        size = htsmsg_get_s64(m, "size", 0);
+        size = htsmsg_get_s64_or_default(m, "size", 0);
         vfs->used_size = size <= vfs->used_size ? vfs->used_size - size : 0;
       }
       htsmsg_delete_field(m, "fsid");
@@ -131,6 +133,32 @@ dvr_vfs_remove_entry(dvr_entry_t *de)
     }
 }
 
+/*
+ *
+ */
+int64_t
+dvr_vfs_update_filename(const char *filename, htsmsg_t *fdata)
+{
+  dvr_vfs_t *vfs;
+  struct stat st;
+  int64_t size;
+
+  if (filename == NULL || fdata == NULL)
+    return -1;
+  vfs = dvr_vfs_find(NULL, htsmsg_get_s64_or_default(fdata, "fsid", 0));
+  if (vfs) {
+    size = htsmsg_get_s64_or_default(fdata, "size", 0);
+    vfs->used_size = size <= vfs->used_size ? vfs->used_size - size : 0;
+    if (stat(filename, &st) >= 0 && st.st_size >= 0) {
+      htsmsg_set_s64(fdata, "size", st.st_size);
+      return st.st_size;
+    }
+  }
+  htsmsg_delete_field(fdata, "fsid");
+  htsmsg_delete_field(fdata, "size");
+  return -1;
+}
+
 /**
  * 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
@@ -196,7 +224,7 @@ dvr_disk_space_cleanup(dvr_config_t *cfg)
       if (dvr_entry_get_removal_days(de) != DVR_RET_SPACE) // only remove the allowed ones
         continue;
 
-      if (dvr_get_filename(de) == NULL || dvr_get_filesize(de) <= 0)
+      if (dvr_get_filename(de) == NULL || dvr_get_filesize(de, DVR_FILESIZE_TOTAL) <= 0)
         continue;
 
       if(statvfs(dvr_get_filename(de), &diskdata) == -1)
@@ -212,7 +240,7 @@ dvr_disk_space_cleanup(dvr_config_t *cfg)
     }
 
     if (oldest) {
-      fileSize = dvr_get_filesize(oldest);
+      fileSize = dvr_get_filesize(oldest, DVR_FILESIZE_TOTAL);
       availBytes += fileSize;
       clearedBytes += fileSize;
       usedBytes -= fileSize;
index f808a0277181b2fddfb334b1da28b821784b552f..8d21b2d6f51f3682f30b71a0c3ac133c19b89eb8 100644 (file)
@@ -924,7 +924,7 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method
     break;
   case DVR_RECORDING:
     s = "recording";
-    fsize = dvr_get_filesize(de);
+    fsize = dvr_get_filesize(de, DVR_FILESIZE_UPDATE);
     if (de->de_rec_state == DVR_RS_ERROR ||
        (de->de_rec_state == DVR_RS_PENDING && de->de_last_error != SM_CODE_OK))
     {
@@ -934,7 +934,7 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method
     break;
   case DVR_COMPLETED:
     s = "completed";
-    fsize = dvr_get_filesize(de);
+    fsize = dvr_get_filesize(de, DVR_FILESIZE_UPDATE);
     if (fsize < 0)
       error = "File missing";
     else if(de->de_last_error)
index 86ba165c6f19607b69450570fd59b668454cd837..ebb39b1c1d1be03a59092a094593cdcc3718bee1 100644 (file)
@@ -850,7 +850,7 @@ http_dvr_list_playlist(http_connection_t *hc, int pltype)
 
   htsbuf_append_str(hq, "#EXTM3U\n");
   LIST_FOREACH(de, &dvrentries, de_global_link) {
-    fsize = dvr_get_filesize(de);
+    fsize = dvr_get_filesize(de, 0);
     if(!fsize)
       continue;
 
@@ -904,7 +904,7 @@ http_dvr_playlist(http_connection_t *hc, int pltype, dvr_entry_t *de)
 
   hostpath  = http_get_hostpath(hc);
   durration  = dvr_entry_get_stop_time(de) - dvr_entry_get_start_time(de, 0);
-  fsize = dvr_get_filesize(de);
+  fsize = dvr_get_filesize(de, 0);
 
   if(fsize) {
     bandwidth = ((8*fsize) / (durration*1024.0));