+static off_t getused_size; /* result of getused() */
+
+/*!
+ nftw callback for getused()
+ */
+static int getused_stat(const char *path,
+ const struct stat *statp,
+ int tflag,
+ struct FTW *ftw)
+{
+ off_t low, high;
+
+ if (tflag == FTW_F || tflag == FTW_D) {
+ getused_size += statp->st_blocks * 512;
+ }
+
+ return 0;
+}
+
+#define GETUSED_CACHETIME 5
+/*!
+ * Calculate used size of a volume with nftw
+ *
+ * The result is cached, we're try to avoid frequently calling nftw()
+ *
+ * 1) Call nftw an refresh if:
+ * 1a) - we're called the first time
+ * 1b) - volume modification date is not yet set and the last time we've been called is
+ * longer then 30 sec ago
+ * 1c) - the last volume modification is less then 30 sec old
+ *
+ * @param vol (r) volume to calculate
+ */
+static int getused(const struct vol *vol)
+{
+ static time_t vol_mtime = 0;
+ int ret = 0;
+ time_t now = time(NULL);
+
+ if (!vol_mtime
+ || (!vol->v_mtime && ((vol_mtime + GETUSED_CACHETIME) < now))
+ || (vol->v_mtime && ((vol_mtime + GETUSED_CACHETIME) < vol->v_mtime))
+ ) {
+ vol_mtime = now;
+ getused_size = 0;
+ ret = nftw(vol->v_path, getused_stat, NULL, 20, FTW_PHYS); /* 2 */
+ LOG(log_debug, logtype_afpd, "volparams: from nftw: %" PRIu64 " bytes",
+ getused_size);
+ } else {
+ LOG(log_debug, logtype_afpd, "volparams: cached used: %" PRIu64 " bytes",
+ getused_size);
+ }
+
+ return ret;
+}
+