aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/virtiofsd/fuse_lowlevel.c43
-rw-r--r--tools/virtiofsd/fuse_virtio.c129
-rw-r--r--tools/virtiofsd/helper.c3
-rw-r--r--tools/virtiofsd/passthrough_ll.c64
4 files changed, 139 insertions, 100 deletions
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c
index 58e32fc963..7fe2cef1eb 100644
--- a/tools/virtiofsd/fuse_lowlevel.c
+++ b/tools/virtiofsd/fuse_lowlevel.c
@@ -106,7 +106,7 @@ static void list_add_req(struct fuse_req *req, struct fuse_req *next)
static void destroy_req(fuse_req_t req)
{
pthread_mutex_destroy(&req->lock);
- free(req);
+ g_free(req);
}
void fuse_free_req(fuse_req_t req)
@@ -130,7 +130,7 @@ static struct fuse_req *fuse_ll_alloc_req(struct fuse_session *se)
{
struct fuse_req *req;
- req = (struct fuse_req *)calloc(1, sizeof(struct fuse_req));
+ req = g_try_new0(struct fuse_req, 1);
if (req == NULL) {
fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate request\n");
} else {
@@ -217,9 +217,9 @@ static int send_reply(fuse_req_t req, int error, const void *arg,
int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
{
int res;
- struct iovec *padded_iov;
+ g_autofree struct iovec *padded_iov = NULL;
- padded_iov = malloc((count + 1) * sizeof(struct iovec));
+ padded_iov = g_try_new(struct iovec, count + 1);
if (padded_iov == NULL) {
return fuse_reply_err(req, ENOMEM);
}
@@ -228,7 +228,6 @@ int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
count++;
res = send_reply_iov(req, 0, padded_iov, count);
- free(padded_iov);
return res;
}
@@ -568,7 +567,7 @@ static struct fuse_ioctl_iovec *fuse_ioctl_iovec_copy(const struct iovec *iov,
struct fuse_ioctl_iovec *fiov;
size_t i;
- fiov = malloc(sizeof(fiov[0]) * count);
+ fiov = g_try_new(struct fuse_ioctl_iovec, count);
if (!fiov) {
return NULL;
}
@@ -586,8 +585,8 @@ int fuse_reply_ioctl_retry(fuse_req_t req, const struct iovec *in_iov,
size_t out_count)
{
struct fuse_ioctl_out arg;
- struct fuse_ioctl_iovec *in_fiov = NULL;
- struct fuse_ioctl_iovec *out_fiov = NULL;
+ g_autofree struct fuse_ioctl_iovec *in_fiov = NULL;
+ g_autofree struct fuse_ioctl_iovec *out_fiov = NULL;
struct iovec iov[4];
size_t count = 1;
int res;
@@ -603,13 +602,14 @@ int fuse_reply_ioctl_retry(fuse_req_t req, const struct iovec *in_iov,
/* Can't handle non-compat 64bit ioctls on 32bit */
if (sizeof(void *) == 4 && req->ioctl_64bit) {
res = fuse_reply_err(req, EINVAL);
- goto out;
+ return res;
}
if (in_count) {
in_fiov = fuse_ioctl_iovec_copy(in_iov, in_count);
if (!in_fiov) {
- goto enomem;
+ res = fuse_reply_err(req, ENOMEM);
+ return res;
}
iov[count].iov_base = (void *)in_fiov;
@@ -619,7 +619,8 @@ int fuse_reply_ioctl_retry(fuse_req_t req, const struct iovec *in_iov,
if (out_count) {
out_fiov = fuse_ioctl_iovec_copy(out_iov, out_count);
if (!out_fiov) {
- goto enomem;
+ res = fuse_reply_err(req, ENOMEM);
+ return res;
}
iov[count].iov_base = (void *)out_fiov;
@@ -628,15 +629,8 @@ int fuse_reply_ioctl_retry(fuse_req_t req, const struct iovec *in_iov,
}
res = send_reply_iov(req, 0, iov, count);
-out:
- free(in_fiov);
- free(out_fiov);
return res;
-
-enomem:
- res = fuse_reply_err(req, ENOMEM);
- goto out;
}
int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
@@ -663,11 +657,11 @@ int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size)
int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
int count)
{
- struct iovec *padded_iov;
+ g_autofree struct iovec *padded_iov = NULL;
struct fuse_ioctl_out arg;
int res;
- padded_iov = malloc((count + 2) * sizeof(struct iovec));
+ padded_iov = g_try_new(struct iovec, count + 2);
if (padded_iov == NULL) {
return fuse_reply_err(req, ENOMEM);
}
@@ -680,7 +674,6 @@ int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
memcpy(&padded_iov[2], iov, count * sizeof(struct iovec));
res = send_reply_iov(req, 0, padded_iov, count + 2);
- free(padded_iov);
return res;
}
@@ -1684,7 +1677,7 @@ static struct fuse_req *check_interrupt(struct fuse_session *se,
if (curr->u.i.unique == req->unique) {
req->interrupted = 1;
list_del_req(curr);
- free(curr);
+ g_free(curr);
return NULL;
}
}
@@ -2477,7 +2470,7 @@ void fuse_session_destroy(struct fuse_session *se)
free(se->vu_socket_path);
se->vu_socket_path = NULL;
- free(se);
+ g_free(se);
}
@@ -2500,7 +2493,7 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
return NULL;
}
- se = (struct fuse_session *)calloc(1, sizeof(struct fuse_session));
+ se = g_try_new0(struct fuse_session, 1);
if (se == NULL) {
fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse object\n");
goto out1;
@@ -2560,7 +2553,7 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
out4:
fuse_opt_free_args(args);
out2:
- free(se);
+ g_free(se);
out1:
return NULL;
}
diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 3e13997406..1170f375a5 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -129,18 +129,55 @@ static void fv_panic(VuDev *dev, const char *err)
* Copy from an iovec into a fuse_buf (memory only)
* Caller must ensure there is space
*/
-static void copy_from_iov(struct fuse_buf *buf, size_t out_num,
- const struct iovec *out_sg)
+static size_t copy_from_iov(struct fuse_buf *buf, size_t out_num,
+ const struct iovec *out_sg,
+ size_t max)
{
void *dest = buf->mem;
+ size_t copied = 0;
- while (out_num) {
+ while (out_num && max) {
size_t onelen = out_sg->iov_len;
+ onelen = MIN(onelen, max);
memcpy(dest, out_sg->iov_base, onelen);
dest += onelen;
+ copied += onelen;
out_sg++;
out_num--;
+ max -= onelen;
}
+
+ return copied;
+}
+
+/*
+ * Skip 'skip' bytes in the iov; 'sg_1stindex' is set as
+ * the index for the 1st iovec to read data from, and
+ * 'sg_1stskip' is the number of bytes to skip in that entry.
+ *
+ * Returns True if there are at least 'skip' bytes in the iovec
+ *
+ */
+static bool skip_iov(const struct iovec *sg, size_t sg_size,
+ size_t skip,
+ size_t *sg_1stindex, size_t *sg_1stskip)
+{
+ size_t vec;
+
+ for (vec = 0; vec < sg_size; vec++) {
+ if (sg[vec].iov_len > skip) {
+ *sg_1stskip = skip;
+ *sg_1stindex = vec;
+
+ return true;
+ }
+
+ skip -= sg[vec].iov_len;
+ }
+
+ *sg_1stindex = vec;
+ *sg_1stskip = 0;
+ return skip == 0;
}
/*
@@ -294,6 +331,7 @@ int virtio_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
VuVirtq *q = vu_get_queue(dev, qi->qidx);
VuVirtqElement *elem = &req->elem;
int ret = 0;
+ g_autofree struct iovec *in_sg_cpy = NULL;
assert(count >= 1);
assert(iov[0].iov_len >= sizeof(struct fuse_out_header));
@@ -347,8 +385,7 @@ int virtio_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
* Build a copy of the the in_sg iov so we can skip bits in it,
* including changing the offsets
*/
- struct iovec *in_sg_cpy = calloc(sizeof(struct iovec), in_num);
- assert(in_sg_cpy);
+ in_sg_cpy = g_new(struct iovec, in_num);
memcpy(in_sg_cpy, in_sg, sizeof(struct iovec) * in_num);
/* These get updated as we skip */
struct iovec *in_sg_ptr = in_sg_cpy;
@@ -386,7 +423,6 @@ int virtio_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
ret = errno;
fuse_log(FUSE_LOG_DEBUG, "%s: preadv failed (%m) len=%zd\n",
__func__, len);
- free(in_sg_cpy);
goto err;
}
fuse_log(FUSE_LOG_DEBUG, "%s: preadv ret=%d len=%zd\n", __func__,
@@ -410,13 +446,11 @@ int virtio_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
if (ret != len) {
fuse_log(FUSE_LOG_DEBUG, "%s: ret!=len\n", __func__);
ret = EIO;
- free(in_sg_cpy);
goto err;
}
in_sg_left -= ret;
len -= ret;
} while (in_sg_left);
- free(in_sg_cpy);
/* Need to fix out->len on EOF */
if (len) {
@@ -457,6 +491,7 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
bool allocated_bufv = false;
struct fuse_bufvec bufv;
struct fuse_bufvec *pbufv;
+ struct fuse_in_header inh;
assert(se->bufsize > sizeof(struct fuse_in_header));
@@ -476,8 +511,7 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
* They're spread over multiple descriptors in a scatter/gather set
* and we can't trust the guest to keep them still; so copy in/out.
*/
- fbuf.mem = malloc(se->bufsize);
- assert(fbuf.mem);
+ fbuf.mem = g_malloc(se->bufsize);
fuse_mutex_init(&req->ch.lock);
req->ch.fd = -1;
@@ -505,14 +539,15 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
elem->index);
assert(0); /* TODO */
}
- /* Copy just the first element and look at it */
- copy_from_iov(&fbuf, 1, out_sg);
+ /* Copy just the fuse_in_header and look at it */
+ copy_from_iov(&fbuf, out_num, out_sg,
+ sizeof(struct fuse_in_header));
+ memcpy(&inh, fbuf.mem, sizeof(struct fuse_in_header));
pbufv = NULL; /* Compiler thinks an unitialised path */
- if (out_num > 2 &&
- out_sg[0].iov_len == sizeof(struct fuse_in_header) &&
- ((struct fuse_in_header *)fbuf.mem)->opcode == FUSE_WRITE &&
- out_sg[1].iov_len == sizeof(struct fuse_write_in)) {
+ if (inh.opcode == FUSE_WRITE &&
+ out_len >= (sizeof(struct fuse_in_header) +
+ sizeof(struct fuse_write_in))) {
/*
* For a write we don't actually need to copy the
* data, we can just do it straight out of guest memory
@@ -521,15 +556,15 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
*/
fuse_log(FUSE_LOG_DEBUG, "%s: Write special case\n", __func__);
- /* copy the fuse_write_in header afte rthe fuse_in_header */
- fbuf.mem += out_sg->iov_len;
- copy_from_iov(&fbuf, 1, out_sg + 1);
- fbuf.mem -= out_sg->iov_len;
- fbuf.size = out_sg[0].iov_len + out_sg[1].iov_len;
+ fbuf.size = copy_from_iov(&fbuf, out_num, out_sg,
+ sizeof(struct fuse_in_header) +
+ sizeof(struct fuse_write_in));
+ /* That copy reread the in_header, make sure we use the original */
+ memcpy(fbuf.mem, &inh, sizeof(struct fuse_in_header));
/* Allocate the bufv, with space for the rest of the iov */
- pbufv = malloc(sizeof(struct fuse_bufvec) +
- sizeof(struct fuse_buf) * (out_num - 2));
+ pbufv = g_try_malloc(sizeof(struct fuse_bufvec) +
+ sizeof(struct fuse_buf) * out_num);
if (!pbufv) {
fuse_log(FUSE_LOG_ERR, "%s: pbufv malloc failed\n",
__func__);
@@ -540,24 +575,37 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
pbufv->count = 1;
pbufv->buf[0] = fbuf;
- size_t iovindex, pbufvindex;
- iovindex = 2; /* 2 headers, separate iovs */
+ size_t iovindex, pbufvindex, iov_bytes_skip;
pbufvindex = 1; /* 2 headers, 1 fusebuf */
+ if (!skip_iov(out_sg, out_num,
+ sizeof(struct fuse_in_header) +
+ sizeof(struct fuse_write_in),
+ &iovindex, &iov_bytes_skip)) {
+ fuse_log(FUSE_LOG_ERR, "%s: skip failed\n",
+ __func__);
+ goto out;
+ }
+
for (; iovindex < out_num; iovindex++, pbufvindex++) {
pbufv->count++;
pbufv->buf[pbufvindex].pos = ~0; /* Dummy */
pbufv->buf[pbufvindex].flags = 0;
pbufv->buf[pbufvindex].mem = out_sg[iovindex].iov_base;
pbufv->buf[pbufvindex].size = out_sg[iovindex].iov_len;
+
+ if (iov_bytes_skip) {
+ pbufv->buf[pbufvindex].mem += iov_bytes_skip;
+ pbufv->buf[pbufvindex].size -= iov_bytes_skip;
+ iov_bytes_skip = 0;
+ }
}
} else {
/* Normal (non fast write) path */
- /* Copy the rest of the buffer */
- fbuf.mem += out_sg->iov_len;
- copy_from_iov(&fbuf, out_num - 1, out_sg + 1);
- fbuf.mem -= out_sg->iov_len;
+ copy_from_iov(&fbuf, out_num, out_sg, se->bufsize);
+ /* That copy reread the in_header, make sure we use the original */
+ memcpy(fbuf.mem, &inh, sizeof(struct fuse_in_header));
fbuf.size = out_len;
/* TODO! Endianness of header */
@@ -573,7 +621,7 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
out:
if (allocated_bufv) {
- free(pbufv);
+ g_free(pbufv);
}
/* If the request has no reply, still recycle the virtqueue element */
@@ -592,7 +640,7 @@ out:
}
pthread_mutex_destroy(&req->ch.lock);
- free(fbuf.mem);
+ g_free(fbuf.mem);
free(req);
}
@@ -733,7 +781,7 @@ static void fv_queue_cleanup_thread(struct fv_VuDev *vud, int qidx)
pthread_mutex_destroy(&ourqi->vq_lock);
close(ourqi->kill_fd);
ourqi->kick_fd = -1;
- free(vud->qi[qidx]);
+ g_free(vud->qi[qidx]);
vud->qi[qidx] = NULL;
}
@@ -764,15 +812,13 @@ static void fv_queue_set_started(VuDev *dev, int qidx, bool started)
if (started) {
/* Fire up a thread to watch this queue */
if (qidx >= vud->nqueues) {
- vud->qi = realloc(vud->qi, (qidx + 1) * sizeof(vud->qi[0]));
- assert(vud->qi);
+ vud->qi = g_realloc_n(vud->qi, qidx + 1, sizeof(vud->qi[0]));
memset(vud->qi + vud->nqueues, 0,
sizeof(vud->qi[0]) * (1 + (qidx - vud->nqueues)));
vud->nqueues = qidx + 1;
}
if (!vud->qi[qidx]) {
- vud->qi[qidx] = calloc(sizeof(struct fv_QueueInfo), 1);
- assert(vud->qi[qidx]);
+ vud->qi[qidx] = g_new0(struct fv_QueueInfo, 1);
vud->qi[qidx]->virtio_dev = vud;
vud->qi[qidx]->qidx = qidx;
} else {
@@ -1038,12 +1084,7 @@ int virtio_session_mount(struct fuse_session *se)
__func__);
/* TODO: Some cleanup/deallocation! */
- se->virtio_dev = calloc(sizeof(struct fv_VuDev), 1);
- if (!se->virtio_dev) {
- fuse_log(FUSE_LOG_ERR, "%s: virtio_dev calloc failed\n", __func__);
- close(data_sock);
- return -1;
- }
+ se->virtio_dev = g_new0(struct fv_VuDev, 1);
se->vu_socketfd = data_sock;
se->virtio_dev->se = se;
@@ -1065,8 +1106,8 @@ void virtio_session_close(struct fuse_session *se)
return;
}
- free(se->virtio_dev->qi);
+ g_free(se->virtio_dev->qi);
pthread_rwlock_destroy(&se->virtio_dev->vu_dispatch_rwlock);
- free(se->virtio_dev);
+ g_free(se->virtio_dev);
se->virtio_dev = NULL;
}
diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
index 28243b51b2..5e98ed702b 100644
--- a/tools/virtiofsd/helper.c
+++ b/tools/virtiofsd/helper.c
@@ -172,6 +172,9 @@ void fuse_cmdline_help(void)
" default: no_writeback\n"
" -o xattr|no_xattr enable/disable xattr\n"
" default: no_xattr\n"
+ " -o xattrmap=<mapping> Enable xattr mapping (enables xattr)\n"
+ " <mapping> is a string consists of a series of rules\n"
+ " e.g. -o xattrmap=:map::user.virtiofs.:\n"
" -o modcaps=CAPLIST Modify the list of capabilities\n"
" e.g. -o modcaps=+sys_admin:-chown\n"
" --rlimit-nofile=<num> set maximum number of file descriptors\n"
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 1553d2ef45..49c21fd855 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -406,7 +406,7 @@ static void lo_map_init(struct lo_map *map)
static void lo_map_destroy(struct lo_map *map)
{
- free(map->elems);
+ g_free(map->elems);
}
static int lo_map_grow(struct lo_map *map, size_t new_nelems)
@@ -418,7 +418,7 @@ static int lo_map_grow(struct lo_map *map, size_t new_nelems)
return 1;
}
- new_elems = realloc(map->elems, sizeof(map->elems[0]) * new_nelems);
+ new_elems = g_try_realloc_n(map->elems, new_nelems, sizeof(map->elems[0]));
if (!new_elems) {
return 0;
}
@@ -1653,7 +1653,7 @@ static void lo_do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
struct lo_data *lo = lo_data(req);
struct lo_dirp *d = NULL;
struct lo_inode *dinode;
- char *buf = NULL;
+ g_autofree char *buf = NULL;
char *p;
size_t rem = size;
int err = EBADF;
@@ -1669,7 +1669,7 @@ static void lo_do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
}
err = ENOMEM;
- buf = calloc(1, size);
+ buf = g_try_malloc0(size);
if (!buf) {
goto error;
}
@@ -1755,7 +1755,6 @@ error:
} else {
fuse_reply_buf(req, buf, size - rem);
}
- free(buf);
}
static void lo_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
@@ -2011,10 +2010,10 @@ static void lo_getlk(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
fuse_log(FUSE_LOG_DEBUG,
"lo_getlk(ino=%" PRIu64 ", flags=%d)"
- " owner=0x%lx, l_type=%d l_start=0x%lx"
- " l_len=0x%lx\n",
- ino, fi->flags, fi->lock_owner, lock->l_type, lock->l_start,
- lock->l_len);
+ " owner=0x%" PRIx64 ", l_type=%d l_start=0x%" PRIx64
+ " l_len=0x%" PRIx64 "\n",
+ ino, fi->flags, fi->lock_owner, lock->l_type,
+ (uint64_t)lock->l_start, (uint64_t)lock->l_len);
if (!lo->posix_lock) {
fuse_reply_err(req, ENOSYS);
@@ -2061,10 +2060,10 @@ static void lo_setlk(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
fuse_log(FUSE_LOG_DEBUG,
"lo_setlk(ino=%" PRIu64 ", flags=%d)"
- " cmd=%d pid=%d owner=0x%lx sleep=%d l_whence=%d"
- " l_start=0x%lx l_len=0x%lx\n",
+ " cmd=%d pid=%d owner=0x%" PRIx64 " sleep=%d l_whence=%d"
+ " l_start=0x%" PRIx64 " l_len=0x%" PRIx64 "\n",
ino, fi->flags, lock->l_type, lock->l_pid, fi->lock_owner, sleep,
- lock->l_whence, lock->l_start, lock->l_len);
+ lock->l_whence, (uint64_t)lock->l_start, (uint64_t)lock->l_len);
if (!lo->posix_lock) {
fuse_reply_err(req, ENOSYS);
@@ -2723,11 +2722,16 @@ static int xattr_map_server(const struct lo_data *lo, const char *server_name,
return -ENODATA;
}
+#define FCHDIR_NOFAIL(fd) do { \
+ int fchdir_res = fchdir(fd); \
+ assert(fchdir_res == 0); \
+ } while (0)
+
static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *in_name,
size_t size)
{
struct lo_data *lo = lo_data(req);
- char *value = NULL;
+ g_autofree char *value = NULL;
char procname[64];
const char *name;
char *mapped_name;
@@ -2768,7 +2772,7 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *in_name,
ino, name, size);
if (size) {
- value = malloc(size);
+ value = g_try_malloc(size);
if (!value) {
goto out_err;
}
@@ -2789,9 +2793,9 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *in_name,
ret = fgetxattr(fd, name, value, size);
} else {
/* fchdir should not fail here */
- assert(fchdir(lo->proc_self_fd) == 0);
+ FCHDIR_NOFAIL(lo->proc_self_fd);
ret = getxattr(procname, name, value, size);
- assert(fchdir(lo->root.fd) == 0);
+ FCHDIR_NOFAIL(lo->root.fd);
}
if (ret == -1) {
@@ -2807,8 +2811,6 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *in_name,
fuse_reply_xattr(req, ret);
}
out_free:
- free(value);
-
if (fd >= 0) {
close(fd);
}
@@ -2827,7 +2829,7 @@ out:
static void lo_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
{
struct lo_data *lo = lo_data(req);
- char *value = NULL;
+ g_autofree char *value = NULL;
char procname[64];
struct lo_inode *inode;
ssize_t ret;
@@ -2849,7 +2851,7 @@ static void lo_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
size);
if (size) {
- value = malloc(size);
+ value = g_try_malloc(size);
if (!value) {
goto out_err;
}
@@ -2864,9 +2866,9 @@ static void lo_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
ret = flistxattr(fd, value, size);
} else {
/* fchdir should not fail here */
- assert(fchdir(lo->proc_self_fd) == 0);
+ FCHDIR_NOFAIL(lo->proc_self_fd);
ret = listxattr(procname, value, size);
- assert(fchdir(lo->root.fd) == 0);
+ FCHDIR_NOFAIL(lo->root.fd);
}
if (ret == -1) {
@@ -2934,8 +2936,6 @@ static void lo_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
fuse_reply_xattr(req, ret);
}
out_free:
- free(value);
-
if (fd >= 0) {
close(fd);
}
@@ -3000,9 +3000,9 @@ static void lo_setxattr(fuse_req_t req, fuse_ino_t ino, const char *in_name,
ret = fsetxattr(fd, name, value, size, flags);
} else {
/* fchdir should not fail here */
- assert(fchdir(lo->proc_self_fd) == 0);
+ FCHDIR_NOFAIL(lo->proc_self_fd);
ret = setxattr(procname, name, value, size, flags);
- assert(fchdir(lo->root.fd) == 0);
+ FCHDIR_NOFAIL(lo->root.fd);
}
saverr = ret == -1 ? errno : 0;
@@ -3066,9 +3066,9 @@ static void lo_removexattr(fuse_req_t req, fuse_ino_t ino, const char *in_name)
ret = fremovexattr(fd, name);
} else {
/* fchdir should not fail here */
- assert(fchdir(lo->proc_self_fd) == 0);
+ FCHDIR_NOFAIL(lo->proc_self_fd);
ret = removexattr(procname, name);
- assert(fchdir(lo->root.fd) == 0);
+ FCHDIR_NOFAIL(lo->root.fd);
}
saverr = ret == -1 ? errno : 0;
@@ -3097,9 +3097,10 @@ static void lo_copy_file_range(fuse_req_t req, fuse_ino_t ino_in, off_t off_in,
fuse_log(FUSE_LOG_DEBUG,
"lo_copy_file_range(ino=%" PRIu64 "/fd=%d, "
- "off=%lu, ino=%" PRIu64 "/fd=%d, "
- "off=%lu, size=%zd, flags=0x%x)\n",
- ino_in, in_fd, off_in, ino_out, out_fd, off_out, len, flags);
+ "off=%ju, ino=%" PRIu64 "/fd=%d, "
+ "off=%ju, size=%zd, flags=0x%x)\n",
+ ino_in, in_fd, (intmax_t)off_in,
+ ino_out, out_fd, (intmax_t)off_out, len, flags);
res = copy_file_range(in_fd, &off_in, out_fd, &off_out, len, flags);
if (res < 0) {
@@ -3826,6 +3827,7 @@ int main(int argc, char *argv[])
}
if (lo.xattrmap) {
+ lo.xattr = 1;
parse_xattrmap(&lo);
}