@@ -154,6 +154,9 @@ AC_PACKAGE_NEED_UUIDCOMPARE
AC_PACKAGE_NEED_PTHREAD_H
AC_PACKAGE_NEED_PTHREADMUTEXINIT
+AC_PACKAGE_NEED_URCU_H
+AC_PACKAGE_NEED_RCU_INIT
+
AC_HAVE_FADVISE
AC_HAVE_MADVISE
AC_HAVE_MINCORE
@@ -9,7 +9,8 @@ LTCOMMAND = xfs_copy
CFILES = xfs_copy.c
HFILES = xfs_copy.h
-LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBPTHREAD) $(LIBRT)
+LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBPTHREAD) $(LIBRT) \
+ $(LIBURCU)
LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) $(LIBFROG)
LLDFLAGS = -static-libtool-libs
@@ -110,6 +110,7 @@ do_message(int flags, int code, const char *fmt, ...)
fprintf(stderr,
_("Aborting XFS copy -- logfile error -- reason: %s\n"),
strerror(errno));
+ rcu_unregister_thread();
pthread_exit(NULL);
}
}
@@ -224,6 +225,7 @@ begin_reader(void *arg)
{
thread_args *args = arg;
+ rcu_register_thread();
for (;;) {
pthread_mutex_lock(&args->wait);
if (do_write(args, NULL))
@@ -243,6 +245,7 @@ handle_error:
if (--glob_masks.num_working == 0)
pthread_mutex_unlock(&mainwait);
pthread_mutex_unlock(&glob_masks.mutex);
+ rcu_unregister_thread();
pthread_exit(NULL);
return NULL;
}
@@ -17,7 +17,8 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \
CFILES = $(HFILES:.h=.c) btdump.c btheight.c convert.c info.c
LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh
-LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
+LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) \
+ $(LIBURCU)
LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) $(LIBFROG)
LLDFLAGS += -static-libtool-libs
@@ -3,7 +3,7 @@ Section: admin
Priority: optional
Maintainer: XFS Development Team <linux-xfs@vger.kernel.org>
Uploaders: Nathan Scott <nathans@debian.org>, Anibal Monsalve Salazar <anibal@debian.org>
-Build-Depends: uuid-dev, dh-autoreconf, debhelper (>= 5), gettext, libtool, libedit-dev, libblkid-dev (>= 2.17), linux-libc-dev, libdevmapper-dev, libattr1-dev, libicu-dev, dh-python, pkg-config
+Build-Depends: uuid-dev, dh-autoreconf, debhelper (>= 5), gettext, libtool, libedit-dev, libblkid-dev (>= 2.17), linux-libc-dev, libdevmapper-dev, libattr1-dev, libicu-dev, dh-python, pkg-config, liburcu-dev
Standards-Version: 4.0.0
Homepage: https://xfs.wiki.kernel.org/
@@ -9,7 +9,8 @@ LTCOMMAND = xfs_growfs
CFILES = xfs_growfs.c
-LLDLIBS = $(LIBXFS) $(LIBXCMD) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
+LLDLIBS = $(LIBXFS) $(LIBXCMD) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) \
+ $(LIBURCU)
ifeq ($(ENABLE_EDITLINE),yes)
LLDLIBS += $(LIBEDITLINE) $(LIBTERMCAP)
@@ -22,6 +22,7 @@ LDFLAGS =
LIBRT = @librt@
LIBUUID = @libuuid@
+LIBURCU = @liburcu@
LIBPTHREAD = @libpthread@
LIBTERMCAP = @libtermcap@
LIBEDITLINE = @libeditline@
@@ -125,7 +126,8 @@ CROND_DIR = @crond_dir@
GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall
# -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl
-PCFLAGS = -D_GNU_SOURCE $(GCCFLAGS)
+# _LGPL_SOURCE is for liburcu to work correctly with GPL/LGPL programs
+PCFLAGS = -D_LGPL_SOURCE -D_GNU_SOURCE $(GCCFLAGS)
ifeq ($(HAVE_UMODE_T),yes)
PCFLAGS += -DHAVE_UMODE_T
endif
@@ -23,6 +23,7 @@
#include <limits.h>
#include <stdbool.h>
#include <libgen.h>
+#include <urcu.h>
typedef struct filldir filldir_t;
@@ -11,6 +11,7 @@
#include <stdbool.h>
#include <errno.h>
#include <assert.h>
+#include <urcu.h>
#include "workqueue.h"
/* Main processing thread */
@@ -24,6 +25,7 @@ workqueue_thread(void *arg)
* Loop pulling work from the passed in work queue.
* Check for notification to exit after every chunk of work.
*/
+ rcu_register_thread();
while (1) {
pthread_mutex_lock(&wq->lock);
@@ -52,6 +54,7 @@ workqueue_thread(void *arg)
(wi->function)(wi->queue, wi->index, wi->arg);
free(wi);
}
+ rcu_unregister_thread();
return NULL;
}
@@ -310,6 +310,8 @@ libxfs_init(libxfs_init_t *a)
fd = -1;
flags = (a->isreadonly | a->isdirect);
+ rcu_init();
+ rcu_register_thread();
radix_tree_init();
if (a->volname) {
@@ -957,6 +959,7 @@ libxfs_destroy(
libxfs_bcache_free();
cache_destroy(libxfs_bcache);
leaked = destroy_zones();
+ rcu_unregister_thread();
if (getenv("LIBXFS_LEAK_CHECK") && leaked)
exit(1);
}
@@ -194,8 +194,7 @@ enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
#define spin_unlock(a) ((void) 0)
#define likely(x) (x)
#define unlikely(x) (x)
-#define rcu_read_lock() ((void) 0)
-#define rcu_read_unlock() ((void) 0)
+
/* Need to be able to handle this bare or in control flow */
static inline bool WARN_ON(bool expr) {
return (expr);
@@ -12,7 +12,8 @@ CFILES = logprint.c \
log_copy.c log_dump.c log_misc.c \
log_print_all.c log_print_trans.c log_redo.c
-LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
+LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) \
+ $(LIBURCU)
LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) $(LIBFROG)
LLDFLAGS = -static-libtool-libs
@@ -24,6 +24,7 @@ LSRCFILES = \
package_services.m4 \
package_types.m4 \
package_icu.m4 \
+ package_urcu.m4 \
package_utilies.m4 \
package_uuiddev.m4 \
multilib.m4 \
new file mode 100644
@@ -0,0 +1,22 @@
+AC_DEFUN([AC_PACKAGE_NEED_URCU_H],
+ [ AC_CHECK_HEADERS(urcu.h)
+ if test $ac_cv_header_urcu_h = no; then
+ AC_CHECK_HEADERS(urcu.h,, [
+ echo
+ echo 'FATAL ERROR: could not find a valid urcu header.'
+ exit 1])
+ fi
+ ])
+
+AC_DEFUN([AC_PACKAGE_NEED_RCU_INIT],
+ [ AC_MSG_CHECKING([for liburcu])
+ AC_TRY_COMPILE([
+#define _GNU_SOURCE
+#include <urcu.h>
+ ], [
+ rcu_init();
+ ], liburcu=-lurcu
+ AC_MSG_RESULT(yes),
+ AC_MSG_RESULT(no))
+ AC_SUBST(liburcu)
+ ])
@@ -8,7 +8,8 @@ include $(TOPDIR)/include/builddefs
LTCOMMAND = xfs_mdrestore
CFILES = xfs_mdrestore.c
-LLDLIBS = $(LIBXFS) $(LIBFROG) $(LIBRT) $(LIBPTHREAD) $(LIBUUID)
+LLDLIBS = $(LIBXFS) $(LIBFROG) $(LIBRT) $(LIBPTHREAD) $(LIBUUID) \
+ $(LIBURCU)
LTDEPENDENCIES = $(LIBXFS) $(LIBFROG)
LLDFLAGS = -static
@@ -11,7 +11,7 @@ HFILES =
CFILES = proto.c xfs_mkfs.c
LLDLIBS += $(LIBXFS) $(LIBXCMD) $(LIBFROG) $(LIBRT) $(LIBPTHREAD) $(LIBBLKID) \
- $(LIBUUID) $(LIBINIH)
+ $(LIBUUID) $(LIBINIH) $(LIBURCU)
LTDEPENDENCIES += $(LIBXFS) $(LIBXCMD) $(LIBFROG)
LLDFLAGS = -static-libtool-libs
@@ -72,7 +72,7 @@ CFILES = \
xfs_repair.c
LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBXCMD) $(LIBFROG) $(LIBUUID) $(LIBRT) \
- $(LIBPTHREAD) $(LIBBLKID)
+ $(LIBPTHREAD) $(LIBBLKID) $(LIBURCU)
LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) $(LIBXCMD) $(LIBFROG)
LLDFLAGS = -static-libtool-libs
@@ -660,6 +660,7 @@ pf_io_worker(
if (buf == NULL)
return NULL;
+ rcu_register_thread();
pthread_mutex_lock(&args->lock);
while (!args->queuing_done || !btree_is_empty(args->io_queue)) {
pftrace("waiting to start prefetch I/O for AG %d", args->agno);
@@ -682,6 +683,7 @@ pf_io_worker(
free(buf);
pftrace("finished prefetch I/O for AG %d", args->agno);
+ rcu_unregister_thread();
return NULL;
}
@@ -726,6 +728,8 @@ pf_queuing_worker(
struct xfs_ino_geometry *igeo = M_IGEO(mp);
unsigned long long cluster_mask;
+ rcu_register_thread();
+
cluster_mask = (1ULL << igeo->inodes_per_cluster) - 1;
for (i = 0; i < PF_THREAD_COUNT; i++) {
@@ -739,7 +743,7 @@ pf_queuing_worker(
args->io_threads[i] = 0;
if (i == 0) {
pf_skip_prefetch_thread(args);
- return NULL;
+ goto out;
}
/*
* since we have at least one I/O thread, use them for
@@ -779,7 +783,6 @@ pf_queuing_worker(
* Start processing as well, in case everything so
* far was already prefetched and the queue is empty.
*/
-
pf_start_io_workers(args);
pf_start_processing(args);
sem_wait(&args->ra_count);
@@ -841,6 +844,8 @@ pf_queuing_worker(
if (next_args)
pf_create_prefetch_thread(next_args);
+out:
+ rcu_unregister_thread();
return NULL;
}
@@ -182,6 +182,7 @@ progress_rpt_thread (void *p)
do_error (_("progress_rpt: cannot malloc progress msg buffer\n"));
running = 1;
+ rcu_register_thread();
/*
* Specify a repeating timer that fires each MSG_INTERVAL seconds.
@@ -286,7 +287,8 @@ progress_rpt_thread (void *p)
do_warn(_("cannot delete timer\n"));
free (msgbuf);
- return (NULL);
+ rcu_unregister_thread();
+ return NULL;
}
int
@@ -71,7 +71,8 @@ spacemap.c \
vfs.c \
xfs_scrub.c
-LLDLIBS += $(LIBHANDLE) $(LIBFROG) $(LIBPTHREAD) $(LIBICU_LIBS) $(LIBRT)
+LLDLIBS += $(LIBHANDLE) $(LIBFROG) $(LIBPTHREAD) $(LIBICU_LIBS) $(LIBRT) \
+ $(LIBURCU)
LTDEPENDENCIES += $(LIBHANDLE) $(LIBFROG)
LLDFLAGS = -static
@@ -117,6 +117,7 @@ progress_report_thread(void *arg)
struct timespec abstime;
int ret;
+ rcu_register_thread();
pthread_mutex_lock(&pt.lock);
while (1) {
uint64_t progress_val;
@@ -140,6 +141,7 @@ progress_report_thread(void *arg)
progress_report(progress_val);
}
pthread_mutex_unlock(&pt.lock);
+ rcu_unregister_thread();
return NULL;
}