From mboxrd@z Thu Jan 1 00:00:00 1970 From: Maxim Patlasov Subject: Re: [PATCH 09/12] fuse: handle synchronous iocbs internally Date: Thu, 5 Mar 2015 18:54:09 -0800 Message-ID: <54F916D1.1000808@parallels.com> References: <1424714436-19371-1-git-send-email-hch@lst.de> <1424714436-19371-10-git-send-email-hch@lst.de> Mime-Version: 1.0 Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit Cc: Robert Baldyga , Michal Nazarewicz , Felipe Balbi , , To: Christoph Hellwig , Al Viro Return-path: In-Reply-To: <1424714436-19371-10-git-send-email-hch@lst.de> Sender: owner-linux-aio@kvack.org List-Id: linux-fsdevel.vger.kernel.org Reviewed-by: Maxim Patlasov On 02/23/2015 10:00 AM, Christoph Hellwig wrote: > Based on a patch from Maxim Patlasov . > > Signed-off-by: Christoph Hellwig > --- > fs/fuse/file.c | 51 +++++++++++++++++++++++++++++++-------------------- > fs/fuse/fuse_i.h | 1 + > 2 files changed, 32 insertions(+), 20 deletions(-) > > diff --git a/fs/fuse/file.c b/fs/fuse/file.c > index c01ec3b..f81d83e 100644 > --- a/fs/fuse/file.c > +++ b/fs/fuse/file.c > @@ -528,6 +528,17 @@ static void fuse_release_user_pages(struct fuse_req *req, int write) > } > } > > +static ssize_t fuse_get_res_by_io(struct fuse_io_priv *io) > +{ > + if (io->err) > + return io->err; > + > + if (io->bytes >= 0 && io->write) > + return -EIO; > + > + return io->bytes < 0 ? io->size : io->bytes; > +} > + > /** > * In case of short read, the caller sets 'pos' to the position of > * actual end of fuse request in IO request. Otherwise, if bytes_requested > @@ -546,6 +557,7 @@ static void fuse_release_user_pages(struct fuse_req *req, int write) > */ > static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos) > { > + bool is_sync = is_sync_kiocb(io->iocb); > int left; > > spin_lock(&io->lock); > @@ -555,27 +567,21 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos) > io->bytes = pos; > > left = --io->reqs; > + if (!left && is_sync) > + complete(io->done); > spin_unlock(&io->lock); > > - if (!left) { > - long res; > + if (!left && !is_sync) { > + ssize_t res = fuse_get_res_by_io(io); > > - if (io->err) > - res = io->err; > - else if (io->bytes >= 0 && io->write) > - res = -EIO; > - else { > - res = io->bytes < 0 ? io->size : io->bytes; > + if (res >= 0) { > + struct inode *inode = file_inode(io->iocb->ki_filp); > + struct fuse_conn *fc = get_fuse_conn(inode); > + struct fuse_inode *fi = get_fuse_inode(inode); > > - if (!is_sync_kiocb(io->iocb)) { > - struct inode *inode = file_inode(io->iocb->ki_filp); > - struct fuse_conn *fc = get_fuse_conn(inode); > - struct fuse_inode *fi = get_fuse_inode(inode); > - > - spin_lock(&fc->lock); > - fi->attr_version = ++fc->attr_version; > - spin_unlock(&fc->lock); > - } > + spin_lock(&fc->lock); > + fi->attr_version = ++fc->attr_version; > + spin_unlock(&fc->lock); > } > > aio_complete(io->iocb, res, 0); > @@ -2801,6 +2807,7 @@ static ssize_t > fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, > loff_t offset) > { > + DECLARE_COMPLETION_ONSTACK(wait); > ssize_t ret = 0; > struct file *file = iocb->ki_filp; > struct fuse_file *ff = file->private_data; > @@ -2852,6 +2859,9 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, > if (!is_sync_kiocb(iocb) && (offset + count > i_size) && rw == WRITE) > io->async = false; > > + if (io->async && is_sync_kiocb(iocb)) > + io->done = &wait; > + > if (rw == WRITE) > ret = __fuse_direct_write(io, iter, &pos); > else > @@ -2864,11 +2874,12 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, > if (!is_sync_kiocb(iocb)) > return -EIOCBQUEUED; > > - ret = wait_on_sync_kiocb(iocb); > - } else { > - kfree(io); > + wait_for_completion(&wait); > + ret = fuse_get_res_by_io(io); > } > > + kfree(io); > + > if (rw == WRITE) { > if (ret > 0) > fuse_write_update_size(inode, pos); > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h > index 1cdfb07..7354dc1 100644 > --- a/fs/fuse/fuse_i.h > +++ b/fs/fuse/fuse_i.h > @@ -263,6 +263,7 @@ struct fuse_io_priv { > int err; > struct kiocb *iocb; > struct file *file; > + struct completion *done; > }; > > /** -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to majordomo@kvack.org. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: aart@kvack.org