lkml.org 
[lkml]   [2018]   [Apr]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 6/7] aio: implement IOCB_CMD_FSYNC and IOCB_CMD_FDSYNC
    Date
    Simple workqueue offload for now, but prepared for adding a real aio_fsync
    method if the need arises. Based on an earlier patch from Dave Chinner.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
    ---
    fs/aio.c | 43 +++++++++++++++++++++++++++++++++++++++++++
    1 file changed, 43 insertions(+)

    diff --git a/fs/aio.c b/fs/aio.c
    index d4dd002712c8..de56496ba86c 100644
    --- a/fs/aio.c
    +++ b/fs/aio.c
    @@ -156,6 +156,12 @@ struct kioctx {
    unsigned id;
    };

    +struct fsync_iocb {
    + struct work_struct work;
    + struct file *file;
    + bool datasync;
    +};
    +
    /*
    * We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either
    * cancelled or completed (this makes a certain amount of sense because
    @@ -172,6 +178,7 @@ struct kioctx {
    struct aio_kiocb {
    union {
    struct kiocb rw;
    + struct fsync_iocb fsync;
    };

    struct kioctx *ki_ctx;
    @@ -1571,6 +1578,36 @@ static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored,
    return ret;
    }

    +static void aio_fsync_work(struct work_struct *work)
    +{
    + struct fsync_iocb *req = container_of(work, struct fsync_iocb, work);
    + int ret;
    +
    + ret = vfs_fsync(req->file, req->datasync);
    + fput(req->file);
    + aio_complete(container_of(req, struct aio_kiocb, fsync), ret, 0);
    +}
    +
    +static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync)
    +{
    + if (unlikely(iocb->aio_buf || iocb->aio_offset || iocb->aio_nbytes ||
    + iocb->aio_rw_flags))
    + return -EINVAL;
    +
    + req->file = fget(iocb->aio_fildes);
    + if (unlikely(!req->file))
    + return -EBADF;
    + if (unlikely(!req->file->f_op->fsync)) {
    + fput(req->file);
    + return -EINVAL;
    + }
    +
    + req->datasync = datasync;
    + INIT_WORK(&req->work, aio_fsync_work);
    + schedule_work(&req->work);
    + return -EIOCBQUEUED;
    +}
    +
    static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
    struct iocb *iocb, bool compat)
    {
    @@ -1634,6 +1671,12 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
    case IOCB_CMD_PWRITEV:
    ret = aio_write(&req->rw, iocb, true, compat);
    break;
    + case IOCB_CMD_FSYNC:
    + ret = aio_fsync(&req->fsync, iocb, false);
    + break;
    + case IOCB_CMD_FDSYNC:
    + ret = aio_fsync(&req->fsync, iocb, true);
    + break;
    default:
    pr_debug("invalid aio operation %d\n", iocb->aio_lio_opcode);
    ret = -EINVAL;
    --
    2.17.0
    \
     
     \ /
      Last update: 2018-04-15 17:03    [W:2.123 / U:0.152 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site