All of lore.kernel.org
 help / color / mirror / Atom feed
* preadv2/pwritev2 updates
@ 2014-10-01 21:04 ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-01 21:04 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

Hi Miklos,

attached are the patches that go on top of your
"[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
series.  The first one adds RWF_NONBLOCK to XFS, the other two
add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* preadv2/pwritev2 updates
@ 2014-10-01 21:04 ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-01 21:04 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

Hi Miklos,

attached are the patches that go on top of your
"[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
series.  The first one adds RWF_NONBLOCK to XFS, the other two
add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/3] xfs: add RWF_NONBLOCK support
  2014-10-01 21:04 ` Christoph Hellwig
@ 2014-10-01 21:04   ` Christoph Hellwig
  -1 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-01 21:04 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

Add support for non-blocking reads.  The guts are handled by the generic
code, the only addition is a non-blocking variant of xfs_rw_ilock.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_file.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index cf61271..f9efffc 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -61,6 +61,23 @@ xfs_rw_ilock(
 	xfs_ilock(ip, type);
 }
 
+static inline bool
+xfs_rw_ilock_nowait(
+	struct xfs_inode	*ip,
+	int			type)
+{
+	if (type & XFS_IOLOCK_EXCL) {
+		if (!mutex_trylock(&VFS_I(ip)->i_mutex))
+			return false;
+	}
+	if (!xfs_ilock_nowait(ip, type)) {
+		mutex_unlock(&VFS_I(ip)->i_mutex);
+		return false;
+	}
+
+	return true;
+}
+
 static inline void
 xfs_rw_iunlock(
 	struct xfs_inode	*ip,
@@ -246,10 +263,6 @@ xfs_file_read_iter(
 
 	XFS_STATS_INC(xs_read_calls);
 
-	/* XXX: need a non-blocking iolock helper, shouldn't be too hard */
-	if (iocb->ki_rwflags & RWF_NONBLOCK)
-		return -EAGAIN;
-
 	if (unlikely(file->f_flags & O_DIRECT))
 		ioflags |= XFS_IO_ISDIRECT;
 	if (file->f_mode & FMODE_NOCMTIME)
@@ -287,7 +300,14 @@ xfs_file_read_iter(
 	 * This allows the normal direct IO case of no page cache pages to
 	 * proceeed concurrently without serialisation.
 	 */
-	xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
+	if (iocb->ki_rwflags & RWF_NONBLOCK) {
+		if (ioflags & XFS_IO_ISDIRECT)
+			return -EAGAIN;
+		if (!xfs_rw_ilock_nowait(ip, XFS_IOLOCK_SHARED))
+			return -EAGAIN;
+	} else {
+		xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
+	}
 	if ((ioflags & XFS_IO_ISDIRECT) && inode->i_mapping->nrpages) {
 		xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
 		xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 1/3] xfs: add RWF_NONBLOCK support
@ 2014-10-01 21:04   ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-01 21:04 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

Add support for non-blocking reads.  The guts are handled by the generic
code, the only addition is a non-blocking variant of xfs_rw_ilock.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_file.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index cf61271..f9efffc 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -61,6 +61,23 @@ xfs_rw_ilock(
 	xfs_ilock(ip, type);
 }
 
+static inline bool
+xfs_rw_ilock_nowait(
+	struct xfs_inode	*ip,
+	int			type)
+{
+	if (type & XFS_IOLOCK_EXCL) {
+		if (!mutex_trylock(&VFS_I(ip)->i_mutex))
+			return false;
+	}
+	if (!xfs_ilock_nowait(ip, type)) {
+		mutex_unlock(&VFS_I(ip)->i_mutex);
+		return false;
+	}
+
+	return true;
+}
+
 static inline void
 xfs_rw_iunlock(
 	struct xfs_inode	*ip,
@@ -246,10 +263,6 @@ xfs_file_read_iter(
 
 	XFS_STATS_INC(xs_read_calls);
 
-	/* XXX: need a non-blocking iolock helper, shouldn't be too hard */
-	if (iocb->ki_rwflags & RWF_NONBLOCK)
-		return -EAGAIN;
-
 	if (unlikely(file->f_flags & O_DIRECT))
 		ioflags |= XFS_IO_ISDIRECT;
 	if (file->f_mode & FMODE_NOCMTIME)
@@ -287,7 +300,14 @@ xfs_file_read_iter(
 	 * This allows the normal direct IO case of no page cache pages to
 	 * proceeed concurrently without serialisation.
 	 */
-	xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
+	if (iocb->ki_rwflags & RWF_NONBLOCK) {
+		if (ioflags & XFS_IO_ISDIRECT)
+			return -EAGAIN;
+		if (!xfs_rw_ilock_nowait(ip, XFS_IOLOCK_SHARED))
+			return -EAGAIN;
+	} else {
+		xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
+	}
 	if ((ioflags & XFS_IO_ISDIRECT) && inode->i_mapping->nrpages) {
 		xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
 		xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);
-- 
1.9.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/3] fs: pass iocb to generic_write_sync
  2014-10-01 21:04 ` Christoph Hellwig
@ 2014-10-01 21:04   ` Christoph Hellwig
  -1 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-01 21:04 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

Clean up the generic_write_sync by just passing an iocb and a bytes
written / negative errno argument.  In addition to simplifying the
callers this also prepares for passing a per-operation O_DSYNC
flag.  Two callers didn't quite fit that scheme:

 - dio_complete didn't both to update ki_pos as we don't need it
   on a iocb that is about to be freed, so we had to add it. Additionally
   it also synced out written data in the error case, which has been
   changed to operate like the other callers.
 - gfs2 also used generic_write_sync to implement a crude version
   of fallocate.  It has been switched to use an open coded variant
   instead.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/block_dev.c     |  8 +-------
 fs/btrfs/file.c    |  7 ++-----
 fs/cifs/file.c     |  8 +-------
 fs/direct-io.c     |  8 ++------
 fs/ext4/file.c     |  8 +-------
 fs/gfs2/file.c     |  9 +++++++--
 fs/ntfs/file.c     |  8 ++------
 fs/udf/file.c      | 11 ++---------
 fs/xfs/xfs_file.c  |  8 +-------
 include/linux/fs.h |  8 +-------
 mm/filemap.c       | 30 ++++++++++++++++++++----------
 11 files changed, 40 insertions(+), 73 deletions(-)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 6d72746..79ed323 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1574,18 +1574,12 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  */
 ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
-	struct file *file = iocb->ki_filp;
 	struct blk_plug plug;
 	ssize_t ret;
 
 	blk_start_plug(&plug);
 	ret = __generic_file_write_iter(iocb, from);
-	if (ret > 0) {
-		ssize_t err;
-		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
-	}
+	ret = generic_write_sync(iocb, ret);
 	blk_finish_plug(&plug);
 	return ret;
 }
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index ff1cc03..e77f599 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1823,11 +1823,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
 	 */
 	BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
 	BTRFS_I(inode)->last_sub_trans = root->log_transid;
-	if (num_written > 0) {
-		err = generic_write_sync(file, pos, num_written);
-		if (err < 0)
-			num_written = err;
-	}
+
+	num_written = generic_write_sync(iocb, num_written);
 
 	if (sync)
 		atomic_dec(&BTRFS_I(inode)->sync_writers);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e7169ba..2dca0da 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2706,13 +2706,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
 		rc = __generic_file_write_iter(iocb, from);
 		mutex_unlock(&inode->i_mutex);
 
-		if (rc > 0) {
-			ssize_t err;
-
-			err = generic_write_sync(file, iocb->ki_pos - rc, rc);
-			if (err < 0)
-				rc = err;
-		}
+		rc = generic_write_sync(iocb, rc);
 	} else {
 		mutex_unlock(&inode->i_mutex);
 	}
diff --git a/fs/direct-io.c b/fs/direct-io.c
index e181b6b..b72ac83 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -257,12 +257,8 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret,
 	inode_dio_done(dio->inode);
 	if (is_async) {
 		if (dio->rw & WRITE) {
-			int err;
-
-			err = generic_write_sync(dio->iocb->ki_filp, offset,
-						 transferred);
-			if (err < 0 && ret > 0)
-				ret = err;
+			dio->iocb->ki_pos = offset + transferred;
+			ret = generic_write_sync(dio->iocb, ret);
 		}
 
 		aio_complete(dio->iocb, ret, 0);
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index aca7b24..79b000c 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -175,13 +175,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	ret = __generic_file_write_iter(iocb, from);
 	mutex_unlock(&inode->i_mutex);
 
-	if (ret > 0) {
-		ssize_t err;
-
-		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
-	}
+	ret = generic_write_sync(iocb, ret);
 	if (o_direct)
 		blk_finish_plug(&plug);
 
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 7f4ed3d..34e3d36 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -895,8 +895,13 @@ retry:
 		gfs2_quota_unlock(ip);
 	}
 
-	if (error == 0)
-		error = generic_write_sync(file, pos, count);
+	if (error)
+		goto out_unlock;
+
+	if ((file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host)) {
+		error = vfs_fsync_range(file, pos, pos + count - 1,
+			       (file->f_flags & __O_SYNC) ? 0 : 1);
+	}
 	goto out_unlock;
 
 out_trans_fail:
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index f5ec1ce..eaf2ce6 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2126,12 +2126,8 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 	mutex_lock(&inode->i_mutex);
 	ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
-	if (ret > 0) {
-		int err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
-	}
-	return ret;
+
+	return generic_write_sync(iocb, ret);
 }
 
 /**
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 86c6743..9fe6bb1 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -155,16 +155,9 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	retval = __generic_file_write_iter(iocb, from);
 	mutex_unlock(&inode->i_mutex);
 
-	if (retval > 0) {
-		ssize_t err;
-
+	if (retval > 0)
 		mark_inode_dirty(inode);
-		err = generic_write_sync(file, iocb->ki_pos - retval, retval);
-		if (err < 0)
-			retval = err;
-	}
-
-	return retval;
+	return generic_write_sync(iocb, retval);
 }
 
 long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index f9efffc..986965a 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -790,14 +790,8 @@ xfs_file_write_iter(
 		ret = xfs_file_buffered_aio_write(iocb, from);
 
 	if (ret > 0) {
-		ssize_t err;
-
 		XFS_STATS_ADD(xs_write_bytes, ret);
-
-		/* Handle various SYNC-type writes */
-		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
+		ret = generic_write_sync(iocb, ret);
 	}
 	return ret;
 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b884975..cf759fa 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2259,13 +2259,7 @@ extern int filemap_fdatawrite_range(struct address_space *mapping,
 extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
 			   int datasync);
 extern int vfs_fsync(struct file *file, int datasync);
-static inline int generic_write_sync(struct file *file, loff_t pos, loff_t count)
-{
-	if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host))
-		return 0;
-	return vfs_fsync_range(file, pos, pos + count - 1,
-			       (file->f_flags & __O_SYNC) ? 0 : 1);
-}
+extern int generic_write_sync(struct kiocb *iocb, loff_t count);
 extern void emergency_sync(void);
 extern void emergency_remount(void);
 #ifdef CONFIG_BLOCK
diff --git a/mm/filemap.c b/mm/filemap.c
index 86ed6f7..f9ffb6f 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2654,6 +2654,24 @@ out:
 }
 EXPORT_SYMBOL(__generic_file_write_iter);
 
+int generic_write_sync(struct kiocb *iocb, loff_t count)
+{
+	struct file *file = iocb->ki_filp;
+
+	if (count > 0 &&
+	    ((file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host))) {
+	    	bool fdatasync = !(file->f_flags & __O_SYNC);
+		ssize_t ret = 0;
+
+		ret = vfs_fsync_range(file, iocb->ki_pos - count,
+				iocb->ki_pos - 1, fdatasync);
+		if (ret < 0)
+			return ret;
+	}
+	return count;
+}
+EXPORT_SYMBOL(generic_write_sync);
+
 /**
  * generic_file_write_iter - write data to a file
  * @iocb:	IO state structure
@@ -2665,22 +2683,14 @@ EXPORT_SYMBOL(__generic_file_write_iter);
  */
 ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
-	struct file *file = iocb->ki_filp;
-	struct inode *inode = file->f_mapping->host;
+	struct inode *inode = iocb->ki_filp->f_mapping->host;
 	ssize_t ret;
 
 	mutex_lock(&inode->i_mutex);
 	ret = __generic_file_write_iter(iocb, from);
 	mutex_unlock(&inode->i_mutex);
 
-	if (ret > 0) {
-		ssize_t err;
-
-		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
-	}
-	return ret;
+	return generic_write_sync(iocb, ret);
 }
 EXPORT_SYMBOL(generic_file_write_iter);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/3] fs: pass iocb to generic_write_sync
@ 2014-10-01 21:04   ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-01 21:04 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

Clean up the generic_write_sync by just passing an iocb and a bytes
written / negative errno argument.  In addition to simplifying the
callers this also prepares for passing a per-operation O_DSYNC
flag.  Two callers didn't quite fit that scheme:

 - dio_complete didn't both to update ki_pos as we don't need it
   on a iocb that is about to be freed, so we had to add it. Additionally
   it also synced out written data in the error case, which has been
   changed to operate like the other callers.
 - gfs2 also used generic_write_sync to implement a crude version
   of fallocate.  It has been switched to use an open coded variant
   instead.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/block_dev.c     |  8 +-------
 fs/btrfs/file.c    |  7 ++-----
 fs/cifs/file.c     |  8 +-------
 fs/direct-io.c     |  8 ++------
 fs/ext4/file.c     |  8 +-------
 fs/gfs2/file.c     |  9 +++++++--
 fs/ntfs/file.c     |  8 ++------
 fs/udf/file.c      | 11 ++---------
 fs/xfs/xfs_file.c  |  8 +-------
 include/linux/fs.h |  8 +-------
 mm/filemap.c       | 30 ++++++++++++++++++++----------
 11 files changed, 40 insertions(+), 73 deletions(-)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 6d72746..79ed323 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1574,18 +1574,12 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  */
 ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
-	struct file *file = iocb->ki_filp;
 	struct blk_plug plug;
 	ssize_t ret;
 
 	blk_start_plug(&plug);
 	ret = __generic_file_write_iter(iocb, from);
-	if (ret > 0) {
-		ssize_t err;
-		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
-	}
+	ret = generic_write_sync(iocb, ret);
 	blk_finish_plug(&plug);
 	return ret;
 }
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index ff1cc03..e77f599 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1823,11 +1823,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
 	 */
 	BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
 	BTRFS_I(inode)->last_sub_trans = root->log_transid;
-	if (num_written > 0) {
-		err = generic_write_sync(file, pos, num_written);
-		if (err < 0)
-			num_written = err;
-	}
+
+	num_written = generic_write_sync(iocb, num_written);
 
 	if (sync)
 		atomic_dec(&BTRFS_I(inode)->sync_writers);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e7169ba..2dca0da 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2706,13 +2706,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
 		rc = __generic_file_write_iter(iocb, from);
 		mutex_unlock(&inode->i_mutex);
 
-		if (rc > 0) {
-			ssize_t err;
-
-			err = generic_write_sync(file, iocb->ki_pos - rc, rc);
-			if (err < 0)
-				rc = err;
-		}
+		rc = generic_write_sync(iocb, rc);
 	} else {
 		mutex_unlock(&inode->i_mutex);
 	}
diff --git a/fs/direct-io.c b/fs/direct-io.c
index e181b6b..b72ac83 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -257,12 +257,8 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret,
 	inode_dio_done(dio->inode);
 	if (is_async) {
 		if (dio->rw & WRITE) {
-			int err;
-
-			err = generic_write_sync(dio->iocb->ki_filp, offset,
-						 transferred);
-			if (err < 0 && ret > 0)
-				ret = err;
+			dio->iocb->ki_pos = offset + transferred;
+			ret = generic_write_sync(dio->iocb, ret);
 		}
 
 		aio_complete(dio->iocb, ret, 0);
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index aca7b24..79b000c 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -175,13 +175,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	ret = __generic_file_write_iter(iocb, from);
 	mutex_unlock(&inode->i_mutex);
 
-	if (ret > 0) {
-		ssize_t err;
-
-		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
-	}
+	ret = generic_write_sync(iocb, ret);
 	if (o_direct)
 		blk_finish_plug(&plug);
 
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 7f4ed3d..34e3d36 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -895,8 +895,13 @@ retry:
 		gfs2_quota_unlock(ip);
 	}
 
-	if (error == 0)
-		error = generic_write_sync(file, pos, count);
+	if (error)
+		goto out_unlock;
+
+	if ((file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host)) {
+		error = vfs_fsync_range(file, pos, pos + count - 1,
+			       (file->f_flags & __O_SYNC) ? 0 : 1);
+	}
 	goto out_unlock;
 
 out_trans_fail:
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index f5ec1ce..eaf2ce6 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2126,12 +2126,8 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 	mutex_lock(&inode->i_mutex);
 	ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
-	if (ret > 0) {
-		int err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
-	}
-	return ret;
+
+	return generic_write_sync(iocb, ret);
 }
 
 /**
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 86c6743..9fe6bb1 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -155,16 +155,9 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	retval = __generic_file_write_iter(iocb, from);
 	mutex_unlock(&inode->i_mutex);
 
-	if (retval > 0) {
-		ssize_t err;
-
+	if (retval > 0)
 		mark_inode_dirty(inode);
-		err = generic_write_sync(file, iocb->ki_pos - retval, retval);
-		if (err < 0)
-			retval = err;
-	}
-
-	return retval;
+	return generic_write_sync(iocb, retval);
 }
 
 long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index f9efffc..986965a 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -790,14 +790,8 @@ xfs_file_write_iter(
 		ret = xfs_file_buffered_aio_write(iocb, from);
 
 	if (ret > 0) {
-		ssize_t err;
-
 		XFS_STATS_ADD(xs_write_bytes, ret);
-
-		/* Handle various SYNC-type writes */
-		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
+		ret = generic_write_sync(iocb, ret);
 	}
 	return ret;
 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b884975..cf759fa 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2259,13 +2259,7 @@ extern int filemap_fdatawrite_range(struct address_space *mapping,
 extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
 			   int datasync);
 extern int vfs_fsync(struct file *file, int datasync);
-static inline int generic_write_sync(struct file *file, loff_t pos, loff_t count)
-{
-	if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host))
-		return 0;
-	return vfs_fsync_range(file, pos, pos + count - 1,
-			       (file->f_flags & __O_SYNC) ? 0 : 1);
-}
+extern int generic_write_sync(struct kiocb *iocb, loff_t count);
 extern void emergency_sync(void);
 extern void emergency_remount(void);
 #ifdef CONFIG_BLOCK
diff --git a/mm/filemap.c b/mm/filemap.c
index 86ed6f7..f9ffb6f 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2654,6 +2654,24 @@ out:
 }
 EXPORT_SYMBOL(__generic_file_write_iter);
 
+int generic_write_sync(struct kiocb *iocb, loff_t count)
+{
+	struct file *file = iocb->ki_filp;
+
+	if (count > 0 &&
+	    ((file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host))) {
+	    	bool fdatasync = !(file->f_flags & __O_SYNC);
+		ssize_t ret = 0;
+
+		ret = vfs_fsync_range(file, iocb->ki_pos - count,
+				iocb->ki_pos - 1, fdatasync);
+		if (ret < 0)
+			return ret;
+	}
+	return count;
+}
+EXPORT_SYMBOL(generic_write_sync);
+
 /**
  * generic_file_write_iter - write data to a file
  * @iocb:	IO state structure
@@ -2665,22 +2683,14 @@ EXPORT_SYMBOL(__generic_file_write_iter);
  */
 ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
-	struct file *file = iocb->ki_filp;
-	struct inode *inode = file->f_mapping->host;
+	struct inode *inode = iocb->ki_filp->f_mapping->host;
 	ssize_t ret;
 
 	mutex_lock(&inode->i_mutex);
 	ret = __generic_file_write_iter(iocb, from);
 	mutex_unlock(&inode->i_mutex);
 
-	if (ret > 0) {
-		ssize_t err;
-
-		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
-		if (err < 0)
-			ret = err;
-	}
-	return ret;
+	return generic_write_sync(iocb, ret);
 }
 EXPORT_SYMBOL(generic_file_write_iter);
 
-- 
1.9.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/3] fs: add a flag for per-operation O_DSYNC semantics
  2014-10-01 21:04 ` Christoph Hellwig
@ 2014-10-01 21:04   ` Christoph Hellwig
  -1 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-01 21:04 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

With the new read/write with flags syscalls we can support a flag
to enable O_DSYNC semantics on a per-operation basis.  This іs
useful to implement protocols like SMB, NFS or SCSI that have such
per-operation flags.

Example program below:

cat > pwritev2.c << EOF

        (off_t) val,                              \
        (off_t) ((((uint64_t) (val)) >> (sizeof (long) * 4)) >> (sizeof (long) * 4))

static ssize_t
pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags)
{
        return syscall(__NR_pwritev2, fd, iov, iovcnt, LO_HI_LONG(offset),
			 flags);
}

int main(int argc, char **argv)
{
	int fd = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0666);
	char buf[1024];
	struct iovec iov = { .iov_base = buf, .iov_len = 1024 };
	int ret;

        if (fd < 0) {
                perror("open");
                return 0;
        }

	memset(buf, 0xfe, sizeof(buf));

	ret = pwritev2(fd, &iov, 1, 0, RWF_DSYNC);
	if (ret < 0)
		perror("pwritev2");
	else
		printf("ret = %d\n", ret);

	return 0;
}
EOF

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/ceph/file.c     |  4 +++-
 fs/fuse/file.c     |  2 ++
 fs/nfs/file.c      | 10 ++++++----
 fs/ocfs2/file.c    |  6 ++++--
 fs/read_write.c    | 11 ++++++++---
 include/linux/fs.h |  3 ++-
 mm/filemap.c       |  4 +++-
 7 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 2eb02f8..e59f1f1 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -968,7 +968,9 @@ retry_snap:
 	ceph_put_cap_refs(ci, got);
 
 	if (written >= 0 &&
-	    ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) ||
+	    ((file->f_flags & O_SYNC) ||
+	     IS_SYNC(file->f_mapping->host) ||
+	     (iocb->ki_rwflags & RWF_DSYNC) ||
 	     ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) {
 		err = vfs_fsync_range(file, pos, pos + written - 1, 1);
 		if (err < 0)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index caa8d95..bb4fb23 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1248,6 +1248,8 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 		written += written_buffered;
 		iocb->ki_pos = pos + written_buffered;
 	} else {
+		if (iocb->ki_rwflags & RWF_DSYNC)
+			return -EINVAL;
 		written = fuse_perform_write(file, mapping, from, pos);
 		if (written >= 0)
 			iocb->ki_pos = pos + written;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 524dd80..a9e6cc4 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -621,13 +621,15 @@ static const struct vm_operations_struct nfs_file_vm_ops = {
 	.remap_pages = generic_file_remap_pages,
 };
 
-static int nfs_need_sync_write(struct file *filp, struct inode *inode)
+static int nfs_need_sync_write(struct kiocb *iocb, struct inode *inode)
 {
 	struct nfs_open_context *ctx;
 
-	if (IS_SYNC(inode) || (filp->f_flags & O_DSYNC))
+	if (IS_SYNC(inode) ||
+	    (iocb->ki_filp->f_flags & O_DSYNC) ||
+	    (iocb->ki_rwflags & RWF_DSYNC))
 		return 1;
-	ctx = nfs_file_open_context(filp);
+	ctx = nfs_file_open_context(iocb->ki_filp);
 	if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags) ||
 	    nfs_ctx_key_to_expire(ctx))
 		return 1;
@@ -674,7 +676,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
 		written = result;
 
 	/* Return error values for O_DSYNC and IS_SYNC() */
-	if (result >= 0 && nfs_need_sync_write(file, inode)) {
+	if (result >= 0 && nfs_need_sync_write(iocb, inode)) {
 		int err = vfs_fsync(file, 0);
 		if (err < 0)
 			result = err;
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index d96f60d..8f29714 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2375,8 +2375,10 @@ out_dio:
 	/* buffered aio wouldn't have proper lock coverage today */
 	BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
 
-	if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) ||
-	    ((file->f_flags & O_DIRECT) && !direct_io)) {
+	if (((file->f_flags & O_DSYNC) && !direct_io) ||
+	    IS_SYNC(inode) ||
+	    ((file->f_flags & O_DIRECT) && !direct_io) ||
+	    (iocb->ki_rwflags & RWF_DSYNC)) {
 		ret = filemap_fdatawrite_range(file->f_mapping, *ppos,
 					       *ppos + count - 1);
 		if (ret < 0)
diff --git a/fs/read_write.c b/fs/read_write.c
index 5592a18..8af8925 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -837,8 +837,13 @@ static ssize_t do_readv_writev(int type, struct file *file,
 		ret = do_iter_readv_writev(file, type, iov, nr_segs, tot_len,
 						pos, iter_fn, flags);
 	} else {
-		if (type == READ && (flags & RWF_NONBLOCK))
-			return -EAGAIN;
+		if (type == READ) {
+			if (flags & RWF_NONBLOCK)
+				return -EAGAIN;
+		} else {
+			if (flags & RWF_DSYNC)
+				return -EINVAL;
+		}
 
 		if (fnv)
 			ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
@@ -886,7 +891,7 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
 		return -EBADF;
 	if (!(file->f_mode & FMODE_CAN_WRITE))
 		return -EINVAL;
-	if (flags & ~0)
+	if (flags & ~RWF_DSYNC)
 		return -EINVAL;
 
 	return do_readv_writev(WRITE, file, vec, vlen, pos, flags);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cf759fa..005e7c8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1478,7 +1478,8 @@ struct block_device_operations;
 #define HAVE_UNLOCKED_IOCTL 1
 
 /* These flags are used for the readv/writev syscalls with flags. */
-#define RWF_NONBLOCK 0x00000001
+#define RWF_NONBLOCK	0x00000001
+#define RWF_DSYNC	0x00000002
 
 struct iov_iter;
 
diff --git a/mm/filemap.c b/mm/filemap.c
index f9ffb6f..40831ae 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2659,7 +2659,9 @@ int generic_write_sync(struct kiocb *iocb, loff_t count)
 	struct file *file = iocb->ki_filp;
 
 	if (count > 0 &&
-	    ((file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host))) {
+	    ((file->f_flags & O_DSYNC) ||
+	     (iocb->ki_rwflags & RWF_DSYNC) ||
+	     IS_SYNC(file->f_mapping->host))) {
 	    	bool fdatasync = !(file->f_flags & __O_SYNC);
 		ssize_t ret = 0;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/3] fs: add a flag for per-operation O_DSYNC semantics
@ 2014-10-01 21:04   ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-01 21:04 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

With the new read/write with flags syscalls we can support a flag
to enable O_DSYNC semantics on a per-operation basis.  This іs
useful to implement protocols like SMB, NFS or SCSI that have such
per-operation flags.

Example program below:

cat > pwritev2.c << EOF

        (off_t) val,                              \
        (off_t) ((((uint64_t) (val)) >> (sizeof (long) * 4)) >> (sizeof (long) * 4))

static ssize_t
pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags)
{
        return syscall(__NR_pwritev2, fd, iov, iovcnt, LO_HI_LONG(offset),
			 flags);
}

int main(int argc, char **argv)
{
	int fd = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0666);
	char buf[1024];
	struct iovec iov = { .iov_base = buf, .iov_len = 1024 };
	int ret;

        if (fd < 0) {
                perror("open");
                return 0;
        }

	memset(buf, 0xfe, sizeof(buf));

	ret = pwritev2(fd, &iov, 1, 0, RWF_DSYNC);
	if (ret < 0)
		perror("pwritev2");
	else
		printf("ret = %d\n", ret);

	return 0;
}
EOF

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/ceph/file.c     |  4 +++-
 fs/fuse/file.c     |  2 ++
 fs/nfs/file.c      | 10 ++++++----
 fs/ocfs2/file.c    |  6 ++++--
 fs/read_write.c    | 11 ++++++++---
 include/linux/fs.h |  3 ++-
 mm/filemap.c       |  4 +++-
 7 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 2eb02f8..e59f1f1 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -968,7 +968,9 @@ retry_snap:
 	ceph_put_cap_refs(ci, got);
 
 	if (written >= 0 &&
-	    ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) ||
+	    ((file->f_flags & O_SYNC) ||
+	     IS_SYNC(file->f_mapping->host) ||
+	     (iocb->ki_rwflags & RWF_DSYNC) ||
 	     ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) {
 		err = vfs_fsync_range(file, pos, pos + written - 1, 1);
 		if (err < 0)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index caa8d95..bb4fb23 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1248,6 +1248,8 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 		written += written_buffered;
 		iocb->ki_pos = pos + written_buffered;
 	} else {
+		if (iocb->ki_rwflags & RWF_DSYNC)
+			return -EINVAL;
 		written = fuse_perform_write(file, mapping, from, pos);
 		if (written >= 0)
 			iocb->ki_pos = pos + written;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 524dd80..a9e6cc4 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -621,13 +621,15 @@ static const struct vm_operations_struct nfs_file_vm_ops = {
 	.remap_pages = generic_file_remap_pages,
 };
 
-static int nfs_need_sync_write(struct file *filp, struct inode *inode)
+static int nfs_need_sync_write(struct kiocb *iocb, struct inode *inode)
 {
 	struct nfs_open_context *ctx;
 
-	if (IS_SYNC(inode) || (filp->f_flags & O_DSYNC))
+	if (IS_SYNC(inode) ||
+	    (iocb->ki_filp->f_flags & O_DSYNC) ||
+	    (iocb->ki_rwflags & RWF_DSYNC))
 		return 1;
-	ctx = nfs_file_open_context(filp);
+	ctx = nfs_file_open_context(iocb->ki_filp);
 	if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags) ||
 	    nfs_ctx_key_to_expire(ctx))
 		return 1;
@@ -674,7 +676,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
 		written = result;
 
 	/* Return error values for O_DSYNC and IS_SYNC() */
-	if (result >= 0 && nfs_need_sync_write(file, inode)) {
+	if (result >= 0 && nfs_need_sync_write(iocb, inode)) {
 		int err = vfs_fsync(file, 0);
 		if (err < 0)
 			result = err;
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index d96f60d..8f29714 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2375,8 +2375,10 @@ out_dio:
 	/* buffered aio wouldn't have proper lock coverage today */
 	BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
 
-	if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) ||
-	    ((file->f_flags & O_DIRECT) && !direct_io)) {
+	if (((file->f_flags & O_DSYNC) && !direct_io) ||
+	    IS_SYNC(inode) ||
+	    ((file->f_flags & O_DIRECT) && !direct_io) ||
+	    (iocb->ki_rwflags & RWF_DSYNC)) {
 		ret = filemap_fdatawrite_range(file->f_mapping, *ppos,
 					       *ppos + count - 1);
 		if (ret < 0)
diff --git a/fs/read_write.c b/fs/read_write.c
index 5592a18..8af8925 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -837,8 +837,13 @@ static ssize_t do_readv_writev(int type, struct file *file,
 		ret = do_iter_readv_writev(file, type, iov, nr_segs, tot_len,
 						pos, iter_fn, flags);
 	} else {
-		if (type == READ && (flags & RWF_NONBLOCK))
-			return -EAGAIN;
+		if (type == READ) {
+			if (flags & RWF_NONBLOCK)
+				return -EAGAIN;
+		} else {
+			if (flags & RWF_DSYNC)
+				return -EINVAL;
+		}
 
 		if (fnv)
 			ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
@@ -886,7 +891,7 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
 		return -EBADF;
 	if (!(file->f_mode & FMODE_CAN_WRITE))
 		return -EINVAL;
-	if (flags & ~0)
+	if (flags & ~RWF_DSYNC)
 		return -EINVAL;
 
 	return do_readv_writev(WRITE, file, vec, vlen, pos, flags);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cf759fa..005e7c8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1478,7 +1478,8 @@ struct block_device_operations;
 #define HAVE_UNLOCKED_IOCTL 1
 
 /* These flags are used for the readv/writev syscalls with flags. */
-#define RWF_NONBLOCK 0x00000001
+#define RWF_NONBLOCK	0x00000001
+#define RWF_DSYNC	0x00000002
 
 struct iov_iter;
 
diff --git a/mm/filemap.c b/mm/filemap.c
index f9ffb6f..40831ae 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2659,7 +2659,9 @@ int generic_write_sync(struct kiocb *iocb, loff_t count)
 	struct file *file = iocb->ki_filp;
 
 	if (count > 0 &&
-	    ((file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host))) {
+	    ((file->f_flags & O_DSYNC) ||
+	     (iocb->ki_rwflags & RWF_DSYNC) ||
+	     IS_SYNC(file->f_mapping->host))) {
 	    	bool fdatasync = !(file->f_flags & __O_SYNC);
 		ssize_t ret = 0;
 
-- 
1.9.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] xfs: add RWF_NONBLOCK support
  2014-10-01 21:04   ` Christoph Hellwig
@ 2014-10-01 22:23     ` Dave Chinner
  -1 siblings, 0 replies; 20+ messages in thread
From: Dave Chinner @ 2014-10-01 22:23 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Milosz Tanski, linux-fsdevel, xfs

On Wed, Oct 01, 2014 at 11:04:52PM +0200, Christoph Hellwig wrote:
> Add support for non-blocking reads.  The guts are handled by the generic
> code, the only addition is a non-blocking variant of xfs_rw_ilock.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/xfs_file.c | 30 +++++++++++++++++++++++++-----
>  1 file changed, 25 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index cf61271..f9efffc 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -61,6 +61,23 @@ xfs_rw_ilock(
>  	xfs_ilock(ip, type);
>  }
>  
> +static inline bool
> +xfs_rw_ilock_nowait(
> +	struct xfs_inode	*ip,
> +	int			type)
> +{
> +	if (type & XFS_IOLOCK_EXCL) {
> +		if (!mutex_trylock(&VFS_I(ip)->i_mutex))
> +			return false;
> +	}
> +	if (!xfs_ilock_nowait(ip, type)) {
> +		mutex_unlock(&VFS_I(ip)->i_mutex);

Shouldn't that be:

		if (type & XFS_IOLOCK_EXCL) {
			mutex_unlock(&VFS_I(ip)->i_mutex);

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] xfs: add RWF_NONBLOCK support
@ 2014-10-01 22:23     ` Dave Chinner
  0 siblings, 0 replies; 20+ messages in thread
From: Dave Chinner @ 2014-10-01 22:23 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, Milosz Tanski, xfs

On Wed, Oct 01, 2014 at 11:04:52PM +0200, Christoph Hellwig wrote:
> Add support for non-blocking reads.  The guts are handled by the generic
> code, the only addition is a non-blocking variant of xfs_rw_ilock.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/xfs_file.c | 30 +++++++++++++++++++++++++-----
>  1 file changed, 25 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index cf61271..f9efffc 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -61,6 +61,23 @@ xfs_rw_ilock(
>  	xfs_ilock(ip, type);
>  }
>  
> +static inline bool
> +xfs_rw_ilock_nowait(
> +	struct xfs_inode	*ip,
> +	int			type)
> +{
> +	if (type & XFS_IOLOCK_EXCL) {
> +		if (!mutex_trylock(&VFS_I(ip)->i_mutex))
> +			return false;
> +	}
> +	if (!xfs_ilock_nowait(ip, type)) {
> +		mutex_unlock(&VFS_I(ip)->i_mutex);

Shouldn't that be:

		if (type & XFS_IOLOCK_EXCL) {
			mutex_unlock(&VFS_I(ip)->i_mutex);

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: preadv2/pwritev2 updates
  2014-10-01 21:04 ` Christoph Hellwig
@ 2014-10-01 22:26   ` Dave Chinner
  -1 siblings, 0 replies; 20+ messages in thread
From: Dave Chinner @ 2014-10-01 22:26 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Milosz Tanski, linux-fsdevel, xfs

On Wed, Oct 01, 2014 at 11:04:51PM +0200, Christoph Hellwig wrote:
> Hi Miklos,
> 
> attached are the patches that go on top of your
> "[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
> series.  The first one adds RWF_NONBLOCK to XFS, the other two
> add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.

Christoph, any plans to add these new syscalls to xfs_io and
data integrity tests for the new RWF_DSYNC flag?

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: preadv2/pwritev2 updates
@ 2014-10-01 22:26   ` Dave Chinner
  0 siblings, 0 replies; 20+ messages in thread
From: Dave Chinner @ 2014-10-01 22:26 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, Milosz Tanski, xfs

On Wed, Oct 01, 2014 at 11:04:51PM +0200, Christoph Hellwig wrote:
> Hi Miklos,
> 
> attached are the patches that go on top of your
> "[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
> series.  The first one adds RWF_NONBLOCK to XFS, the other two
> add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.

Christoph, any plans to add these new syscalls to xfs_io and
data integrity tests for the new RWF_DSYNC flag?

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] xfs: add RWF_NONBLOCK support
  2014-10-01 22:23     ` Dave Chinner
@ 2014-10-02 11:29       ` Christoph Hellwig
  -1 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-02 11:29 UTC (permalink / raw)
  To: Dave Chinner; +Cc: Christoph Hellwig, Milosz Tanski, linux-fsdevel, xfs

On Thu, Oct 02, 2014 at 08:23:27AM +1000, Dave Chinner wrote:
> Shouldn't that be:
> 
> 		if (type & XFS_IOLOCK_EXCL) {
> 			mutex_unlock(&VFS_I(ip)->i_mutex);

Yes, I will resend the fixed version.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] xfs: add RWF_NONBLOCK support
@ 2014-10-02 11:29       ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-02 11:29 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-fsdevel, xfs, Christoph Hellwig, Milosz Tanski

On Thu, Oct 02, 2014 at 08:23:27AM +1000, Dave Chinner wrote:
> Shouldn't that be:
> 
> 		if (type & XFS_IOLOCK_EXCL) {
> 			mutex_unlock(&VFS_I(ip)->i_mutex);

Yes, I will resend the fixed version.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: preadv2/pwritev2 updates
  2014-10-01 22:26   ` Dave Chinner
@ 2014-10-02 11:31     ` Christoph Hellwig
  -1 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-02 11:31 UTC (permalink / raw)
  To: Dave Chinner; +Cc: Christoph Hellwig, Milosz Tanski, linux-fsdevel, xfs

On Thu, Oct 02, 2014 at 08:26:37AM +1000, Dave Chinner wrote:
> On Wed, Oct 01, 2014 at 11:04:51PM +0200, Christoph Hellwig wrote:
> > Hi Miklos,
> > 
> > attached are the patches that go on top of your
> > "[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
> > series.  The first one adds RWF_NONBLOCK to XFS, the other two
> > add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.
> 
> Christoph, any plans to add these new syscalls to xfs_io and
> data integrity tests for the new RWF_DSYNC flag?

I've got some hacked up xfs_io support, but Milosz was planning a
slight revision of the syscall interface that I'm still waiting for.

How would you want to automatically test for data integrity?  That requires
a powerfail or crash unfortunately and we don't have good infrastructure
for that yet.  I've tested it by adding a printk that RWF_DSYNC triggers
the same code path as O_DSYNC.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: preadv2/pwritev2 updates
@ 2014-10-02 11:31     ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-02 11:31 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-fsdevel, xfs, Christoph Hellwig, Milosz Tanski

On Thu, Oct 02, 2014 at 08:26:37AM +1000, Dave Chinner wrote:
> On Wed, Oct 01, 2014 at 11:04:51PM +0200, Christoph Hellwig wrote:
> > Hi Miklos,
> > 
> > attached are the patches that go on top of your
> > "[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
> > series.  The first one adds RWF_NONBLOCK to XFS, the other two
> > add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.
> 
> Christoph, any plans to add these new syscalls to xfs_io and
> data integrity tests for the new RWF_DSYNC flag?

I've got some hacked up xfs_io support, but Milosz was planning a
slight revision of the syscall interface that I'm still waiting for.

How would you want to automatically test for data integrity?  That requires
a powerfail or crash unfortunately and we don't have good infrastructure
for that yet.  I've tested it by adding a printk that RWF_DSYNC triggers
the same code path as O_DSYNC.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/3 v2] xfs: add RWF_NONBLOCK support
  2014-10-01 21:04   ` Christoph Hellwig
  (?)
  (?)
@ 2014-10-02 17:33   ` Christoph Hellwig
  -1 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2014-10-02 17:33 UTC (permalink / raw)
  To: Milosz Tanski; +Cc: linux-fsdevel, xfs

Add support for non-blocking reads.  The guts are handled by the generic
code, the only addition is a non-blocking variant of xfs_rw_ilock.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_file.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index cf61271..6981b10 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -61,6 +61,25 @@ xfs_rw_ilock(
 	xfs_ilock(ip, type);
 }
 
+static inline bool
+xfs_rw_ilock_nowait(
+	struct xfs_inode	*ip,
+	int			type)
+{
+	if (type & XFS_IOLOCK_EXCL) {
+		if (!mutex_trylock(&VFS_I(ip)->i_mutex))
+			return false;
+		if (!xfs_ilock_nowait(ip, type)) {
+			mutex_unlock(&VFS_I(ip)->i_mutex);
+			return false;
+		}
+	} else {
+		if (!xfs_ilock_nowait(ip, type))
+			return false;
+	}
+	return true;
+}
+
 static inline void
 xfs_rw_iunlock(
 	struct xfs_inode	*ip,
@@ -246,10 +265,6 @@ xfs_file_read_iter(
 
 	XFS_STATS_INC(xs_read_calls);
 
-	/* XXX: need a non-blocking iolock helper, shouldn't be too hard */
-	if (iocb->ki_rwflags & RWF_NONBLOCK)
-		return -EAGAIN;
-
 	if (unlikely(file->f_flags & O_DIRECT))
 		ioflags |= XFS_IO_ISDIRECT;
 	if (file->f_mode & FMODE_NOCMTIME)
@@ -287,7 +302,14 @@ xfs_file_read_iter(
 	 * This allows the normal direct IO case of no page cache pages to
 	 * proceeed concurrently without serialisation.
 	 */
-	xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
+	if (iocb->ki_rwflags & RWF_NONBLOCK) {
+		if (ioflags & XFS_IO_ISDIRECT)
+			return -EAGAIN;
+		if (!xfs_rw_ilock_nowait(ip, XFS_IOLOCK_SHARED))
+			return -EAGAIN;
+	} else {
+		xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
+	}
 	if ((ioflags & XFS_IO_ISDIRECT) && inode->i_mapping->nrpages) {
 		xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
 		xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);
-- 
1.9.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: preadv2/pwritev2 updates
  2014-10-02 11:31     ` Christoph Hellwig
@ 2014-10-02 21:05       ` Dave Chinner
  -1 siblings, 0 replies; 20+ messages in thread
From: Dave Chinner @ 2014-10-02 21:05 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Milosz Tanski, linux-fsdevel, xfs

On Thu, Oct 02, 2014 at 01:31:23PM +0200, Christoph Hellwig wrote:
> On Thu, Oct 02, 2014 at 08:26:37AM +1000, Dave Chinner wrote:
> > On Wed, Oct 01, 2014 at 11:04:51PM +0200, Christoph Hellwig wrote:
> > > Hi Miklos,
> > > 
> > > attached are the patches that go on top of your
> > > "[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
> > > series.  The first one adds RWF_NONBLOCK to XFS, the other two
> > > add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.
> > 
> > Christoph, any plans to add these new syscalls to xfs_io and
> > data integrity tests for the new RWF_DSYNC flag?
> 
> I've got some hacked up xfs_io support, but Milosz was planning a
> slight revision of the syscall interface that I'm still waiting for.
> 
> How would you want to automatically test for data integrity?  That requires
> a powerfail or crash unfortunately and we don't have good infrastructure
> for that yet.  I've tested it by adding a printk that RWF_DSYNC triggers
> the same code path as O_DSYNC.

We have the infrastructure in xfstests to do this in a generic way:
use dm-flakey.  The fsync tests (generic/311, generic/32[23]) that
Josef wrote that use dm-flakey to prevent writes after the IOs have
completed and check that the data is there after remount.

Similarly, for xfs specific tests we have older tests that use the
shutdown ioctl (e.g. xfs/137-139) by using the godown function to
shut the filesystem down and prevent unmount from writing metadata.
On remount the data should be present.

So there's a couple of different ways you can do this...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: preadv2/pwritev2 updates
@ 2014-10-02 21:05       ` Dave Chinner
  0 siblings, 0 replies; 20+ messages in thread
From: Dave Chinner @ 2014-10-02 21:05 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, Milosz Tanski, xfs

On Thu, Oct 02, 2014 at 01:31:23PM +0200, Christoph Hellwig wrote:
> On Thu, Oct 02, 2014 at 08:26:37AM +1000, Dave Chinner wrote:
> > On Wed, Oct 01, 2014 at 11:04:51PM +0200, Christoph Hellwig wrote:
> > > Hi Miklos,
> > > 
> > > attached are the patches that go on top of your
> > > "[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
> > > series.  The first one adds RWF_NONBLOCK to XFS, the other two
> > > add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.
> > 
> > Christoph, any plans to add these new syscalls to xfs_io and
> > data integrity tests for the new RWF_DSYNC flag?
> 
> I've got some hacked up xfs_io support, but Milosz was planning a
> slight revision of the syscall interface that I'm still waiting for.
> 
> How would you want to automatically test for data integrity?  That requires
> a powerfail or crash unfortunately and we don't have good infrastructure
> for that yet.  I've tested it by adding a printk that RWF_DSYNC triggers
> the same code path as O_DSYNC.

We have the infrastructure in xfstests to do this in a generic way:
use dm-flakey.  The fsync tests (generic/311, generic/32[23]) that
Josef wrote that use dm-flakey to prevent writes after the IOs have
completed and check that the data is there after remount.

Similarly, for xfs specific tests we have older tests that use the
shutdown ioctl (e.g. xfs/137-139) by using the godown function to
shut the filesystem down and prevent unmount from writing metadata.
On remount the data should be present.

So there's a couple of different ways you can do this...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: preadv2/pwritev2 updates
  2014-10-01 21:04 ` Christoph Hellwig
                   ` (4 preceding siblings ...)
  (?)
@ 2014-10-08  2:58 ` Milosz Tanski
  -1 siblings, 0 replies; 20+ messages in thread
From: Milosz Tanski @ 2014-10-08  2:58 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, xfs

I'm haven't gotten to many comments back from the last set of patches.
So I imagine that people are okay with the interface and the general
code.

The next submission will probably rename the call to preadv6/pwritev6
just to follow the interface ... but I don't think they'll be any
other changes; so no need to wait on me. How should we go about
packaging this up for mainline inclusion?

Additionally, I've been testing it with out application in and in the
test environment we've a 30% reduction in average response time. We
might be kind of a best case since we do a fair amount of CPU / IO
bound work overlapped and this lets us skip the threadpool queue in a
huge chunk of the cases. But the gains are real... for a real
application.

On Wed, Oct 1, 2014 at 5:04 PM, Christoph Hellwig <hch@lst.de> wrote:
> Hi Miklos,
>
> attached are the patches that go on top of your
> "[RFC v3 0/4] vfs: Non-blockling buffered fs read (page cache only)"
> series.  The first one adds RWF_NONBLOCK to XFS, the other two
> add a new RWF_DSYNC flag that adds a per-operation O_DSYNC flag.
>



-- 
Milosz Tanski
CTO
16 East 34th Street, 15th floor
New York, NY 10016

p: 646-253-9055
e: milosz@adfin.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2014-10-08  2:58 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-01 21:04 preadv2/pwritev2 updates Christoph Hellwig
2014-10-01 21:04 ` Christoph Hellwig
2014-10-01 21:04 ` [PATCH 1/3] xfs: add RWF_NONBLOCK support Christoph Hellwig
2014-10-01 21:04   ` Christoph Hellwig
2014-10-01 22:23   ` Dave Chinner
2014-10-01 22:23     ` Dave Chinner
2014-10-02 11:29     ` Christoph Hellwig
2014-10-02 11:29       ` Christoph Hellwig
2014-10-02 17:33   ` [PATCH 1/3 v2] " Christoph Hellwig
2014-10-01 21:04 ` [PATCH 2/3] fs: pass iocb to generic_write_sync Christoph Hellwig
2014-10-01 21:04   ` Christoph Hellwig
2014-10-01 21:04 ` [PATCH 3/3] fs: add a flag for per-operation O_DSYNC semantics Christoph Hellwig
2014-10-01 21:04   ` Christoph Hellwig
2014-10-01 22:26 ` preadv2/pwritev2 updates Dave Chinner
2014-10-01 22:26   ` Dave Chinner
2014-10-02 11:31   ` Christoph Hellwig
2014-10-02 11:31     ` Christoph Hellwig
2014-10-02 21:05     ` Dave Chinner
2014-10-02 21:05       ` Dave Chinner
2014-10-08  2:58 ` Milosz Tanski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.