Browse Source

checkpoint

clonefd
Antonio SJ Musumeci 5 years ago
parent
commit
67a36d436f
  1. 1
      libfuse/include/fuse_chan.h
  2. 175
      libfuse/lib/fuse_chan.c

1
libfuse/include/fuse_chan.h

@ -20,3 +20,4 @@ fuse_chan_t *fuse_chan_new(int32_t fd, uint32_t flags);
void fuse_chan_destroy(fuse_chan_t *ch);
int64_t fuse_chan_recv(fuse_chan_t *ch, char *buf, uint64_t size);
int64_t fuse_chan_send(fuse_chan_t *ch, const struct iovec iov[], uint64_t count);

175
libfuse/lib/fuse_chan.c

@ -234,6 +234,181 @@ fuse_chan_send(fuse_chan_t *ch,
return fuse_chan_send_write(ch,iov,count);
}
static
int
retryable_error(const int errno_)
{
switch(errno_)
{
case EINTR:
case EAGAIN:
return 1;
default:
return 0;
}
}
static
int
retry_error(const int rv_,
const int errno_)
{
if(rv_ == -1)
return retryable_error(errno_);
return 0;
}
static
int64_t
writen(const int fd_,
void *buf_,
const uint64_t count_)
{
char *buf;
uint64_t n_left;
int64_t n_written;
buf = buf_;
n_left = count_;
do
{
n_written = write(fd_,buf,n_left);
if(retry_error(n_written,errno))
continue;
if(n_written == -1)
return -1;
n_left -= n_written;
buf += n_written;
}
while(n_left > 0);
return count_;
}
static
int64_t
readn(const int fd_,
char *buf_,
const uint64_t count_)
{
uint64_t n_left;
int64_t n_read;
n_left = count_;
do
{
n_read = read(fd_,buf_,n_left);
if(n_read == 0)
return 0;
if(retry_error(n_read,errno))
continue;
if(n_read == -1)
return -1;
n_left -= n_read;
}
while(n_left > 0);
return count_;
}
static
int64_t
splicen_seek(const int fd_in_,
const loff_t off_in_,
const int fd_out_,
const uint64_t len_)
{
uint64_t n_left;
int64_t n_written;
loff_t off_in;
n_left = len_;
off_in = off_in_;
do
{
n_written = splice(fd_in_,&off_in,fd_out_,NULL,n_left,SPLICE_F_MOVE);
if(retry_error(n_written,errno))
continue;
if(n_written == -1)
return -1;
n_left -= n_written;
off_in += n_written;
}
while(n_left > 0);
return len_;
}
static
int64_t
splicen_noseek(const int fd_in_,
const int fd_out_,
const uint64_t len_)
{
uint64_t n_left;
int64_t n_written;
n_left = len_;
do
{
n_written = splice(fd_in_,NULL,fd_out_,NULL,n_left,SPLICE_F_MOVE);
if(retry_error(n_written,errno))
continue;
if(n_written == -1)
return -1;
n_left -= n_written;
}
while(n_left > 0);
return len_;
}
int64_t
fuse_chan_send_data_splice(fuse_chan_t *ch_,
struct fuse_out_header *hdr_,
const int data_fd_,
const loff_t data_off_,
const int data_len_)
{
int64_t rv;
rv = writen(ch_->splice_pipe[1],hdr_,sizeof(struct fuse_out_header));
if(rv == -1)
return -1;
rv = splicen_seek(data_fd_,data_off_,ch_->splice_pipe[1],data_len_);
if(rv == -1)
return -1;
rv = splicen_noseek(ch_->splice_pipe[0],ch_->fd,(sizeof(struct fuse_out_header)+data_len_));
return rv;
}
int64_t
fuse_chan_send_data(fuse_chan_t *ch_,
struct fuse_out_header *hdr_,
const int data_fd_,
const int data_len_)
{
int64_t rv;
memcpy(ch_->buf,hdr_,sizeof(struct fuse_out_header));
rv = readn(data_fd_,
&ch_->buf[sizeof(struct fuse_out_header)],
data_len_);
if(rv == -1)
return -1;
rv = write(ch_->fd,ch_->buf,(sizeof(struct fuse_out_header) + data_len_));
return rv;
}
void
fuse_chan_destroy(fuse_chan_t *ch)
{

Loading…
Cancel
Save