aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/buffer.c3
-rw-r--r--lib/cuse_lowlevel.c1
-rw-r--r--[-rwxr-xr-x]lib/fuse.c21
-rw-r--r--lib/fuse_loop_mt.c9
-rw-r--r--lib/fuse_lowlevel.c126
-rw-r--r--lib/fuse_misc.h25
-rw-r--r--lib/fuse_versionscript1
-rw-r--r--lib/meson.build2
-rw-r--r--lib/modules/iconv.c22
-rw-r--r--lib/mount_util.c2
10 files changed, 138 insertions, 74 deletions
diff --git a/lib/buffer.c b/lib/buffer.c
index 5ab9b87..757807a 100644
--- a/lib/buffer.c
+++ b/lib/buffer.c
@@ -266,6 +266,9 @@ static int fuse_bufvec_advance(struct fuse_bufvec *bufv, size_t len)
{
const struct fuse_buf *buf = fuse_bufvec_current(bufv);
+ if (!buf)
+ return 0;
+
bufv->off += len;
assert(bufv->off <= buf->size);
if (bufv->off == buf->size) {
diff --git a/lib/cuse_lowlevel.c b/lib/cuse_lowlevel.c
index 9917b64..b70947e 100644
--- a/lib/cuse_lowlevel.c
+++ b/lib/cuse_lowlevel.c
@@ -319,6 +319,7 @@ struct fuse_session *cuse_lowlevel_setup(int argc, char *argv[],
if (res == -1)
goto err_sig;
+ fuse_opt_free_args(&args);
return se;
err_sig:
diff --git a/lib/fuse.c b/lib/fuse.c
index b0f5b30..a95d7c1 100755..100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -3390,7 +3390,7 @@ static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
dh->len = 0;
dh->filled = 0;
dh->nodeid = ino;
- fuse_mutex_init(&dh->lock);
+ pthread_mutex_init(&dh->lock, NULL);
llfi->fh = (uintptr_t) dh;
@@ -3566,7 +3566,7 @@ static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp,
return 1;
}
- if (off && statp && (flags & FUSE_FILL_DIR_PLUS)) {
+ if (statp && (flags & FUSE_FILL_DIR_PLUS)) {
e.attr = *statp;
if (!is_dot_or_dotdot(name)) {
@@ -3578,6 +3578,11 @@ static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp,
}
} else {
e.attr.st_ino = FUSE_UNKNOWN_INO;
+ if (statp) {
+ e.attr.st_mode = statp->st_mode;
+ if (f->conf.use_ino)
+ e.attr.st_ino = statp->st_ino;
+ }
if (!f->conf.use_ino && f->conf.readdir_ino) {
e.attr.st_ino = (ino_t)
lookup_nodeid(f, dh->nodeid, name);
@@ -4533,7 +4538,7 @@ static int fuse_session_loop_remember(struct fuse *f)
res = poll(&fds, 1, timeout * 1000);
if (res == -1) {
- if (errno == -EINTR)
+ if (errno == EINTR)
continue;
else
break;
@@ -4569,7 +4574,7 @@ int fuse_loop(struct fuse *f)
return fuse_session_loop(f->se);
}
-FUSE_SYMVER(".symver fuse_loop_mt_32,fuse_loop_mt@@FUSE_3.2");
+FUSE_SYMVER("fuse_loop_mt_32", "fuse_loop_mt@@FUSE_3.2")
int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config)
{
if (f == NULL)
@@ -4585,7 +4590,7 @@ int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config)
}
int fuse_loop_mt_31(struct fuse *f, int clone_fd);
-FUSE_SYMVER(".symver fuse_loop_mt_31,fuse_loop_mt@FUSE_3.0");
+FUSE_SYMVER("fuse_loop_mt_31", "fuse_loop_mt@FUSE_3.0")
int fuse_loop_mt_31(struct fuse *f, int clone_fd)
{
struct fuse_loop_config config;
@@ -4870,7 +4875,7 @@ void fuse_stop_cleanup_thread(struct fuse *f)
}
-FUSE_SYMVER(".symver fuse_new_31,fuse_new@@FUSE_3.1");
+FUSE_SYMVER("fuse_new_31", "fuse_new@@FUSE_3.1")
struct fuse *fuse_new_31(struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size, void *user_data)
@@ -4973,7 +4978,7 @@ struct fuse *fuse_new_31(struct fuse_args *args,
if (node_table_init(&f->id_table) == -1)
goto out_free_name_table;
- fuse_mutex_init(&f->lock);
+ pthread_mutex_init(&f->lock, NULL);
root = alloc_node(f);
if (root == NULL) {
@@ -5024,7 +5029,7 @@ out:
/* Emulates 3.0-style fuse_new(), which processes --help */
struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
size_t op_size, void *private_data);
-FUSE_SYMVER(".symver fuse_new_30,fuse_new@FUSE_3.0");
+FUSE_SYMVER("fuse_new_30", "fuse_new@FUSE_3.0")
struct fuse *fuse_new_30(struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size, void *user_data)
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c
index 445e9a0..8fcc46c 100644
--- a/lib/fuse_loop_mt.c
+++ b/lib/fuse_loop_mt.c
@@ -32,7 +32,6 @@ struct fuse_worker {
struct fuse_worker *prev;
struct fuse_worker *next;
pthread_t thread_id;
- size_t bufsize;
// We need to include fuse_buf so that we can properly free
// it when a thread is terminated by pthread_cancel().
@@ -65,7 +64,7 @@ static struct fuse_chan *fuse_chan_new(int fd)
memset(ch, 0, sizeof(*ch));
ch->fd = fd;
ch->ctr = 1;
- fuse_mutex_init(&ch->lock);
+ pthread_mutex_init(&ch->lock, NULL);
return ch;
}
@@ -304,7 +303,7 @@ static void fuse_join_worker(struct fuse_mt *mt, struct fuse_worker *w)
free(w);
}
-FUSE_SYMVER(".symver fuse_session_loop_mt_32,fuse_session_loop_mt@@FUSE_3.2");
+FUSE_SYMVER("fuse_session_loop_mt_32", "fuse_session_loop_mt@@FUSE_3.2")
int fuse_session_loop_mt_32(struct fuse_session *se, struct fuse_loop_config *config)
{
int err;
@@ -321,7 +320,7 @@ int fuse_session_loop_mt_32(struct fuse_session *se, struct fuse_loop_config *co
mt.main.thread_id = pthread_self();
mt.main.prev = mt.main.next = &mt.main;
sem_init(&mt.finish, 0, 0);
- fuse_mutex_init(&mt.lock);
+ pthread_mutex_init(&mt.lock, NULL);
pthread_mutex_lock(&mt.lock);
err = fuse_loop_start_thread(&mt);
@@ -352,7 +351,7 @@ int fuse_session_loop_mt_32(struct fuse_session *se, struct fuse_loop_config *co
}
int fuse_session_loop_mt_31(struct fuse_session *se, int clone_fd);
-FUSE_SYMVER(".symver fuse_session_loop_mt_31,fuse_session_loop_mt@FUSE_3.0");
+FUSE_SYMVER("fuse_session_loop_mt_31", "fuse_session_loop_mt@FUSE_3.0")
int fuse_session_loop_mt_31(struct fuse_session *se, int clone_fd)
{
struct fuse_loop_config config;
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index a4a4df0..aee22b4 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -156,7 +156,7 @@ static struct fuse_req *fuse_ll_alloc_req(struct fuse_session *se)
req->se = se;
req->ctr = 1;
list_init_req(req);
- fuse_mutex_init(&req->lock);
+ pthread_mutex_init(&req->lock, NULL);
}
return req;
@@ -168,6 +168,7 @@ static int fuse_send_msg(struct fuse_session *se, struct fuse_chan *ch,
{
struct fuse_out_header *out = iov[0].iov_base;
+ assert(se != NULL);
out->len = iov_length(iov, count);
if (se->debug) {
if (out->unique == 0) {
@@ -190,8 +191,6 @@ static int fuse_send_msg(struct fuse_session *se, struct fuse_chan *ch,
int err = errno;
if (res == -1) {
- assert(se != NULL);
-
/* ENOENT means the operation was interrupted */
if (!fuse_session_exited(se) && err != ENOENT)
perror("fuse: writing device");
@@ -400,20 +399,45 @@ static void fill_open(struct fuse_open_out *arg,
arg->open_flags |= FOPEN_NONSEEKABLE;
}
-int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
-{
- struct fuse_entry_out arg;
- size_t size = req->se->conn.proto_minor < 9 ?
- FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(arg);
+int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param* e) {
+ struct {
+ struct fuse_entry_out arg;
+ struct fuse_entry_bpf_out bpf_arg;
+ } __attribute__((packed)) arg_ext = {0};
- /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
- negative entry */
- if (!e->ino && req->se->conn.proto_minor < 4)
- return fuse_reply_err(req, ENOENT);
+ struct fuse_entry_out arg;
+ struct fuse_entry_bpf_out bpf_arg;
+ size_t size;
+ int extended_args = e->bpf_action || bpf_arg.bpf_fd || e->backing_action || e->backing_fd;
- memset(&arg, 0, sizeof(arg));
- fill_entry(&arg, e);
- return send_reply_ok(req, &arg, size);
+ if (extended_args) {
+ size = req->se->conn.proto_minor < 9 ? FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(arg_ext);
+ } else {
+ size = req->se->conn.proto_minor < 9 ? FUSE_COMPAT_ENTRY_OUT_SIZE : sizeof(arg);
+ }
+
+ /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
+ negative entry */
+ if (!e->ino && req->se->conn.proto_minor < 4) return fuse_reply_err(req, ENOENT);
+
+ memset(&arg, 0, sizeof(arg));
+
+ if (extended_args) {
+ memset(&bpf_arg, 0, sizeof(bpf_arg));
+
+ bpf_arg.bpf_action = e->bpf_action;
+ bpf_arg.bpf_fd = e->bpf_fd;
+ bpf_arg.backing_action = e->backing_action;
+ bpf_arg.backing_fd = e->backing_fd;
+
+ arg_ext.arg = arg;
+ arg_ext.bpf_arg = bpf_arg;
+
+ return send_reply_ok(req, &arg_ext, size);
+ } else {
+ fill_entry(&arg, e);
+ return send_reply_ok(req, &arg, size);
+ }
}
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
@@ -730,7 +754,7 @@ static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
struct fuse_ll_pipe *llp;
int splice_flags;
size_t pipesize;
- size_t total_fd_size;
+ size_t total_buf_size;
size_t idx;
size_t headerlen;
struct fuse_bufvec pipe_buf = FUSE_BUFVEC_INIT(len);
@@ -741,15 +765,13 @@ static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
if (flags & FUSE_BUF_NO_SPLICE)
goto fallback;
- total_fd_size = 0;
+ total_buf_size = 0;
for (idx = buf->idx; idx < buf->count; idx++) {
- if (buf->buf[idx].flags & FUSE_BUF_IS_FD) {
- total_fd_size = buf->buf[idx].size;
- if (idx == buf->idx)
- total_fd_size -= buf->off;
- }
+ total_buf_size += buf->buf[idx].size;
+ if (idx == buf->idx)
+ total_buf_size -= buf->off;
}
- if (total_fd_size < 2 * pagesize)
+ if (total_buf_size < 2 * pagesize)
goto fallback;
if (se->conn.proto_minor < 14 ||
@@ -1981,7 +2003,10 @@ static void do_lseek(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
fuse_reply_err(req, ENOSYS);
}
-static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
+/* Prevent bogus data races (bogus since "init" is called before
+ * multi-threading becomes relevant */
+static __attribute__((no_sanitize("thread")))
+void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
struct fuse_init_out outarg;
@@ -2053,8 +2078,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
se->conn.capable |= FUSE_CAP_POSIX_ACL;
if (arg->flags & FUSE_HANDLE_KILLPRIV)
se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
+ if (arg->flags & FUSE_CACHE_SYMLINKS)
+ se->conn.capable |= FUSE_CAP_CACHE_SYMLINKS;
if (arg->flags & FUSE_NO_OPENDIR_SUPPORT)
se->conn.capable |= FUSE_CAP_NO_OPENDIR_SUPPORT;
+ if (arg->flags & FUSE_EXPLICIT_INVAL_DATA)
+ se->conn.capable |= FUSE_CAP_EXPLICIT_INVAL_DATA;
if (!(arg->flags & FUSE_MAX_PAGES)) {
size_t max_bufsize =
FUSE_DEFAULT_MAX_PAGES_PER_REQ * getpagesize()
@@ -2179,6 +2208,10 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
outarg.flags |= FUSE_POSIX_ACL;
if (se->conn.want & FUSE_CAP_PASSTHROUGH)
outarg.flags |= FUSE_PASSTHROUGH;
+ if (se->conn.want & FUSE_CAP_CACHE_SYMLINKS)
+ outarg.flags |= FUSE_CACHE_SYMLINKS;
+ if (se->conn.want & FUSE_CAP_EXPLICIT_INVAL_DATA)
+ outarg.flags |= FUSE_EXPLICIT_INVAL_DATA;
outarg.max_readahead = se->conn.max_readahead;
outarg.max_write = se->conn.max_write;
if (se->conn.proto_minor >= 13) {
@@ -2319,7 +2352,7 @@ int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino,
if (!se)
return -EINVAL;
- if (se->conn.proto_major < 6 || se->conn.proto_minor < 12)
+ if (se->conn.proto_minor < 12)
return -ENOSYS;
outarg.ino = ino;
@@ -2341,7 +2374,7 @@ int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent,
if (!se)
return -EINVAL;
- if (se->conn.proto_major < 6 || se->conn.proto_minor < 12)
+ if (se->conn.proto_minor < 12)
return -ENOSYS;
outarg.parent = parent;
@@ -2366,7 +2399,7 @@ int fuse_lowlevel_notify_delete(struct fuse_session *se,
if (!se)
return -EINVAL;
- if (se->conn.proto_major < 6 || se->conn.proto_minor < 18)
+ if (se->conn.proto_minor < 18)
return -ENOSYS;
outarg.parent = parent;
@@ -2395,7 +2428,7 @@ int fuse_lowlevel_notify_store(struct fuse_session *se, fuse_ino_t ino,
if (!se)
return -EINVAL;
- if (se->conn.proto_major < 6 || se->conn.proto_minor < 15)
+ if (se->conn.proto_minor < 15)
return -ENOSYS;
out.unique = 0;
@@ -2473,7 +2506,7 @@ int fuse_lowlevel_notify_retrieve(struct fuse_session *se, fuse_ino_t ino,
if (!se)
return -EINVAL;
- if (se->conn.proto_major < 6 || se->conn.proto_minor < 15)
+ if (se->conn.proto_minor < 15)
return -ENOSYS;
rreq = malloc(sizeof(*rreq));
@@ -2604,6 +2637,22 @@ static const char *opname(enum fuse_opcode opcode)
return fuse_ll_ops[opcode].name;
}
+static const char *opfiltername(int filter)
+{
+ switch (filter) {
+ case 0:
+ return "NONE";
+ case FUSE_PREFILTER:
+ return "FUSE_PREFILTER";
+ case FUSE_POSTFILTER:
+ return "FUSE_POSTFILTER";
+ case FUSE_PREFILTER | FUSE_POSTFILTER:
+ return "FUSE_PREFILTER | FUSE_POSTFILTER";
+ default:
+ return "???";
+ }
+}
+
static int fuse_ll_copy_from_pipe(struct fuse_bufvec *dst,
struct fuse_bufvec *src)
{
@@ -2638,6 +2687,7 @@ void fuse_session_process_buf_int(struct fuse_session *se,
void *mbuf = NULL;
int err;
int res;
+ int opcode_filter;
if (buf->flags & FUSE_BUF_IS_FD) {
if (buf->size < tmpbuf.buf[0].size)
@@ -2659,11 +2709,16 @@ void fuse_session_process_buf_int(struct fuse_session *se,
in = buf->mem;
}
+ /* Cleanup opcode most significant bits used by FUSE BPF */
+ opcode_filter = in->opcode & ~FUSE_OPCODE_FILTER;
+ in->opcode &= FUSE_OPCODE_FILTER;
+
if (se->debug) {
fuse_log(FUSE_LOG_DEBUG,
- "unique: %llu, opcode: %s (%i), nodeid: %llu, insize: %zu, pid: %u\n",
+ "unique: %llu, opcode: %s (%i), opcode filter: %s (%i), nodeid: %llu, insize: %zu, pid: %u\n",
(unsigned long long) in->unique,
opname((enum fuse_opcode) in->opcode), in->opcode,
+ opfiltername((enum fuse_opcode) opcode_filter), opcode_filter,
(unsigned long long) in->nodeid, buf->size, in->pid);
}
@@ -3045,7 +3100,7 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
list_init_req(&se->interrupts);
list_init_nreq(&se->notify_list);
se->notify_ctr = 1;
- fuse_mutex_init(&se->lock);
+ pthread_mutex_init(&se->lock, NULL);
err = pthread_key_create(&se->pipe_key, fuse_ll_pipe_destructor);
if (err) {
@@ -3066,7 +3121,8 @@ out5:
out4:
fuse_opt_free_args(args);
out3:
- free(mo);
+ if (mo != NULL)
+ destroy_mount_opts(mo);
out2:
free(se);
out1:
@@ -3132,6 +3188,7 @@ void fuse_session_unmount(struct fuse_session *se)
{
if (se->mountpoint != NULL) {
fuse_kern_unmount(se->mountpoint, se->fd);
+ se->fd = -1;
free(se->mountpoint);
se->mountpoint = NULL;
}
@@ -3207,17 +3264,22 @@ int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
}
#endif
+/* Prevent spurious data race warning - we don't care
+ * about races for this flag */
+__attribute__((no_sanitize_thread))
void fuse_session_exit(struct fuse_session *se)
{
se->exited = 1;
}
+__attribute__((no_sanitize_thread))
void fuse_session_reset(struct fuse_session *se)
{
se->exited = 0;
se->error = 0;
}
+__attribute__((no_sanitize_thread))
int fuse_session_exited(struct fuse_session *se)
{
return se->exited;
diff --git a/lib/fuse_misc.h b/lib/fuse_misc.h
index 2f6663e..f956ab7 100644
--- a/lib/fuse_misc.h
+++ b/lib/fuse_misc.h
@@ -10,27 +10,16 @@
/*
Versioned symbols cannot be used in some cases because it
- - confuse the dynamic linker in uClibc
- not supported on MacOSX (in MachO binary format)
*/
-#if (!defined(__UCLIBC__) && !defined(__APPLE__))
-#define FUSE_SYMVER(x) __asm__(x)
+#ifndef __APPLE__
+# if HAVE_SYMVER_ATTRIBUTE
+# define FUSE_SYMVER(sym1, sym2) __attribute__ ((symver (sym2)))
+# else
+# define FUSE_SYMVER(sym1, sym2) __asm__("\t.symver " sym1 "," sym2);
+# endif
#else
-#define FUSE_SYMVER(x)
-#endif
-
-#ifndef USE_UCLIBC
-#define fuse_mutex_init(mut) pthread_mutex_init(mut, NULL)
-#else
-/* Is this hack still needed? */
-static inline void fuse_mutex_init(pthread_mutex_t *mut)
-{
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
- pthread_mutex_init(mut, &attr);
- pthread_mutexattr_destroy(&attr);
-}
+#define FUSE_SYMVER(sym1, sym2)
#endif
#ifdef HAVE_STRUCT_STAT_ST_ATIM
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index b01699a..35964f3 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -145,6 +145,7 @@ FUSE_3.2 {
global:
fuse_session_loop_mt;
fuse_session_loop_mt_31;
+ fuse_session_loop_mt_32;
fuse_loop_mt;
fuse_loop_mt_31;
} FUSE_3.1;
diff --git a/lib/meson.build b/lib/meson.build
index 28f0aee..98461d8 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -37,7 +37,7 @@ libfuse = library('fuse3', libfuse_sources, version: meson.project_version(),
soversion: '3', include_directories: include_dirs,
dependencies: deps, install: true,
link_depends: 'fuse_versionscript',
- c_args: [ '-DFUSE_USE_VERSION=34',
+ c_args: [ '-DFUSE_USE_VERSION=35',
'-DFUSERMOUNT_DIR="@0@"'.format(fusermount_path) ],
link_args: ['-Wl,--version-script,' + meson.current_source_dir()
+ '/fuse_versionscript' ])
diff --git a/lib/modules/iconv.c b/lib/modules/iconv.c
index eb5edd8..0ec3c2b 100644
--- a/lib/modules/iconv.c
+++ b/lib/modules/iconv.c
@@ -638,13 +638,18 @@ static const struct fuse_opt iconv_opts[] = {
static void iconv_help(void)
{
- char *old = strdup(setlocale(LC_CTYPE, ""));
- char *charmap = strdup(nl_langinfo(CODESET));
- setlocale(LC_CTYPE, old);
- free(old);
+ char *charmap;
+ const char *old = setlocale(LC_CTYPE, "");
+
+ charmap = strdup(nl_langinfo(CODESET));
+ if (old)
+ setlocale(LC_CTYPE, old);
+ else
+ perror("setlocale");
+
printf(
" -o from_code=CHARSET original encoding of file names (default: UTF-8)\n"
-" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
+" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
charmap);
free(charmap);
}
@@ -667,7 +672,7 @@ static struct fuse_fs *iconv_new(struct fuse_args *args,
{
struct fuse_fs *fs;
struct iconv *ic;
- char *old = NULL;
+ const char *old = NULL;
const char *from;
const char *to;
@@ -689,7 +694,7 @@ static struct fuse_fs *iconv_new(struct fuse_args *args,
to = ic->to_code ? ic->to_code : "";
/* FIXME: detect charset equivalence? */
if (!to[0])
- old = strdup(setlocale(LC_CTYPE, ""));
+ old = setlocale(LC_CTYPE, "");
ic->tofs = iconv_open(from, to);
if (ic->tofs == (iconv_t) -1) {
fuse_log(FUSE_LOG_ERR, "fuse-iconv: cannot convert from %s to %s\n",
@@ -704,7 +709,7 @@ static struct fuse_fs *iconv_new(struct fuse_args *args,
}
if (old) {
setlocale(LC_CTYPE, old);
- free(old);
+ old = NULL;
}
ic->next = next[0];
@@ -724,7 +729,6 @@ out_free:
free(ic);
if (old) {
setlocale(LC_CTYPE, old);
- free(old);
}
return NULL;
}
diff --git a/lib/mount_util.c b/lib/mount_util.c
index f1d2325..35e9948 100644
--- a/lib/mount_util.c
+++ b/lib/mount_util.c
@@ -30,7 +30,7 @@
#include <sys/mount.h>
#include <sys/param.h>
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
#define umount2(mnt, flags) unmount(mnt, ((flags) == 2) ? MNT_FORCE : 0)
#endif