diff --git a/ChangeLog b/ChangeLog index 260c2ce..3b2f2d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-02-15 Miklos Szeredi + + * Work around FreeBSD runtime linker "feature" which binds an old + version of a symbol to internal references if the symbol has more + than one version. This resulted in infinite recursion in + fuse_lowlevel_new_compat25(). + 2006-02-10 Csaba Henk * Refine clock_gettime() querying so that linker options diff --git a/configure.in b/configure.in index f35cae2..e10226e 100644 --- a/configure.in +++ b/configure.in @@ -66,12 +66,8 @@ AC_CHECK_MEMBERS([struct stat.st_atim]) libfuse_libs=-lpthread LIBS= AC_SEARCH_LIBS(clock_gettime, [rt]) -rt_libs=$LIBS - -AC_SUBST(rt_libs) +libfuse_libs="$libfuse_libs $LIBS" LIBS= - -libfuse_libs="$libfuse_libs $rt_libs" AC_SUBST(libfuse_libs) if test -z "$MOUNT_FUSE_PATH"; then diff --git a/lib/fuse.c b/lib/fuse.c index b2a1904..d070f4d 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -2014,7 +2014,8 @@ struct fuse *fuse_new_common(int fd, struct fuse_args *args, goto out_free; } - f->se = fuse_lowlevel_new(args, &fuse_path_ops, sizeof(fuse_path_ops), f); + f->se = fuse_lowlevel_new_common(args, &fuse_path_ops, + sizeof(fuse_path_ops), f); if (f->se == NULL) goto out_free; diff --git a/lib/fuse_i.h b/lib/fuse_i.h index 79c3cbf..e54509e 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -10,6 +10,7 @@ struct fuse_session; struct fuse_chan; +struct fuse_lowlevel_ops; struct fuse_cmd { char *buf; @@ -24,3 +25,7 @@ struct fuse *fuse_new_common(int fd, struct fuse_args *args, size_t op_size, int compat); int fuse_sync_compat_args(struct fuse_args *args); + +struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args, + const struct fuse_lowlevel_ops *op, + size_t op_size, void *userdata); diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 13ddab9..efcc2a7 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -989,7 +989,7 @@ static void fuse_ll_destroy(void *data) free(f); } -struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, +struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata) { @@ -1034,6 +1034,20 @@ struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, return NULL; } + +/* + * always call fuse_lowlevel_new_common() internally, to work around a + * bug in the FreeBSD runtime linker, which links the old version of a + * symbol to internal references. + */ +struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, + const struct fuse_lowlevel_ops *op, + size_t op_size, void *userdata) +{ + return fuse_lowlevel_new_common(args, op, op_size, userdata); +} + + #include "fuse_lowlevel_compat.h" #ifndef __FreeBSD__ @@ -1100,12 +1114,6 @@ struct fuse_session *fuse_lowlevel_new_compat(const char *opts, return se; } -__asm__(".symver fuse_reply_statfs_compat,fuse_reply_statfs@FUSE_2.4"); -__asm__(".symver fuse_reply_open_compat,fuse_reply_open@FUSE_2.4"); -__asm__(".symver fuse_lowlevel_new_compat,fuse_lowlevel_new@FUSE_2.4"); - -#endif /* __FreeBSD__ */ - struct fuse_ll_compat_conf { unsigned max_read; int set_max_read; @@ -1138,6 +1146,20 @@ int fuse_sync_compat_args(struct fuse_args *args) return 0; } +__asm__(".symver fuse_reply_statfs_compat,fuse_reply_statfs@FUSE_2.4"); +__asm__(".symver fuse_reply_open_compat,fuse_reply_open@FUSE_2.4"); +__asm__(".symver fuse_lowlevel_new_compat,fuse_lowlevel_new@FUSE_2.4"); + +#else /* __FreeBSD__ */ + +int fuse_sync_compat_args(struct fuse_args *args) +{ + (void) args; + return 0; +} + +#endif /* __FreeBSD__ */ + struct fuse_session *fuse_lowlevel_new_compat25(struct fuse_args *args, const struct fuse_lowlevel_ops_compat25 *op, size_t op_size, void *userdata) @@ -1145,9 +1167,9 @@ struct fuse_session *fuse_lowlevel_new_compat25(struct fuse_args *args, if (fuse_sync_compat_args(args) == -1) return NULL; - return fuse_lowlevel_new(args, (const struct fuse_lowlevel_ops *) op, - op_size, userdata); + return fuse_lowlevel_new_common(args, + (const struct fuse_lowlevel_ops *) op, + op_size, userdata); } - __asm__(".symver fuse_lowlevel_new_compat25,fuse_lowlevel_new@FUSE_2.5");