New function now supports two flags: will need and don't need.
return ret;
}
-bool tr_sys_file_prefetch(tr_sys_file_t handle, uint64_t offset, uint64_t size, tr_error** error)
+bool tr_sys_file_advise(tr_sys_file_t handle, uint64_t offset, uint64_t size, tr_sys_file_advice_t advice, tr_error** error)
{
TR_ASSERT(handle != TR_BAD_SYS_FILE);
TR_ASSERT(size > 0);
+ TR_ASSERT(advice == TR_SYS_FILE_ADVICE_WILL_NEED || advice == TR_SYS_FILE_ADVICE_DONT_NEED);
bool ret = true;
#if defined(HAVE_POSIX_FADVISE)
- int code = posix_fadvise(handle, offset, size, POSIX_FADV_WILLNEED);
+ int const native_advice = advice == TR_SYS_FILE_ADVICE_WILL_NEED ? POSIX_FADV_WILLNEED :
+ (advice == TR_SYS_FILE_ADVICE_DONT_NEED ? POSIX_FADV_DONTNEED : POSIX_FADV_NORMAL);
+
+ TR_ASSERT(native_advice != POSIX_FADV_NORMAL);
+
+ int const code = posix_fadvise(handle, offset, size, native_advice);
if (code != 0)
{
#elif defined(__APPLE__)
- struct radvisory radv;
- radv.ra_offset = offset;
- radv.ra_count = size;
+ if (advice != TR_SYS_FILE_ADVICE_WILL_NEED)
+ {
+ goto skip_darwin_fcntl;
+ }
+
+ struct radvisory const radv =
+ {
+ .ra_offset = offset,
+ .ra_count = size
+ };
ret = fcntl(handle, F_RDADVISE, &radv) != -1;
set_system_error(error, errno);
}
+skip_darwin_fcntl:
+
+#else
+
+ (void)handle;
+ (void)offset;
+ (void)size;
+ (void)advice;
+ (void)error;
+
#endif
return ret;
return ret;
}
-bool tr_sys_file_prefetch(tr_sys_file_t handle, uint64_t offset, uint64_t size, tr_error** error)
+bool tr_sys_file_advise(tr_sys_file_t handle, uint64_t offset, uint64_t size, tr_sys_file_advice_t advice, tr_error** error)
{
TR_ASSERT(handle != TR_BAD_SYS_FILE);
TR_ASSERT(size > 0);
+ TR_ASSERT(advice == TR_SYS_FILE_ADVICE_WILL_NEED || advice == TR_SYS_FILE_ADVICE_DONT_NEED);
(void)handle;
(void)offset;
(void)size;
+ (void)advice;
(void)error;
bool ret = true;
}
tr_sys_path_get_info_flags_t;
+typedef enum
+{
+ TR_SYS_FILE_ADVICE_WILL_NEED,
+ TR_SYS_FILE_ADVICE_DONT_NEED
+}
+tr_sys_file_advice_t;
+
typedef enum
{
TR_SYS_FILE_PREALLOC_SPARSE = (1 << 0)
bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, struct tr_error** error);
/**
- * @brief Tell system to prefetch some part of file which is to be read soon.
+ * @brief Tell system to prefetch or discard some part of file which is [not] to be read soon.
*
* @param[in] handle Valid file descriptor.
* @param[in] offset Offset in file to prefetch from.
*
* @return `True` on success, `false` otherwise (with `error` set accordingly).
*/
-bool tr_sys_file_prefetch(tr_sys_file_t handle, uint64_t offset, uint64_t size, struct tr_error** error);
+bool tr_sys_file_advise(tr_sys_file_t handle, uint64_t offset, uint64_t size, tr_sys_file_advice_t advice,
+ struct tr_error** error);
/**
* @brief Preallocate file to specified size in full or sparse mode.
}
else if (ioMode == TR_IO_PREFETCH)
{
- tr_sys_file_prefetch(fd, fileOffset, buflen, NULL);
+ tr_sys_file_advise(fd, fileOffset, buflen, TR_SYS_FILE_ADVICE_WILL_NEED, NULL);
}
else
{
*
*/
-#if defined(HAVE_POSIX_FADVISE) && (!defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600)
-#undef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600
-#endif
-
#include <string.h> /* memcmp() */
#include <stdlib.h> /* free() */
-#ifdef HAVE_POSIX_FADVISE
-#include <fcntl.h> /* posix_fadvise() */
-#endif
-
#include "transmission.h"
#include "completion.h"
#include "crypto-utils.h"
{
bytesThisPass = numRead;
tr_sha1_update(sha, buffer, bytesThisPass);
-#if defined HAVE_POSIX_FADVISE && defined POSIX_FADV_DONTNEED
- (void)posix_fadvise(fd, filePos, bytesThisPass, POSIX_FADV_DONTNEED);
-#endif
+ tr_sys_file_advise(fd, filePos, bytesThisPass, TR_SYS_FILE_ADVICE_DONT_NEED, NULL);
}
}