#include "libfrog/radix-tree.h"
#include "libfrog/bitmask.h"
#include "libfrog/div64.h"
+#include "libfrog/util.h"
#include "atomic.h"
#include "spinlock.h"
int libxfs_file_write(struct xfs_inode *ip, void *buf, off_t pos,
size_t len);
-/* XXX: this is messy and needs fixing */
-#ifndef __LIBXFS_INTERNAL_XFS_H__
-extern void cmn_err(int, char *, ...);
-enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
-#endif
-
#include "xfs_ialloc.h"
#include "xfs_attr_leaf.h"
extern int platform_nproc(void);
+/* 64-bit seconds counter that works independently of the C library time_t. */
+typedef long long int time64_t;
+
+struct timespec64 {
+ time64_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+
#define NSEC_PER_SEC (1000000000ULL)
#define NSEC_PER_USEC (1000ULL)
#define XFS_IOC_CLONE_RANGE _IOW (0x94, 13, struct xfs_clone_args)
#define XFS_IOC_FILE_EXTENT_SAME _IOWR(0x94, 54, struct xfs_extent_data)
-/* 64-bit seconds counter that works independently of the C library time_t. */
-typedef long long int time64_t;
-
-struct timespec64 {
- time64_t tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
-};
-
#define U32_MAX ((uint32_t)~0U)
#define S32_MAX ((int32_t)(U32_MAX >> 1))
#define S32_MIN ((int32_t)(-S32_MAX - 1))
HAVE_GETTEXT = False
endif
+ifeq ($(HAVE_GETRANDOM_NONBLOCK),yes)
+LCFLAGS += -DHAVE_GETRANDOM_NONBLOCK
+endif
+
default: ltdepend $(LTLIBRARY) $(GETTEXT_PY)
crc32table.h: gen_crc32table.c crc32defs.h
#include "platform_defs.h"
#include "util.h"
+#ifdef HAVE_GETRANDOM_NONBLOCK
+#include <sys/random.h>
+#endif
+
+extern char *progname;
+
/*
* libfrog is a collection of miscellaneous userspace utilities.
* It's a library of Funny Random Oddball Gunk <cough>.
}
return rval;
}
+
+/*
+ * current_fixed_time() tries to detect if SOURCE_DATE_EPOCH is in our
+ * environment, and set input timespec's timestamp to that value.
+ *
+ * Returns true on success, fail otherwise.
+ */
+bool
+current_fixed_time(
+ struct timespec64 *tv)
+{
+ /*
+ * To avoid many getenv() we'll use an initialization static flag, so
+ * we only read once.
+ */
+ static bool enabled = false;
+ static bool read_env = false;
+ static time64_t epoch;
+ char *endp;
+ char *source_date_epoch;
+
+ if (!read_env) {
+ read_env = true;
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+ if (source_date_epoch && source_date_epoch[0] != '\0') {
+ errno = 0;
+ epoch = strtoll(source_date_epoch, &endp, 10);
+ if (errno != 0 || *endp != '\0') {
+ fprintf(stderr,
+ "%s: SOURCE_DATE_EPOCH '%s' invalid timestamp, ignoring.\n",
+ progname, source_date_epoch);
+
+ return false;
+ }
+
+ enabled = true;
+ }
+ }
+
+ /*
+ * This will happen only if we successfully read a valid
+ * SOURCE_DATE_EPOCH and properly initiated the epoch value.
+ */
+ if (read_env && enabled) {
+ tv->tv_sec = epoch;
+ tv->tv_nsec = 0;
+ return true;
+ }
+
+ /*
+ * We initialized but had no valid SOURCE_DATE_EPOCH so we fall back
+ * to regular behaviour.
+ */
+ return false;
+}
+
+void
+cmn_err(int level, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fputs("\n", stderr);
+ va_end(ap);
+}
+
+unsigned int
+hweight8(unsigned int w)
+{
+ unsigned int res = w - ((w >> 1) & 0x55);
+ res = (res & 0x33) + ((res >> 2) & 0x33);
+ return (res + (res >> 4)) & 0x0F;
+}
+
+unsigned int
+hweight32(unsigned int w)
+{
+ unsigned int res = w - ((w >> 1) & 0x55555555);
+ res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+ res = (res + (res >> 4)) & 0x0F0F0F0F;
+ res = res + (res >> 8);
+ return (res + (res >> 16)) & 0x000000FF;
+}
+
+unsigned int
+hweight64(uint64_t w)
+{
+ return hweight32((unsigned int)w) +
+ hweight32((unsigned int)(w >> 32));
+}
+
+/*
+ * get_deterministic_seed() tries to detect if DETERMINISTIC_SEED=1 is in our
+ * environment, and set our result to 0x53454544 (SEED) instead of
+ * extracting from getrandom().
+ *
+ * Returns true on success, fail otherwise.
+ */
+bool
+get_deterministic_seed(
+ uint32_t *result)
+{
+ /*
+ * To avoid many getenv() we'll use an initialization static flag, so
+ * we only read once.
+ */
+ static bool enabled = false;
+ static bool read_env = false;
+ static uint32_t deterministic_seed = 0x53454544; /* SEED */
+ char *seed_env;
+
+ if (!read_env) {
+ read_env = true;
+ seed_env = getenv("DETERMINISTIC_SEED");
+ if (seed_env && strcmp(seed_env, "1") == 0)
+ enabled = true;
+ }
+
+ /*
+ * This will happen only if we successfully read DETERMINISTIC_SEED=1.
+ */
+ if (read_env && enabled) {
+ *result = deterministic_seed;
+
+ return true;
+ }
+
+ /*
+ * We initialized but had no DETERMINISTIC_SEED=1 in env so we fall
+ * back to regular behaviour.
+ */
+ return false;
+}
+
+#ifdef HAVE_GETRANDOM_NONBLOCK
+uint32_t
+get_random_u32(void)
+{
+ uint32_t ret;
+ ssize_t sz;
+
+ /*
+ * Check for DETERMINISTIC_SEED in environment, it means we're
+ * creating a reproducible filesystem.
+ * If it fails, fall back to returning getrandom() like we used to do.
+ */
+ if (get_deterministic_seed(&ret))
+ return ret;
+ /*
+ * Try to extract a u32 of randomness from /dev/urandom. If that
+ * fails, fall back to returning zero like we used to do.
+ */
+ sz = getrandom(&ret, sizeof(ret), GRND_NONBLOCK);
+ if (sz != sizeof(ret))
+ return 0;
+
+ return ret;
+}
+#endif
#define __LIBFROG_UTIL_H__
#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
unsigned int log2_roundup(unsigned int i);
unsigned int log2_rounddown(unsigned long long i);
void *memchr_inv(const void *start, int c, size_t bytes);
+struct timespec64;
+
+bool current_fixed_time(struct timespec64 *tv);
+bool get_deterministic_seed(uint32_t *result);
+
+#ifdef HAVE_GETRANDOM_NONBLOCK
+uint32_t get_random_u32(void);
+#else
+#define get_random_u32() (0)
+#endif
+
+extern void cmn_err(int, char *, ...);
+enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
+
+typedef unsigned char u8;
+unsigned int hweight8(unsigned int w);
+unsigned int hweight32(unsigned int w);
+unsigned int hweight64(uint64_t w);
+
#endif /* __LIBFROG_UTIL_H__ */
FCFLAGS = -I.
-LTLIBS = $(LIBPTHREAD) $(LIBRT)
+LTLIBS = $(LIBPTHREAD) $(LIBRT) $(LIBFROG)
# don't try linking xfs_repair with a debug libxfs.
DEBUG = -DNDEBUG
#include "libfrog/crc32c.h"
#include <sys/xattr.h>
-#ifdef HAVE_GETRANDOM_NONBLOCK
-#include <sys/random.h>
-#endif
/* Zones used in libxfs allocations that aren't in shared header files */
extern struct kmem_cache *xfs_buf_item_cache;
#define XFS_IGET_CREATE 0x1
#define XFS_IGET_UNTRUSTED 0x2
-extern void cmn_err(int, char *, ...);
-enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
-
#define xfs_info(mp,fmt,args...) cmn_err(CE_CONT, _(fmt), ## args)
#define xfs_info_ratelimited(mp,fmt,args...) cmn_err(CE_CONT, _(fmt), ## args)
#define xfs_notice(mp,fmt,args...) cmn_err(CE_NOTE, _(fmt), ## args)
#define percpu_counter_read_positive(x) ((*x) > 0 ? (*x) : 0)
#define percpu_counter_sum_positive(x) ((*x) > 0 ? (*x) : 0)
-#ifdef HAVE_GETRANDOM_NONBLOCK
-uint32_t get_random_u32(void);
-#else
-#define get_random_u32() (0)
-#endif
-
#define PAGE_SIZE getpagesize()
extern unsigned int PAGE_SHIFT;
#define XFS_STATS_INC_OFF(mp, off)
#define XFS_STATS_ADD_OFF(mp, off, val)
-typedef unsigned char u8;
-unsigned int hweight8(unsigned int w);
-unsigned int hweight32(unsigned int w);
-unsigned int hweight64(__u64 w);
-
#define xfs_buf_cache_init(bch) (0)
#define xfs_buf_cache_destroy(bch) ((void)0)
return unit_bytes;
}
-/*
- * current_fixed_time() tries to detect if SOURCE_DATE_EPOCH is in our
- * environment, and set input timespec's timestamp to that value.
- *
- * Returns true on success, fail otherwise.
- */
-static bool
-current_fixed_time(
- struct timespec64 *tv)
-{
- /*
- * To avoid many getenv() we'll use an initialization static flag, so
- * we only read once.
- */
- static bool enabled = false;
- static bool read_env = false;
- static time64_t epoch;
- char *endp;
- char *source_date_epoch;
-
- if (!read_env) {
- read_env = true;
- source_date_epoch = getenv("SOURCE_DATE_EPOCH");
- if (source_date_epoch && source_date_epoch[0] != '\0') {
- errno = 0;
- epoch = strtoll(source_date_epoch, &endp, 10);
- if (errno != 0 || *endp != '\0') {
- fprintf(stderr,
- "%s: SOURCE_DATE_EPOCH '%s' invalid timestamp, ignoring.\n",
- progname, source_date_epoch);
-
- return false;
- }
-
- enabled = true;
- }
- }
-
- /*
- * This will happen only if we successfully read a valid
- * SOURCE_DATE_EPOCH and properly initiated the epoch value.
- */
- if (read_env && enabled) {
- tv->tv_sec = epoch;
- tv->tv_nsec = 0;
- return true;
- }
-
- /*
- * We initialized but had no valid SOURCE_DATE_EPOCH so we fall back
- * to regular behaviour.
- */
- return false;
-}
-
struct timespec64
current_time(struct inode *inode)
{
return error;
}
-void
-cmn_err(int level, char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- fputs("\n", stderr);
- va_end(ap);
-}
-
/*
* Warnings specifically for verifier errors. Differentiate CRC vs. invalid
* values, and omit the stack trace unless the error level is tuned high.
return libxfs_device_zero(xfs_find_bdev_for_inode(ip), sector, size);
}
-unsigned int
-hweight8(unsigned int w)
-{
- unsigned int res = w - ((w >> 1) & 0x55);
- res = (res & 0x33) + ((res >> 2) & 0x33);
- return (res + (res >> 4)) & 0x0F;
-}
-
-unsigned int
-hweight32(unsigned int w)
-{
- unsigned int res = w - ((w >> 1) & 0x55555555);
- res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
- res = (res + (res >> 4)) & 0x0F0F0F0F;
- res = res + (res >> 8);
- return (res + (res >> 16)) & 0x000000FF;
-}
-
-unsigned int
-hweight64(__u64 w)
-{
- return hweight32((unsigned int)w) +
- hweight32((unsigned int)(w >> 32));
-}
-
/* xfs_health.c */
/* Mark a per-fs metadata healed. */
void xfs_da_mark_sick(struct xfs_da_args *args) { }
void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask) { }
-/*
- * get_deterministic_seed() tries to detect if DETERMINISTIC_SEED=1 is in our
- * environment, and set our result to 0x53454544 (SEED) instead of
- * extracting from getrandom().
- *
- * Returns true on success, fail otherwise.
- */
-static bool
-get_deterministic_seed(
- uint32_t *result)
-{
- /*
- * To avoid many getenv() we'll use an initialization static flag, so
- * we only read once.
- */
- static bool enabled = false;
- static bool read_env = false;
- static uint32_t deterministic_seed = 0x53454544; /* SEED */
- char *seed_env;
-
- if (!read_env) {
- read_env = true;
- seed_env = getenv("DETERMINISTIC_SEED");
- if (seed_env && strcmp(seed_env, "1") == 0)
- enabled = true;
- }
-
- /*
- * This will happen only if we successfully read DETERMINISTIC_SEED=1.
- */
- if (read_env && enabled) {
- *result = deterministic_seed;
-
- return true;
- }
-
- /*
- * We initialized but had no DETERMINISTIC_SEED=1 in env so we fall
- * back to regular behaviour.
- */
- return false;
-}
-
-#ifdef HAVE_GETRANDOM_NONBLOCK
-uint32_t
-get_random_u32(void)
-{
- uint32_t ret;
- ssize_t sz;
-
- /*
- * Check for DETERMINISTIC_SEED in environment, it means we're
- * creating a reproducible filesystem.
- * If it fails, fall back to returning getrandom() like we used to do.
- */
- if (get_deterministic_seed(&ret))
- return ret;
- /*
- * Try to extract a u32 of randomness from /dev/urandom. If that
- * fails, fall back to returning zero like we used to do.
- */
- sz = getrandom(&ret, sizeof(ret), GRND_NONBLOCK);
- if (sz != sizeof(ret))
- return 0;
-
- return ret;
-}
-#endif
-
/*
* Write a buffer to a file on the data device. There must not be sparse holes
* or unwritten extents, and the blocks underneath the file range will be