Rework fuse read to use same buffers as messages

This commit is contained in:
Antonio SJ Musumeci
2023-02-26 15:16:18 -05:00
parent 4a647beec1
commit 373d331f39
9 changed files with 188 additions and 202 deletions

View File

@ -23,6 +23,7 @@
#include "fuse_misc.h"
#include "fuse_opt.h"
#include "fuse_pollhandle.h"
#include "fuse_msgbuf.hpp"
#include <assert.h>
#include <dlfcn.h>
@ -1379,20 +1380,6 @@ req_fuse(fuse_req_t req)
return (struct fuse*)fuse_req_userdata(req);
}
static
void
fuse_free_buf(struct fuse_bufvec *buf)
{
if(buf != NULL)
{
size_t i;
for(i = 0; i < buf->count; i++)
free(buf->buf[i].mem);
free(buf);
}
}
static
int
node_open(const struct node *node_)
@ -1545,16 +1532,6 @@ req_fuse_prepare(fuse_req_t req)
return c->ctx.fuse;
}
static
inline
void
reply_err(fuse_req_t req,
int err)
{
/* fuse_reply_err() uses non-negated errno values */
fuse_reply_err(req,-err);
}
static
void
reply_entry(fuse_req_t req,
@ -1573,7 +1550,7 @@ reply_entry(fuse_req_t req,
}
else
{
reply_err(req,err);
fuse_reply_err(req,err);
}
}
@ -1770,7 +1747,7 @@ fuse_lib_getattr(fuse_req_t req,
}
else
{
reply_err(req,err);
fuse_reply_err(req,err);
}
}
@ -1893,7 +1870,7 @@ fuse_lib_setattr(fuse_req_t req,
}
else
{
reply_err(req,err);
fuse_reply_err(req,err);
}
}
@ -1918,7 +1895,7 @@ fuse_lib_access(fuse_req_t req,
free_path(f,hdr_->nodeid,path);
}
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -1947,7 +1924,7 @@ fuse_lib_readlink(fuse_req_t req,
}
else
{
reply_err(req,err);
fuse_reply_err(req,err);
}
}
@ -2068,7 +2045,7 @@ fuse_lib_unlink(fuse_req_t req,
free_path_wrlock(f,hdr_->nodeid,wnode,path);
}
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -2095,7 +2072,7 @@ fuse_lib_rmdir(fuse_req_t req,
free_path_wrlock(f,hdr_->nodeid,wnode,path);
}
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -2168,7 +2145,7 @@ fuse_lib_rename(fuse_req_t req,
free_path2(f,hdr_->nodeid,arg->newdir,wnode1,wnode2,oldpath,newpath);
}
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -2295,7 +2272,7 @@ fuse_lib_create(fuse_req_t req,
}
else
{
reply_err(req,err);
fuse_reply_err(req,err);
}
free_path(f,hdr_->nodeid,path);
@ -2376,7 +2353,7 @@ fuse_lib_open(fuse_req_t req,
}
else
{
reply_err(req,err);
fuse_reply_err(req,err);
}
free_path(f,hdr_->nodeid,path);
@ -2390,8 +2367,8 @@ fuse_lib_read(fuse_req_t req,
int res;
struct fuse *f;
fuse_file_info_t ffi = {0};
struct fuse_bufvec *buf = NULL;
struct fuse_read_in *arg;
fuse_msgbuf_t *msgbuf;
arg = fuse_hdr_arg(hdr_);
ffi.fh = arg->fh;
@ -2403,14 +2380,16 @@ fuse_lib_read(fuse_req_t req,
f = req_fuse_prepare(req);
res = f->fs->op.read_buf(&ffi,&buf,arg->size,arg->offset);
msgbuf = msgbuf_alloc();
res = f->fs->op.read(&ffi,msgbuf->mem,arg->size,arg->offset);
if(res >= 0)
fuse_reply_data(req,buf,FUSE_BUF_SPLICE_MOVE);
fuse_reply_data(req,msgbuf->mem,res);
else
reply_err(req,res);
fuse_reply_err(req,res);
fuse_free_buf(buf);
msgbuf_free(msgbuf);
}
static
@ -2446,7 +2425,7 @@ fuse_lib_write(fuse_req_t req,
if(res >= 0)
fuse_reply_write(req,res);
else
reply_err(req,res);
fuse_reply_err(req,res);
}
static
@ -2467,7 +2446,7 @@ fuse_lib_fsync(fuse_req_t req,
err = f->fs->op.fsync(&ffi,
!!(arg->fsync_flags & 1));
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -2502,7 +2481,7 @@ fuse_lib_opendir(fuse_req_t req,
dh = (struct fuse_dh *)calloc(1,sizeof(struct fuse_dh));
if(dh == NULL)
{
reply_err(req,-ENOMEM);
fuse_reply_err(req,ENOMEM);
return;
}
@ -2534,7 +2513,7 @@ fuse_lib_opendir(fuse_req_t req,
}
else
{
reply_err(req,err);
fuse_reply_err(req,err);
pthread_mutex_destroy(&dh->lock);
free(dh);
}
@ -2597,7 +2576,7 @@ fuse_lib_readdir(fuse_req_t req_,
if(rv)
{
reply_err(req_,rv);
fuse_reply_err(req_,rv);
goto out;
}
@ -2641,7 +2620,7 @@ fuse_lib_readdir_plus(fuse_req_t req_,
if(rv)
{
reply_err(req_,rv);
fuse_reply_err(req_,rv);
goto out;
}
@ -2681,7 +2660,7 @@ fuse_lib_releasedir(fuse_req_t req_,
pthread_mutex_destroy(&dh->lock);
fuse_dirents_free(&dh->d);
free(dh);
reply_err(req_,0);
fuse_reply_err(req_,0);
}
static
@ -2705,7 +2684,7 @@ fuse_lib_fsyncdir(fuse_req_t req,
err = f->fs->op.fsyncdir(&ffi,
!!(arg->fsync_flags & FUSE_FSYNC_FDATASYNC));
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -2732,7 +2711,7 @@ fuse_lib_statfs(fuse_req_t req,
if(!err)
fuse_reply_statfs(req,&buf);
else
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -2764,7 +2743,7 @@ fuse_lib_setxattr(fuse_req_t req,
free_path(f,hdr_->nodeid,path);
}
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -2810,7 +2789,7 @@ fuse_lib_getxattr(fuse_req_t req,
char *value = (char*)malloc(arg->size);
if(value == NULL)
{
reply_err(req,-ENOMEM);
fuse_reply_err(req,ENOMEM);
return;
}
@ -2818,7 +2797,7 @@ fuse_lib_getxattr(fuse_req_t req,
if(res > 0)
fuse_reply_buf(req,value,res);
else
reply_err(req,res);
fuse_reply_err(req,res);
free(value);
}
else
@ -2827,7 +2806,7 @@ fuse_lib_getxattr(fuse_req_t req,
if(res >= 0)
fuse_reply_xattr(req,res);
else
reply_err(req,res);
fuse_reply_err(req,res);
}
}
@ -2870,7 +2849,7 @@ fuse_lib_listxattr(fuse_req_t req,
char *list = (char*)malloc(arg->size);
if(list == NULL)
{
reply_err(req,-ENOMEM);
fuse_reply_err(req,ENOMEM);
return;
}
@ -2878,7 +2857,7 @@ fuse_lib_listxattr(fuse_req_t req,
if(res > 0)
fuse_reply_buf(req,list,res);
else
reply_err(req,res);
fuse_reply_err(req,res);
free(list);
}
else
@ -2887,7 +2866,7 @@ fuse_lib_listxattr(fuse_req_t req,
if(res >= 0)
fuse_reply_xattr(req,res);
else
reply_err(req,res);
fuse_reply_err(req,res);
}
}
@ -2912,7 +2891,7 @@ fuse_lib_removexattr(fuse_req_t req,
free_path(f,hdr_->nodeid,path);
}
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -2942,7 +2921,7 @@ fuse_lib_copy_file_range(fuse_req_t req_,
if(rv >= 0)
fuse_reply_write(req_,rv);
else
reply_err(req_,rv);
fuse_reply_err(req_,rv);
}
static
@ -3157,7 +3136,7 @@ fuse_lib_release(fuse_req_t req,
fuse_do_release(f,hdr_->nodeid,&ffi);
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -3181,7 +3160,7 @@ fuse_lib_flush(fuse_req_t req,
err = fuse_flush_common(f,req,hdr_->nodeid,&ffi);
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -3252,7 +3231,7 @@ fuse_lib_getlk(fuse_req_t req,
if(!err)
fuse_reply_lock(req,&flk);
else
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -3276,7 +3255,7 @@ fuse_lib_setlk(fuse_req_t req,
pthread_mutex_unlock(&f->lock);
}
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -3291,7 +3270,7 @@ fuse_lib_flock(fuse_req_t req,
err = f->fs->op.flock(fi,op);
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -3320,7 +3299,7 @@ fuse_lib_bmap(fuse_req_t req,
if(!err)
fuse_reply_bmap(req,block);
else
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -3388,7 +3367,7 @@ fuse_lib_ioctl(fuse_req_t req,
fuse_reply_ioctl(req,err,out_buf,out_size);
goto out;
err:
reply_err(req,err);
fuse_reply_err(req,err);
out:
free(out_buf);
}
@ -3427,7 +3406,7 @@ fuse_lib_poll(fuse_req_t req,
if(!err)
fuse_reply_poll(req,revents);
else
reply_err(req,err);
fuse_reply_err(req,err);
}
static
@ -3450,7 +3429,7 @@ fuse_lib_fallocate(fuse_req_t req,
arg->offset,
arg->length);
reply_err(req,err);
fuse_reply_err(req,err);
}
static

View File

@ -146,6 +146,8 @@ fuse_send_msg(struct fuse_ll *f,
return 0;
}
#define MAX_ERRNO 4095
int
fuse_send_reply_iov_nofree(fuse_req_t req,
int error,
@ -154,17 +156,20 @@ fuse_send_reply_iov_nofree(fuse_req_t req,
{
struct fuse_out_header out;
if(error <= -1000 || error > 0)
if(error > 0)
error = -error;
if(error <= -MAX_ERRNO)
{
fprintf(stderr, "fuse: bad error value: %i\n",error);
fprintf(stderr,"fuse: bad error value: %i\n",error);
error = -ERANGE;
}
out.unique = req->unique;
out.error = error;
out.error = error;
iov[0].iov_base = &out;
iov[0].iov_len = sizeof(struct fuse_out_header);
iov[0].iov_len = sizeof(struct fuse_out_header);
return fuse_send_msg(req->f, req->ch, iov, count);
}
@ -231,7 +236,7 @@ int
fuse_reply_err(fuse_req_t req_,
int err_)
{
return send_reply(req_,-err_,NULL,0);
return send_reply(req_,err_,NULL,0);
}
void
@ -445,21 +450,23 @@ fuse_send_data_iov(struct fuse_ll *f,
}
int
fuse_reply_data(fuse_req_t req,
struct fuse_bufvec *bufv,
enum fuse_buf_copy_flags flags)
fuse_reply_data(fuse_req_t req,
char *buf_,
const size_t bufsize_)
{
int res;
struct iovec iov[2];
struct fuse_out_header out;
int res;
iov[0].iov_base = &out;
iov[0].iov_len = sizeof(struct fuse_out_header);
iov[0].iov_len = sizeof(struct fuse_out_header);
iov[1].iov_base = buf_;
iov[1].iov_len = bufsize_;
out.unique = req->unique;
out.error = 0;
res = fuse_send_data_iov(req->f, req->ch, iov, 1, bufv, flags);
res = fuse_send_msg(req->f,req->ch,iov,2);
if(res <= 0)
{
destroy_req(req);