aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlessio Balsini <balsini@google.com>2022-01-25 10:20:53 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-01-25 10:20:53 +0000
commitcf2ecd0ca3b023bcd1f492a2a8964154f4253b04 (patch)
tree2cab7816ace50b5f1a8ada440be0efc0cdc1a7c8 /lib
parent2df88fddbd2487e338c0d816125b2ccdf19e3a34 (diff)
parent67d943a80f139dd731419bef7338285c87c179ab (diff)
downloadlibfuse-cf2ecd0ca3b023bcd1f492a2a8964154f4253b04.tar.gz
Merge tag 'fuse-3.10.5' into HEAD am: cd66eb8d16 am: 0492860686 am: f89a857b27 am: 67d943a80f
Original change: https://android-review.googlesource.com/c/platform/external/libfuse/+/1959081 Change-Id: I6db3bad798490d3319cf0da2f6d7c4bb2b0a968d
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.c53
-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, 78 insertions, 61 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 459fca5..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");
@@ -755,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);
@@ -766,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 ||
@@ -2006,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;
@@ -2078,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()
@@ -2204,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) {
@@ -2344,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;
@@ -2366,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;
@@ -2391,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;
@@ -2420,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;
@@ -2498,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));
@@ -3092,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) {
@@ -3113,7 +3121,8 @@ out5:
out4:
fuse_opt_free_args(args);
out3:
- free(mo);
+ if (mo != NULL)
+ destroy_mount_opts(mo);
out2:
free(se);
out1:
@@ -3179,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;
}
@@ -3254,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