Skip to content

Commit a3c0d43

Browse files
author
Christoph Hellwig
committed
aio: implement IOCB_CMD_FSYNC and IOCB_CMD_FDSYNC
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 <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]>
1 parent 54843f8 commit a3c0d43

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

fs/aio.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,12 @@ struct kioctx {
156156
unsigned id;
157157
};
158158

159+
struct fsync_iocb {
160+
struct work_struct work;
161+
struct file *file;
162+
bool datasync;
163+
};
164+
159165
/*
160166
* We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either
161167
* cancelled or completed (this makes a certain amount of sense because
@@ -172,6 +178,7 @@ struct kioctx {
172178
struct aio_kiocb {
173179
union {
174180
struct kiocb rw;
181+
struct fsync_iocb fsync;
175182
};
176183

177184
struct kioctx *ki_ctx;
@@ -1573,6 +1580,36 @@ static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored,
15731580
return ret;
15741581
}
15751582

1583+
static void aio_fsync_work(struct work_struct *work)
1584+
{
1585+
struct fsync_iocb *req = container_of(work, struct fsync_iocb, work);
1586+
int ret;
1587+
1588+
ret = vfs_fsync(req->file, req->datasync);
1589+
fput(req->file);
1590+
aio_complete(container_of(req, struct aio_kiocb, fsync), ret, 0);
1591+
}
1592+
1593+
static int aio_fsync(struct fsync_iocb *req, struct iocb *iocb, bool datasync)
1594+
{
1595+
if (unlikely(iocb->aio_buf || iocb->aio_offset || iocb->aio_nbytes ||
1596+
iocb->aio_rw_flags))
1597+
return -EINVAL;
1598+
1599+
req->file = fget(iocb->aio_fildes);
1600+
if (unlikely(!req->file))
1601+
return -EBADF;
1602+
if (unlikely(!req->file->f_op->fsync)) {
1603+
fput(req->file);
1604+
return -EINVAL;
1605+
}
1606+
1607+
req->datasync = datasync;
1608+
INIT_WORK(&req->work, aio_fsync_work);
1609+
schedule_work(&req->work);
1610+
return -EIOCBQUEUED;
1611+
}
1612+
15761613
static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
15771614
struct iocb *iocb, bool compat)
15781615
{
@@ -1636,6 +1673,12 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
16361673
case IOCB_CMD_PWRITEV:
16371674
ret = aio_write(&req->rw, iocb, true, compat);
16381675
break;
1676+
case IOCB_CMD_FSYNC:
1677+
ret = aio_fsync(&req->fsync, iocb, false);
1678+
break;
1679+
case IOCB_CMD_FDSYNC:
1680+
ret = aio_fsync(&req->fsync, iocb, true);
1681+
break;
16391682
default:
16401683
pr_debug("invalid aio operation %d\n", iocb->aio_lio_opcode);
16411684
ret = -EINVAL;

0 commit comments

Comments
 (0)