void timeshift_filemgr_term ( void );
int timeshift_filemgr_makedirs ( int ts_index, char *buf, size_t len );
-timeshift_file_t *timeshift_filemgr_last
- ( timeshift_t *ts );
timeshift_file_t *timeshift_filemgr_get
( timeshift_t *ts, int create );
+timeshift_file_t *timeshift_filemgr_oldest
+ ( timeshift_t *ts );
+timeshift_file_t *timeshift_filemgr_newest
+ ( timeshift_t *ts );
timeshift_file_t *timeshift_filemgr_prev
( timeshift_file_t *ts, int *end, int keep );
timeshift_file_t *timeshift_filemgr_next
{
if (tsf->fd != -1)
close(tsf->fd);
+ tvhlog(LOG_DEBUG, "timeshift", "ts %d remove %s\n", ts->id, tsf->path);
TAILQ_REMOVE(&ts->files, tsf, link);
atomic_add_u64(×hift_total_size, -tsf->size);
timeshift_reaper_remove(tsf);
/* Return last file */
if (!create)
- return TAILQ_LAST(&ts->files, timeshift_file_list);
+ return timeshift_filemgr_newest(ts);
/* No space */
if (ts->full)
if (!tsf_hd->refcount) {
timeshift_filemgr_remove(ts, tsf_hd, 0);
} else {
-#ifdef TSHFT_TRACE
tvhlog(LOG_DEBUG, "timeshift", "ts %d buffer full", ts->id);
-#endif
ts->full = 1;
}
}
/* Check size */
if (!timeshift_unlimited_size &&
atomic_pre_add_u64(×hift_total_size, 0) >= timeshift_max_size) {
- tvhlog(LOG_DEBUG, "timshift", "ts %d buffer full", ts->id);
- ts->full = 1;
+
+ /* Remove the last file (if we can) */
+ if (!tsf_hd->refcount) {
+ timeshift_filemgr_remove(ts, tsf_hd, 0);
+
+ /* Full */
+ } else {
+ tvhlog(LOG_DEBUG, "timshift", "ts %d buffer full", ts->id);
+ ts->full = 1;
+ }
}
/* Create new file */
tsf_tl = tsf_tmp;
}
+ tsf_tl->refcount++;
return tsf_tl;
}
/*
* Get the oldest file
*/
-timeshift_file_t *timeshift_filemgr_last ( timeshift_t *ts )
+timeshift_file_t *timeshift_filemgr_oldest ( timeshift_t *ts )
{
- return TAILQ_FIRST(&ts->files);
+ timeshift_file_t *tsf = TAILQ_FIRST(&ts->files);
+ if (tsf)
+ tsf->refcount++;
+ return tsf;
}
+/*
+ * Get the newest file
+ */
+timeshift_file_t *timeshift_filemgr_newest ( timeshift_t *ts )
+{
+ timeshift_file_t *tsf = TAILQ_LAST(&ts->files, timeshift_file_list);
+ if (tsf)
+ tsf->refcount++;
+ return tsf;
+}
/* **************************************************************************
* Setup / Teardown
{
int end;
timeshift_index_iframe_t *tsi = NULL;
- timeshift_file_t *tsf = timeshift_filemgr_last(ts);
+ timeshift_file_t *tsf = timeshift_filemgr_oldest(ts);
while (tsf && !tsi) {
- if (!(tsi = TAILQ_FIRST(&tsf->iframes)))
+ if (!(tsi = TAILQ_FIRST(&tsf->iframes))) {
tsf = timeshift_filemgr_next(tsf, &end, 0);
+ }
}
if (tsf)
tsf->refcount--;
timeshift_index_iframe_t *tsi = NULL;
timeshift_file_t *tsf = timeshift_filemgr_get(ts, 0);
while (tsf && !tsi) {
- if (!(tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list)))
+ if (!(tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) {
tsf = timeshift_filemgr_prev(tsf, &end, 0);
+ }
}
if (tsf)
tsf->refcount--;
int64_t sec = req_time / (1000000 * TIMESHIFT_FILE_PERIOD);
int back = (req_time < cur_time) ? 1 : 0;
int end = 0;
+
+ /* Hold local ref */
+ if (cur_file)
+ cur_file->refcount++;
/* Coarse search */
if (!tsi) {
/* Find start/end of buffer */
if (end) {
if (back) {
- tsf = timeshift_filemgr_last(ts);
+ tsf = timeshift_filemgr_oldest(ts);
tsi = NULL;
while (tsf && !tsi) {
if (!(tsi = TAILQ_FIRST(&tsf->iframes)))
}
}
+ if (cur_file)
+ cur_file->refcount--;
+
/* Done */
*new_file = tsf;
*iframe = tsi;
}
/* Position */
+ if (cur_file)
+ cur_file->refcount--;
cur_file = tsf;
if (tsi)
cur_off = tsi->pos;
tsf->bad = 1;
ts->full = 1; ///< Stop any more writing
}
+ tsf->refcount--;
}
pthread_mutex_unlock(&ts->rdwr_mutex);
break;