Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1512114 > unrolled thread
| Started by | Christoph Hellwig <hch@lst.de> |
|---|---|
| First post | 2016-10-30 17:50 +0100 |
| Last post | 2016-11-09 03:50 +0100 |
| Articles | 15 — 4 participants |
Back to article view | Back to linux.kernel
aio fixes for use after free and freeze protection Christoph Hellwig <hch@lst.de> - 2016-10-30 17:50 +0100
[PATCH 3/4] fs: remove aio_run_iocb Christoph Hellwig <hch@lst.de> - 2016-10-30 17:50 +0100
[PATCH 1/4] aio: hold an extra file reference over AIO read/write operations Christoph Hellwig <hch@lst.de> - 2016-10-30 17:50 +0100
[PATCH 4/4] aio: fix freeze protection of aio writes Christoph Hellwig <hch@lst.de> - 2016-10-30 17:50 +0100
[PATCH 2/4] fs: remove the never implemented aio_fsync file operation Christoph Hellwig <hch@lst.de> - 2016-10-30 17:50 +0100
Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation Dave Chinner <david@fromorbit.com> - 2016-10-31 00:30 +0100
Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation Christoph Hellwig <hch@lst.de> - 2016-10-31 14:10 +0100
Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation Dave Chinner <david@fromorbit.com> - 2016-10-31 21:30 +0100
Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation Linus Torvalds <torvalds@linux-foundation.org> - 2016-11-01 02:40 +0100
Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation Christoph Hellwig <hch@lst.de> - 2016-11-01 15:40 +0100
Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation Linus Torvalds <torvalds@linux-foundation.org> - 2016-11-01 16:10 +0100
Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation Christoph Hellwig <hch@lst.de> - 2016-11-01 15:30 +0100
Re: aio fixes for use after free and freeze protection Al Viro <viro@ZenIV.linux.org.uk> - 2016-10-30 18:00 +0100
Re: aio fixes for use after free and freeze protection Christoph Hellwig <hch@lst.de> - 2016-10-30 18:10 +0100
Re: aio fixes for use after free and freeze protection Christoph Hellwig <hch@lst.de> - 2016-11-09 03:50 +0100
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-10-30 17:50 +0100 |
| Subject | aio fixes for use after free and freeze protection |
| Message-ID | <sy1t0-78h-11@gated-at.bofh.it> |
Hi Linus, hi Al, below is the new version of the aio fix(es). Patch one just holds an additional file reference over AIO ops. This one is minimally invasive and a clear 4.9 and stable candidate. The next one drops the never implemented aio_fsync methods because it makes my life easier later on. No user visible change as we always ended up returning EINVAL anyway. Patch three refators the aio code so that it's not a spaghetti monster, and patch four is Jan's original free patch rebased on top of this whole stack.
[toc] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-10-30 17:50 +0100 |
| Subject | [PATCH 3/4] fs: remove aio_run_iocb |
| Message-ID | <sy1t0-78h-9@gated-at.bofh.it> |
| In reply to | #1512114 |
Pass the ABI iocb structure to aio_setup_rw and let it handle the
non-vectored I/O case as well. With that and a new helper for the AIO
return value handling we can now define new aio_read and aio_write
helpers that implement reads and writes in a self-contained way without
duplicating too much code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/aio.c | 182 +++++++++++++++++++++++++++++++++------------------------------
1 file changed, 94 insertions(+), 88 deletions(-)
diff --git a/fs/aio.c b/fs/aio.c
index 2a6030a..c197551 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1392,110 +1392,100 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
return -EINVAL;
}
-typedef ssize_t (rw_iter_op)(struct kiocb *, struct iov_iter *);
-
-static int aio_setup_vectored_rw(int rw, char __user *buf, size_t len,
- struct iovec **iovec,
- bool compat,
- struct iov_iter *iter)
+static int aio_setup_rw(int rw, struct iocb *iocb, struct iovec **iovec,
+ bool vectored, bool compat, struct iov_iter *iter)
{
+ void __user *buf = (void __user *)(uintptr_t)iocb->aio_buf;
+ size_t len = iocb->aio_nbytes;
+
+ if (!vectored) {
+ ssize_t ret = import_single_range(rw, buf, len, *iovec, iter);
+ *iovec = NULL;
+ return ret;
+ }
#ifdef CONFIG_COMPAT
if (compat)
- return compat_import_iovec(rw,
- (struct compat_iovec __user *)buf,
- len, UIO_FASTIOV, iovec, iter);
+ return compat_import_iovec(rw, buf, len, UIO_FASTIOV, iovec,
+ iter);
#endif
- return import_iovec(rw, (struct iovec __user *)buf,
- len, UIO_FASTIOV, iovec, iter);
+ return import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter);
}
-/*
- * aio_run_iocb:
- * Performs the initial checks and io submission.
- */
-static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
- char __user *buf, size_t len, bool compat)
+static inline ssize_t aio_ret(struct kiocb *req, ssize_t ret)
+{
+ switch (ret) {
+ case -EIOCBQUEUED:
+ return ret;
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ case -ERESTARTNOHAND:
+ case -ERESTART_RESTARTBLOCK:
+ /*
+ * There's no easy way to restart the syscall since other AIO's
+ * may be already running. Just fail this IO with EINTR.
+ */
+ ret = -EINTR;
+ /*FALLTHRU*/
+ default:
+ aio_complete(req, ret, 0);
+ return 0;
+ }
+}
+
+static ssize_t aio_read(struct kiocb *req, struct iocb *iocb, bool vectored,
+ bool compat)
{
struct file *file = req->ki_filp;
- ssize_t ret;
- int rw;
- fmode_t mode;
- rw_iter_op *iter_op;
struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
struct iov_iter iter;
+ ssize_t ret;
- switch (opcode) {
- case IOCB_CMD_PREAD:
- case IOCB_CMD_PREADV:
- mode = FMODE_READ;
- rw = READ;
- iter_op = file->f_op->read_iter;
- goto rw_common;
-
- case IOCB_CMD_PWRITE:
- case IOCB_CMD_PWRITEV:
- mode = FMODE_WRITE;
- rw = WRITE;
- iter_op = file->f_op->write_iter;
- goto rw_common;
-rw_common:
- if (unlikely(!(file->f_mode & mode)))
- return -EBADF;
-
- if (!iter_op)
- return -EINVAL;
-
- if (opcode == IOCB_CMD_PREADV || opcode == IOCB_CMD_PWRITEV)
- ret = aio_setup_vectored_rw(rw, buf, len,
- &iovec, compat, &iter);
- else {
- ret = import_single_range(rw, buf, len, iovec, &iter);
- iovec = NULL;
- }
- if (!ret)
- ret = rw_verify_area(rw, file, &req->ki_pos,
- iov_iter_count(&iter));
- if (ret < 0) {
- kfree(iovec);
- return ret;
- }
-
- get_file(file);
- if (rw == WRITE)
- file_start_write(file);
+ if (unlikely(!(file->f_mode & FMODE_READ)))
+ return -EBADF;
+ if (unlikely(!file->f_op->read_iter))
+ return -EINVAL;
- ret = iter_op(req, &iter);
+ ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter);
+ if (ret)
+ return ret;
+ ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter));
+ if (!ret)
+ ret = aio_ret(req, file->f_op->read_iter(req, &iter));
+ kfree(iovec);
+ return ret;
+}
- if (rw == WRITE)
- file_end_write(file);
- fput(file);
- kfree(iovec);
- break;
+static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored,
+ bool compat)
+{
+ struct file *file = req->ki_filp;
+ struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
+ struct iov_iter iter;
+ ssize_t ret;
- default:
- pr_debug("EINVAL: no operation provided\n");
+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
+ return -EBADF;
+ if (unlikely(!file->f_op->write_iter))
return -EINVAL;
- }
- if (ret != -EIOCBQUEUED) {
- /*
- * There's no easy way to restart the syscall since other AIO's
- * may be already running. Just fail this IO with EINTR.
- */
- if (unlikely(ret == -ERESTARTSYS || ret == -ERESTARTNOINTR ||
- ret == -ERESTARTNOHAND ||
- ret == -ERESTART_RESTARTBLOCK))
- ret = -EINTR;
- aio_complete(req, ret, 0);
+ ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter);
+ if (ret)
+ return ret;
+ ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter));
+ if (!ret) {
+ file_start_write(file);
+ ret = aio_ret(req, file->f_op->write_iter(req, &iter));
+ file_end_write(file);
}
-
- return 0;
+ kfree(iovec);
+ return ret;
}
static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
struct iocb *iocb, bool compat)
{
struct aio_kiocb *req;
+ struct file *file;
ssize_t ret;
/* enforce forwards compatibility on users */
@@ -1518,7 +1508,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
if (unlikely(!req))
return -EAGAIN;
- req->common.ki_filp = fget(iocb->aio_fildes);
+ req->common.ki_filp = file = fget(iocb->aio_fildes);
if (unlikely(!req->common.ki_filp)) {
ret = -EBADF;
goto out_put_req;
@@ -1553,13 +1543,29 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
req->ki_user_iocb = user_iocb;
req->ki_user_data = iocb->aio_data;
- ret = aio_run_iocb(&req->common, iocb->aio_lio_opcode,
- (char __user *)(unsigned long)iocb->aio_buf,
- iocb->aio_nbytes,
- compat);
- if (ret)
- goto out_put_req;
+ get_file(file);
+ switch (iocb->aio_lio_opcode) {
+ case IOCB_CMD_PREAD:
+ ret = aio_read(&req->common, iocb, false, compat);
+ break;
+ case IOCB_CMD_PWRITE:
+ ret = aio_write(&req->common, iocb, false, compat);
+ break;
+ case IOCB_CMD_PREADV:
+ ret = aio_read(&req->common, iocb, true, compat);
+ break;
+ case IOCB_CMD_PWRITEV:
+ ret = aio_write(&req->common, iocb, true, compat);
+ break;
+ default:
+ pr_debug("invalid aio operation %d\n", iocb->aio_lio_opcode);
+ ret = -EINVAL;
+ break;
+ }
+ fput(file);
+ if (ret && ret != -EIOCBQUEUED)
+ goto out_put_req;
return 0;
out_put_req:
put_reqs_available(ctx, 1);
--
2.1.4
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-10-30 17:50 +0100 |
| Subject | [PATCH 1/4] aio: hold an extra file reference over AIO read/write operations |
| Message-ID | <sy1t0-78h-15@gated-at.bofh.it> |
| In reply to | #1512114 |
Otherwise we might dereference an already freed file and/or inode when aio_complete is called before we return from the read_iter or write_iter method. Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/aio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/aio.c b/fs/aio.c index 1157e13..0aa71d3 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1460,6 +1460,7 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, return ret; } + get_file(file); if (rw == WRITE) file_start_write(file); @@ -1467,6 +1468,7 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, if (rw == WRITE) file_end_write(file); + fput(file); kfree(iovec); break; -- 2.1.4
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-10-30 17:50 +0100 |
| Subject | [PATCH 4/4] aio: fix freeze protection of aio writes |
| Message-ID | <sy1t0-78h-25@gated-at.bofh.it> |
| In reply to | #1512114 |
Currently we dropped freeze protection of aio writes just after IO was
submitted. Thus aio write could be in flight while the filesystem was
frozen and that could result in unexpected situation like aio completion
wanting to convert extent type on frozen filesystem. Testcase from
Dmitry triggering this is like:
for ((i=0;i<60;i++));do fsfreeze -f /mnt ;sleep 1;fsfreeze -u /mnt;done &
fio --bs=4k --ioengine=libaio --iodepth=128 --size=1g --direct=1 \
--runtime=60 --filename=/mnt/file --name=rand-write --rw=randwrite
Fix the problem by dropping freeze protection only once IO is completed
in aio_complete().
Reported-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Jan Kara <jack@suse.cz>
[hch: forward ported on top of various VFS and aio changes]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/aio.c | 19 ++++++++++++++++++-
include/linux/fs.h | 1 +
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/fs/aio.c b/fs/aio.c
index c197551..428484f 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1078,6 +1078,17 @@ static void aio_complete(struct kiocb *kiocb, long res, long res2)
unsigned tail, pos, head;
unsigned long flags;
+ if (kiocb->ki_flags & IOCB_WRITE) {
+ struct file *file = kiocb->ki_filp;
+
+ /*
+ * Tell lockdep we inherited freeze protection from submission
+ * thread.
+ */
+ __sb_writers_acquired(file_inode(file)->i_sb, SB_FREEZE_WRITE);
+ file_end_write(file);
+ }
+
/*
* Special case handling for sync iocbs:
* - events go directly into the iocb for fast handling
@@ -1473,9 +1484,15 @@ static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored,
return ret;
ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter));
if (!ret) {
+ req->ki_flags |= IOCB_WRITE;
file_start_write(file);
ret = aio_ret(req, file->f_op->write_iter(req, &iter));
- file_end_write(file);
+ /*
+ * We release freeze protection in aio_complete(). Fool lockdep
+ * by telling it the lock got released so that it doesn't
+ * complain about held lock when we return to userspace.
+ */
+ __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE);
}
kfree(iovec);
return ret;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ff7bcd9..dc0478c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -321,6 +321,7 @@ struct writeback_control;
#define IOCB_HIPRI (1 << 3)
#define IOCB_DSYNC (1 << 4)
#define IOCB_SYNC (1 << 5)
+#define IOCB_WRITE (1 << 6)
struct kiocb {
struct file *ki_filp;
--
2.1.4
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-10-30 17:50 +0100 |
| Subject | [PATCH 2/4] fs: remove the never implemented aio_fsync file operation |
| Message-ID | <sy1t0-78h-31@gated-at.bofh.it> |
| In reply to | #1512114 |
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
Documentation/filesystems/Locking | 1 -
Documentation/filesystems/vfs.txt | 1 -
fs/aio.c | 14 --------------
fs/ntfs/dir.c | 2 --
include/linux/fs.h | 1 -
5 files changed, 19 deletions(-)
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 14cdc10..1b5f156 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -447,7 +447,6 @@ prototypes:
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t start, loff_t end, int datasync);
- int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index d619c8d..b5039a0 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -828,7 +828,6 @@ struct file_operations {
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
- int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
diff --git a/fs/aio.c b/fs/aio.c
index 0aa71d3..2a6030a 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1472,20 +1472,6 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
kfree(iovec);
break;
- case IOCB_CMD_FDSYNC:
- if (!file->f_op->aio_fsync)
- return -EINVAL;
-
- ret = file->f_op->aio_fsync(req, 1);
- break;
-
- case IOCB_CMD_FSYNC:
- if (!file->f_op->aio_fsync)
- return -EINVAL;
-
- ret = file->f_op->aio_fsync(req, 0);
- break;
-
default:
pr_debug("EINVAL: no operation provided\n");
return -EINVAL;
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index a186135..0ee19ec 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1544,8 +1544,6 @@ const struct file_operations ntfs_dir_ops = {
.iterate = ntfs_readdir, /* Read directory contents. */
#ifdef NTFS_RW
.fsync = ntfs_dir_fsync, /* Sync a directory to disk. */
- /*.aio_fsync = ,*/ /* Sync all outstanding async
- i/o operations on a kiocb. */
#endif /* NTFS_RW */
/*.ioctl = ,*/ /* Perform function on the
mounted filesystem. */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 16d2b6e..ff7bcd9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1709,7 +1709,6 @@ struct file_operations {
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
- int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
--
2.1.4
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2016-10-31 00:30 +0100 |
| Subject | Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation |
| Message-ID | <sy7I5-2Mi-5@gated-at.bofh.it> |
| In reply to | #1512124 |
On Sun, Oct 30, 2016 at 11:42:02AM -0500, Christoph Hellwig wrote: > Signed-off-by: Christoph Hellwig <hch@lst.de> This doesn't belong in this patchset. Regardless, can we just implement the damned thing rather than removing it? Plenty of people have asked for it and they still want this functionality. I've sent a couple of different prototypes that worked but got bikeshedded to death, and IIRC Ben also tried to get it implemented but that went nowhere because other parts of his patchset got bikeshedded to death. If nothing else, just let me implement it in XFS like I did the first time so when all the bikshedding stops we can convert it to the One True AIO Interface that is decided on. Cheers, Dave. -- Dave Chinner david@fromorbit.com
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-10-31 14:10 +0100 |
| Subject | Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation |
| Message-ID | <sykvE-2PE-31@gated-at.bofh.it> |
| In reply to | #1512236 |
On Mon, Oct 31, 2016 at 10:23:31AM +1100, Dave Chinner wrote: > This doesn't belong in this patchset. It does. I can't fix up the calling conventions for a methods that was never implemented. > Regardless, can we just implement the damned thing rather than > removing it? Plenty of people have asked for it and they still want > this functionality. I've sent a couple of different prototypes that > worked but got bikeshedded to death, and IIRC Ben also tried to get > it implemented but that went nowhere because other parts of his > patchset got bikeshedded to death. > > If nothing else, just let me implement it in XFS like I did the > first time so when all the bikshedding stops we can convert it to > the One True AIO Interface that is decided on. I'm not going to complain about a proper implementation, but right now we don't have any, and I'm not even sure the method signature is all that suitable. E.g. for the in-kernel users we'd really want a ranged fsync like the normal fsync anyway.
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2016-10-31 21:30 +0100 |
| Subject | Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation |
| Message-ID | <syrns-7fi-37@gated-at.bofh.it> |
| In reply to | #1512549 |
On Mon, Oct 31, 2016 at 02:07:54PM +0100, Christoph Hellwig wrote: > On Mon, Oct 31, 2016 at 10:23:31AM +1100, Dave Chinner wrote: > > This doesn't belong in this patchset. > > It does. I can't fix up the calling conventions for a methods that > was never implemented. That sounds like a problem with your fix - it should work regardless of whether a valid/implemented AIO function is called or not, right? There's no difference between an invalid command, IOCB_CMD_FSYNC where ->aio_fsync() is null, or some supported command that immediately returns -EIO, the end result should be the same... > > Regardless, can we just implement the damned thing rather than > > removing it? Plenty of people have asked for it and they still want > > this functionality. I've sent a couple of different prototypes that > > worked but got bikeshedded to death, and IIRC Ben also tried to get > > it implemented but that went nowhere because other parts of his > > patchset got bikeshedded to death. > > > > If nothing else, just let me implement it in XFS like I did the > > first time so when all the bikshedding stops we can convert it to > > the One True AIO Interface that is decided on. > > I'm not going to complain about a proper implementation, but right now > we don't have any, and I'm not even sure the method signature is > all that suitable. E.g. for the in-kernel users we'd really want a > ranged fsync like the normal fsync anyway. You mean like this version I posted a year ago: https://lkml.org/lkml/2015/10/29/517 Cheers, Dave. -- Dave Chinner david@fromorbit.com
[toc] | [prev] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2016-11-01 02:40 +0100 |
| Subject | Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation |
| Message-ID | <sywds-1Rv-21@gated-at.bofh.it> |
| In reply to | #1512862 |
On Mon, Oct 31, 2016 at 1:25 PM, Dave Chinner <david@fromorbit.com> wrote:
>
> You mean like this version I posted a year ago:
>
> https://lkml.org/lkml/2015/10/29/517
I still suspect that if we want to do this, we should strive to expose
all the other syncing flags from sync_file_range() too.
Not everybody wants to do just synchronous syncs. Especially if you're
doing async work, you might well want to have one async operation to
*start* the writeback on a range, then do something else, and then do
one to wait for the sync to actually have succeeded.
Yeah, that's more of a "keep writes streaming" interface than a
fsync() like interface, but I think the two really do fit together.
It's kind of sad how we have this very fragmented interface to
writeback, where some operations take that "data vs metadata", some
operations take a range of bytes, and some operations take that "start
writeback vs wait for it", but nothing does all of the above. They are
really just different faces of the same writeback coin.
Linus
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-11-01 15:40 +0100 |
| Subject | Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation |
| Message-ID | <syIoi-1st-9@gated-at.bofh.it> |
| In reply to | #1513039 |
On Mon, Oct 31, 2016 at 06:30:11PM -0700, Linus Torvalds wrote: > I still suspect that if we want to do this, we should strive to expose > all the other syncing flags from sync_file_range() too. sync_file_range is entirely different from fsync - sync_file_range allows you detailed control of data writeback, but it does not allow to commit metadata at all, i.e. it's not a data integrity operation. > Yeah, that's more of a "keep writes streaming" interface than a > fsync() like interface, but I think the two really do fit together. > It's kind of sad how we have this very fragmented interface to > writeback, where some operations take that "data vs metadata", some > operations take a range of bytes, and some operations take that "start > writeback vs wait for it", but nothing does all of the above. They are > really just different faces of the same writeback coin. sync_file_range at the moment actually doesn't involve the fs, which has it's own set of problems. So yes, maybe we need a full blown sync method unifying fsync, sync_file_range and which enables ranged data integrity fsync and asynchronous operations of all this. But to go back to Dave's argument - none of that can archived with that aio_fsync method added more than 10 years ago and never implemented.
[toc] | [prev] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2016-11-01 16:10 +0100 |
| Subject | Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation |
| Message-ID | <syIRj-1Tk-9@gated-at.bofh.it> |
| In reply to | #1513293 |
On Tue, Nov 1, 2016 at 7:30 AM, Christoph Hellwig <hch@lst.de> wrote:
>
> sync_file_range is entirely different from fsync -
Absolutely.
And I think it's a shame. Particularly the fact that we don't have any
way to actually tie into the filesystem, and we just work on the page
cache level, which "mostly works" for writeback, but is really not
right. It's not like a filesystem even has to work on that level at
all..
> sync_file_range at the moment actually doesn't involve the fs, which
> has it's own set of problems. So yes, maybe we need a full blown
> sync method unifying fsync, sync_file_range and which enables ranged
> data integrity fsync and asynchronous operations of all this.
I *think* we could just expand the existing filesystem "f_op->fsync()"
interface to take more than just the single-bit argument, and have the
full interface.
But being Linux-only, it sadly will never get much use. Even if the
other flags really are very useful for getting overlapping streaming
writes with minimal dirty state. It might be more productive to have
some easier-to-use interface to some generic writebehind logic, but..
> But to go back to Dave's argument - none of that can archived with that
> aio_fsync method added more than 10 years ago and never implemented.
Yeah, no, I actually agree with just removing that. I think we are
often much too slow to just say "nobody uses it, get rid of it". Even
if it were to ever be needed in the future, we could just resurrect
it, but it's not clear that it would ever be in that particular form.
Linus
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-11-01 15:30 +0100 |
| Subject | Re: [PATCH 2/4] fs: remove the never implemented aio_fsync file operation |
| Message-ID | <syIeC-1oI-15@gated-at.bofh.it> |
| In reply to | #1512862 |
On Tue, Nov 01, 2016 at 07:25:21AM +1100, Dave Chinner wrote: > That sounds like a problem with your fix - it should work > regardless of whether a valid/implemented AIO function is called > or not, right? There's no difference between an invalid command, > IOCB_CMD_FSYNC where ->aio_fsync() is null, or some supported > command that immediately returns -EIO, the end result should > be the same... We would need the same increased file refcount if aio_fsync actually was implemented using -EIOCBQUEUED returns. We wouldn't nessecarily need it without that. > > I'm not going to complain about a proper implementation, but right now > > we don't have any, and I'm not even sure the method signature is > > all that suitable. E.g. for the in-kernel users we'd really want a > > ranged fsync like the normal fsync anyway. > > You mean like this version I posted a year ago: > > https://lkml.org/lkml/2015/10/29/517 I'd love to see that one in - but it doesn't use the aio_fsync method either..
[toc] | [prev] | [next] | [standalone]
| From | Al Viro <viro@ZenIV.linux.org.uk> |
|---|---|
| Date | 2016-10-30 18:00 +0100 |
| Message-ID | <sy1CG-7bz-39@gated-at.bofh.it> |
| In reply to | #1512114 |
On Sun, Oct 30, 2016 at 11:42:00AM -0500, Christoph Hellwig wrote: > Hi Linus, hi Al, > > below is the new version of the aio fix(es). > > Patch one just holds an additional file reference over AIO ops. This > one is minimally invasive and a clear 4.9 and stable candidate. > > The next one drops the never implemented aio_fsync methods because it > makes my life easier later on. No user visible change as we always > ended up returning EINVAL anyway. > > Patch three refators the aio code so that it's not a spaghetti monster, > and patch four is Jan's original free patch rebased on top of this whole > stack. Applied.
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-10-30 18:10 +0100 |
| Message-ID | <sy1Mm-7uo-1@gated-at.bofh.it> |
| In reply to | #1512144 |
Btw, patch 4 should be attributed to Jan - for some reason git keeps resetting the attribution whenever there is a conflict during a rebase.
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2016-11-09 03:50 +0100 |
| Message-ID | <sBr7z-1fj-5@gated-at.bofh.it> |
| In reply to | #1512144 |
Al, did you get a chance to send this series (or at very least patch 1 which is the most critical) to Linus? I'd hate to miss another rc for the use after free fix.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web