linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/6] Btrfs: stop abusing current->journal_info for direct I/O
@ 2018-08-28  0:03 Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 1/6] fs: pass iocb to direct I/O get_block() Omar Sandoval
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Omar Sandoval @ 2018-08-28  0:03 UTC (permalink / raw)
  To: linux-fsdevel, linux-btrfs, Al Viro; +Cc: David Sterba, kernel-team

From: Omar Sandoval <osandov@fb.com>

Hi,

This is a different approach from v1 [1] of this series to stop abusing
current->journal_info in Btrfs. This approach unifies everything to use
iocb->private instead of map_bh->b_private. Patches 1 and 5 pass the
iocb to a couple of callbacks which need it. Patches 2 and 3 migrates
the users of b_private to use iocb->private, and patch 4 gets rid of the
b_private handling in the direct I/O code. Patch 6 cleans up Btrfs.

I'm not convinced that this is cleaner that my first approach, but it at
least avoids growing the argument list to do_blockdev_direct_IO(), which
was Al's complaint of v1.

Thanks!

1: https://www.spinics.net/lists/linux-btrfs/msg77859.html

Omar Sandoval (6):
  fs: pass iocb to direct I/O get_block()
  ext4: use iocb->private instead of bh->b_private
  ocfs2: use iocb->private instead of bh->b_private
  fs: stop propagating bh->b_private for direct I/O
  fs: pass iocb to direct I/O submit_io()
  Btrfs: stop abusing current->journal_info in btrfs_direct_IO()

 fs/affs/file.c      |  9 ++++++-
 fs/btrfs/inode.c    | 36 +++++++------------------
 fs/direct-io.c      | 23 +++++++---------
 fs/ext2/inode.c     |  9 ++++++-
 fs/ext4/ext4.h      |  2 --
 fs/ext4/inode.c     | 40 ++++++++++++++++------------
 fs/f2fs/data.c      |  5 ++--
 fs/fat/inode.c      |  9 ++++++-
 fs/gfs2/aops.c      |  5 ++--
 fs/hfs/inode.c      |  9 ++++++-
 fs/hfsplus/inode.c  |  9 ++++++-
 fs/jfs/inode.c      |  9 ++++++-
 fs/nilfs2/inode.c   |  9 ++++++-
 fs/ocfs2/aops.c     | 39 ++++++++++++++-------------
 fs/ocfs2/aops.h     | 64 ++++++++++++++++++++++++++++++---------------
 fs/reiserfs/inode.c |  4 +--
 fs/udf/inode.c      |  9 ++++++-
 include/linux/fs.h  | 17 ++++++------
 18 files changed, 187 insertions(+), 120 deletions(-)

-- 
2.18.0

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

* [RFC PATCH v2 1/6] fs: pass iocb to direct I/O get_block()
  2018-08-28  0:03 [RFC PATCH v2 0/6] Btrfs: stop abusing current->journal_info for direct I/O Omar Sandoval
@ 2018-08-28  0:03 ` Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 2/6] ext4: use iocb->private instead of bh->b_private Omar Sandoval
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Omar Sandoval @ 2018-08-28  0:03 UTC (permalink / raw)
  To: linux-fsdevel, linux-btrfs, Al Viro; +Cc: David Sterba, kernel-team

From: Omar Sandoval <osandov@fb.com>

Split out dio_get_block_t which is the same as get_block_t except that
it takes the iocb as well, and update fs/direct-io.c and all callers to
use it. This is preparation for replacing the use of bh->b_private in
the direct I/O code with iocb->private.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 fs/affs/file.c      |  9 ++++++++-
 fs/btrfs/inode.c    |  3 ++-
 fs/direct-io.c      | 13 ++++++-------
 fs/ext2/inode.c     |  9 ++++++++-
 fs/ext4/ext4.h      |  2 --
 fs/ext4/inode.c     | 27 ++++++++++++++++++---------
 fs/f2fs/data.c      |  5 +++--
 fs/fat/inode.c      |  9 ++++++++-
 fs/gfs2/aops.c      |  5 +++--
 fs/hfs/inode.c      |  9 ++++++++-
 fs/hfsplus/inode.c  |  9 ++++++++-
 fs/jfs/inode.c      |  9 ++++++++-
 fs/nilfs2/inode.c   |  9 ++++++++-
 fs/ocfs2/aops.c     | 15 +++++++++------
 fs/reiserfs/inode.c |  4 ++--
 fs/udf/inode.c      |  9 ++++++++-
 include/linux/fs.h  | 10 ++++++----
 17 files changed, 113 insertions(+), 43 deletions(-)

diff --git a/fs/affs/file.c b/fs/affs/file.c
index a85817f54483..66a1a5601d65 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -389,6 +389,13 @@ static void affs_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
+static int affs_get_block_dio(struct kiocb *iocb, struct inode *inode,
+			      sector_t block, struct buffer_head *bh_result,
+			      int create)
+{
+	return affs_get_block(inode, block, bh_result, create);
+}
+
 static ssize_t
 affs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
@@ -406,7 +413,7 @@ affs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 			return 0;
 	}
 
-	ret = blockdev_direct_IO(iocb, inode, iter, affs_get_block);
+	ret = blockdev_direct_IO(iocb, inode, iter, affs_get_block_dio);
 	if (ret < 0 && iov_iter_rw(iter) == WRITE)
 		affs_write_failed(mapping, offset + count);
 	return ret;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index eba61bcb9bb3..b61ea6dd9956 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7659,7 +7659,8 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
 	return ret;
 }
 
-static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
+static int btrfs_get_blocks_direct(struct kiocb *iocb, struct inode *inode,
+				   sector_t iblock,
 				   struct buffer_head *bh_result, int create)
 {
 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 093fb54cd316..f631aa98849b 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -82,7 +82,7 @@ struct dio_submit {
 	int reap_counter;		/* rate limit reaping */
 	sector_t final_block_in_request;/* doesn't change */
 	int boundary;			/* prev block is at a boundary */
-	get_block_t *get_block;		/* block mapping function */
+	dio_get_block_t *get_block;	/* block mapping function */
 	dio_submit_t *submit_io;	/* IO submition function */
 
 	loff_t logical_offset_in_bio;	/* current first logical block in bio */
@@ -713,8 +713,8 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio,
 				create = 0;
 		}
 
-		ret = (*sdio->get_block)(dio->inode, fs_startblk,
-						map_bh, create);
+		ret = (*sdio->get_block)(dio->iocb, dio->inode, fs_startblk,
+					 map_bh, create);
 
 		/* Store for completion */
 		dio->private = map_bh->b_private;
@@ -1170,7 +1170,7 @@ static inline int drop_refcount(struct dio *dio)
 static inline ssize_t
 do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
 		      struct block_device *bdev, struct iov_iter *iter,
-		      get_block_t get_block, dio_iodone_t end_io,
+		      dio_get_block_t get_block, dio_iodone_t end_io,
 		      dio_submit_t submit_io, int flags)
 {
 	unsigned i_blkbits = READ_ONCE(inode->i_blkbits);
@@ -1398,9 +1398,8 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
 
 ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
 			     struct block_device *bdev, struct iov_iter *iter,
-			     get_block_t get_block,
-			     dio_iodone_t end_io, dio_submit_t submit_io,
-			     int flags)
+			     dio_get_block_t get_block, dio_iodone_t end_io,
+			     dio_submit_t submit_io, int flags)
 {
 	/*
 	 * The block device state is needed in the end to finally
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 71635909df3b..f390e6392238 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -930,6 +930,13 @@ static sector_t ext2_bmap(struct address_space *mapping, sector_t block)
 	return generic_block_bmap(mapping,block,ext2_get_block);
 }
 
+static int ext2_get_block_dio(struct kiocb *iocb, struct inode *inode,
+			      sector_t iblock, struct buffer_head *bh_result,
+			      int create)
+{
+	return ext2_get_block(inode, iblock, bh_result, create);
+}
+
 static ssize_t
 ext2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
@@ -940,7 +947,7 @@ ext2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	loff_t offset = iocb->ki_pos;
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(iocb, inode, iter, ext2_get_block);
+	ret = blockdev_direct_IO(iocb, inode, iter, ext2_get_block_dio);
 	if (ret < 0 && iov_iter_rw(iter) == WRITE)
 		ext2_write_failed(mapping, offset + count);
 	return ret;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 7c7123f265c2..2c46c2e69b42 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2425,8 +2425,6 @@ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
 			     struct buffer_head *bh_result, int create);
 int ext4_get_block(struct inode *inode, sector_t iblock,
 		   struct buffer_head *bh_result, int create);
-int ext4_dio_get_block(struct inode *inode, sector_t iblock,
-		       struct buffer_head *bh_result, int create);
 int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
 			   struct buffer_head *bh, int create);
 int ext4_walk_page_buffers(handle_t *handle,
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 4efe77286ecd..18ad91b1c8f6 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -850,8 +850,9 @@ static int ext4_get_block_trans(struct inode *inode, sector_t iblock,
 }
 
 /* Get block function for DIO reads and writes to inodes without extents */
-int ext4_dio_get_block(struct inode *inode, sector_t iblock,
-		       struct buffer_head *bh, int create)
+static int ext4_dio_get_block(struct kiocb *iocb, struct inode *inode,
+			      sector_t iblock, struct buffer_head *bh,
+			      int create)
 {
 	/* We don't expect handle for direct IO */
 	WARN_ON_ONCE(ext4_journal_current_handle());
@@ -866,8 +867,11 @@ int ext4_dio_get_block(struct inode *inode, sector_t iblock,
  * blocks are not allocated yet. The extent will be converted to written
  * after IO is complete.
  */
-static int ext4_dio_get_block_unwritten_async(struct inode *inode,
-		sector_t iblock, struct buffer_head *bh_result,	int create)
+static int ext4_dio_get_block_unwritten_async(struct kiocb *iocb,
+					      struct inode *inode,
+					      sector_t iblock,
+					      struct buffer_head *bh_result,
+					      int create)
 {
 	int ret;
 
@@ -905,8 +909,11 @@ static int ext4_dio_get_block_unwritten_async(struct inode *inode,
  * blocks are not allocated yet. The extent will be converted to written
  * after IO is complete by ext4_direct_IO_write().
  */
-static int ext4_dio_get_block_unwritten_sync(struct inode *inode,
-		sector_t iblock, struct buffer_head *bh_result,	int create)
+static int ext4_dio_get_block_unwritten_sync(struct kiocb *iocb,
+					     struct inode *inode,
+					     sector_t iblock,
+					     struct buffer_head *bh_result,
+					     int create)
 {
 	int ret;
 
@@ -927,8 +934,10 @@ static int ext4_dio_get_block_unwritten_sync(struct inode *inode,
 	return ret;
 }
 
-static int ext4_dio_get_block_overwrite(struct inode *inode, sector_t iblock,
-		   struct buffer_head *bh_result, int create)
+static int ext4_dio_get_block_overwrite(struct kiocb *iocb, struct inode *inode,
+					sector_t iblock,
+					struct buffer_head *bh_result,
+					int create)
 {
 	int ret;
 
@@ -3663,7 +3672,7 @@ static ssize_t ext4_direct_IO_write(struct kiocb *iocb, struct iov_iter *iter)
 	loff_t offset = iocb->ki_pos;
 	size_t count = iov_iter_count(iter);
 	int overwrite = 0;
-	get_block_t *get_block_func = NULL;
+	dio_get_block_t *get_block_func = NULL;
 	int dio_flags = 0;
 	loff_t final_size = offset + count;
 	int orphan = 0;
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 8f931d699287..a465d7877886 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1232,8 +1232,9 @@ static int get_data_block(struct inode *inode, sector_t iblock,
 							NO_CHECK_TYPE);
 }
 
-static int get_data_block_dio(struct inode *inode, sector_t iblock,
-			struct buffer_head *bh_result, int create)
+static int get_data_block_dio(struct kiocb *iocb, struct inode *inode,
+			      sector_t iblock, struct buffer_head *bh_result,
+			      int create)
 {
 	return __get_data_block(inode, iblock, bh_result, create,
 						F2FS_GET_BLOCK_DEFAULT, NULL,
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index bfd589ea74c0..b2caca4ed6bc 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -251,6 +251,13 @@ static int fat_write_end(struct file *file, struct address_space *mapping,
 	return err;
 }
 
+static int fat_get_block_dio(struct kiocb *iocb, struct inode *inode,
+			     sector_t iblock, struct buffer_head *bh_result,
+			     int create)
+{
+	return fat_get_block(inode, iblock, bh_result, create);
+}
+
 static ssize_t fat_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *file = iocb->ki_filp;
@@ -279,7 +286,7 @@ static ssize_t fat_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	 * FAT need to use the DIO_LOCKING for avoiding the race
 	 * condition of fat_get_block() and ->truncate().
 	 */
-	ret = blockdev_direct_IO(iocb, inode, iter, fat_get_block);
+	ret = blockdev_direct_IO(iocb, inode, iter, fat_get_block_dio);
 	if (ret < 0 && iov_iter_rw(iter) == WRITE)
 		fat_write_failed(mapping, offset + count);
 
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 35f5ee23566d..cb908153559b 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -82,8 +82,9 @@ static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock,
 	return 0;
 }
 
-static int gfs2_get_block_direct(struct inode *inode, sector_t lblock,
-				 struct buffer_head *bh_result, int create)
+static int gfs2_get_block_direct(struct kiocb *iocb, struct inode *inode,
+				 sector_t lblock, struct buffer_head *bh_result,
+				 int create)
 {
 	return gfs2_block_map(inode, lblock, bh_result, 0);
 }
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 2a16111d312f..6986024c8ba0 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -126,6 +126,13 @@ static int hfs_releasepage(struct page *page, gfp_t mask)
 	return res ? try_to_free_buffers(page) : 0;
 }
 
+static int hfs_get_block_dio(struct kiocb *iocb, struct inode *inode,
+			     sector_t block, struct buffer_head *bh_result,
+			     int create)
+{
+	return hfs_get_block(inode, block, bh_result, create);
+}
+
 static ssize_t hfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *file = iocb->ki_filp;
@@ -134,7 +141,7 @@ static ssize_t hfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	size_t count = iov_iter_count(iter);
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(iocb, inode, iter, hfs_get_block);
+	ret = blockdev_direct_IO(iocb, inode, iter, hfs_get_block_dio);
 
 	/*
 	 * In case of error extending write may have instantiated a few
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index c824f702feec..0e1659bc934f 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -124,6 +124,13 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask)
 	return res ? try_to_free_buffers(page) : 0;
 }
 
+static int hfsplus_get_block_dio(struct kiocb *iocb, struct inode *inode,
+				 sector_t iblock, struct buffer_head *bh_result,
+				 int create)
+{
+	return hfsplus_get_block(inode, iblock, bh_result, create);
+}
+
 static ssize_t hfsplus_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *file = iocb->ki_filp;
@@ -132,7 +139,7 @@ static ssize_t hfsplus_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	size_t count = iov_iter_count(iter);
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(iocb, inode, iter, hfsplus_get_block);
+	ret = blockdev_direct_IO(iocb, inode, iter, hfsplus_get_block_dio);
 
 	/*
 	 * In case of error extending write may have instantiated a few
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 054cc761b426..e255bd5b15dc 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -332,6 +332,13 @@ static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
 	return generic_block_bmap(mapping, block, jfs_get_block);
 }
 
+static int jfs_get_block_dio(struct kiocb *iocb, struct inode *ip,
+			     sector_t lblock, struct buffer_head *bh_result,
+			     int create)
+{
+	return jfs_get_block(ip, lblock, bh_result, create);
+}
+
 static ssize_t jfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *file = iocb->ki_filp;
@@ -340,7 +347,7 @@ static ssize_t jfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	size_t count = iov_iter_count(iter);
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(iocb, inode, iter, jfs_get_block);
+	ret = blockdev_direct_IO(iocb, inode, iter, jfs_get_block_dio);
 
 	/*
 	 * In case of error extending write may have instantiated a few
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 6a612d832e7d..10f1b063fb4d 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -300,6 +300,13 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping,
 	return err ? : copied;
 }
 
+static int nilfs_get_block_dio(struct kiocb *iocb, struct inode *inode,
+			       sector_t blkoff, struct buffer_head *bh_result,
+			       int create)
+{
+	return nilfs_get_block(inode, blkoff, bh_result, create);
+}
+
 static ssize_t
 nilfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
@@ -309,7 +316,7 @@ nilfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 		return 0;
 
 	/* Needs synchronization with the cleaner */
-	return blockdev_direct_IO(iocb, inode, iter, nilfs_get_block);
+	return blockdev_direct_IO(iocb, inode, iter, nilfs_get_block_dio);
 }
 
 const struct address_space_operations nilfs_aops = {
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 302cd7caa4a7..93ca23c56b07 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -134,8 +134,9 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
 	return err;
 }
 
-static int ocfs2_lock_get_block(struct inode *inode, sector_t iblock,
-		    struct buffer_head *bh_result, int create)
+static int ocfs2_lock_get_block(struct kiocb *iocb, struct inode *inode,
+				sector_t iblock, struct buffer_head *bh_result,
+				int create)
 {
 	int ret = 0;
 	struct ocfs2_inode_info *oi = OCFS2_I(inode);
@@ -2143,8 +2144,9 @@ static void ocfs2_dio_free_write_ctx(struct inode *inode,
  * called like this: dio->get_blocks(dio->inode, fs_startblk,
  * 					fs_count, map_bh, dio->rw == WRITE);
  */
-static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
-			       struct buffer_head *bh_result, int create)
+static int ocfs2_dio_wr_get_block(struct kiocb *iocb, struct inode *inode,
+				  sector_t iblock,
+				  struct buffer_head *bh_result, int create)
 {
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 	struct ocfs2_inode_info *oi = OCFS2_I(inode);
@@ -2171,7 +2173,8 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
 	if (pos + total_len <= i_size_read(inode)) {
 
 		/* This is the fast path for re-write. */
-		ret = ocfs2_lock_get_block(inode, iblock, bh_result, create);
+		ret = ocfs2_lock_get_block(iocb, inode, iblock, bh_result,
+					   create);
 		if (buffer_mapped(bh_result) &&
 		    !buffer_new(bh_result) &&
 		    ret == 0)
@@ -2427,7 +2430,7 @@ static ssize_t ocfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_mapping->host;
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
-	get_block_t *get_block;
+	dio_get_block_t *get_block;
 
 	/*
 	 * Fallback to buffered I/O if we see an inode without
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 132ec4406ed0..55ac918dbc73 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -511,8 +511,8 @@ static int reiserfs_get_block_create_0(struct inode *inode, sector_t block,
  * This is special helper for reiserfs_get_block in case we are executing
  * direct_IO request.
  */
-static int reiserfs_get_blocks_direct_io(struct inode *inode,
-					 sector_t iblock,
+static int reiserfs_get_blocks_direct_io(struct kiocb *iocb,
+					 struct inode *inode, sector_t iblock,
 					 struct buffer_head *bh_result,
 					 int create)
 {
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 9915a58fbabd..5ef1c72fa1ab 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -206,6 +206,13 @@ static int udf_write_begin(struct file *file, struct address_space *mapping,
 	return ret;
 }
 
+static int udf_get_block_dio(struct kiocb *iocb, struct inode *inode,
+			     sector_t block, struct buffer_head *bh_result,
+			     int create)
+{
+	return udf_get_block(inode, block, bh_result, create);
+}
+
 static ssize_t udf_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *file = iocb->ki_filp;
@@ -214,7 +221,7 @@ static ssize_t udf_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	size_t count = iov_iter_count(iter);
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(iocb, inode, iter, udf_get_block);
+	ret = blockdev_direct_IO(iocb, inode, iter, udf_get_block_dio);
 	if (unlikely(ret < 0 && iov_iter_rw(iter) == WRITE))
 		udf_write_failed(mapping, iocb->ki_pos + count);
 	return ret;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 805bf22898cf..85db69835023 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -80,6 +80,9 @@ typedef __kernel_rwf_t rwf_t;
 struct buffer_head;
 typedef int (get_block_t)(struct inode *inode, sector_t iblock,
 			struct buffer_head *bh_result, int create);
+typedef int (dio_get_block_t)(struct kiocb *iocb, struct inode *inode,
+			      sector_t iblock, struct buffer_head *bh_result,
+			      int create);
 typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 			ssize_t bytes, void *private);
 
@@ -3017,14 +3020,13 @@ void dio_warn_stale_pagecache(struct file *filp);
 
 ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
 			     struct block_device *bdev, struct iov_iter *iter,
-			     get_block_t get_block,
-			     dio_iodone_t end_io, dio_submit_t submit_io,
-			     int flags);
+			     dio_get_block_t get_block, dio_iodone_t end_io,
+			     dio_submit_t submit_io, int flags);
 
 static inline ssize_t blockdev_direct_IO(struct kiocb *iocb,
 					 struct inode *inode,
 					 struct iov_iter *iter,
-					 get_block_t get_block)
+					 dio_get_block_t get_block)
 {
 	return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter,
 			get_block, NULL, NULL, DIO_LOCKING | DIO_SKIP_HOLES);
-- 
2.18.0

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

* [RFC PATCH v2 2/6] ext4: use iocb->private instead of bh->b_private
  2018-08-28  0:03 [RFC PATCH v2 0/6] Btrfs: stop abusing current->journal_info for direct I/O Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 1/6] fs: pass iocb to direct I/O get_block() Omar Sandoval
@ 2018-08-28  0:03 ` Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 3/6] ocfs2: " Omar Sandoval
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Omar Sandoval @ 2018-08-28  0:03 UTC (permalink / raw)
  To: linux-fsdevel, linux-btrfs, Al Viro
  Cc: David Sterba, kernel-team, Theodore Ts'o, Andreas Dilger

From: Omar Sandoval <osandov@fb.com>

As part of simplifying all of the private data passed around for direct
I/O, bh->b_private will no longer be passed to dio_iodone_t. iocb is
still available there, however, so convert ext4 to use it. Note that
ext4_file_write_iter() also uses iocb->private, but
ext4_direct_IO_write() resets it to NULL after reading it.

Also note that the comment above ext4_should_dioread_nolock() is no
longer accurate. It seems that it should be possible to remove the data
journaling restriction now?

Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 fs/ext4/inode.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 18ad91b1c8f6..841d79919cef 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -884,18 +884,16 @@ static int ext4_dio_get_block_unwritten_async(struct kiocb *iocb,
 	/*
 	 * When doing DIO using unwritten extents, we need io_end to convert
 	 * unwritten extents to written on IO completion. We allocate io_end
-	 * once we spot unwritten extent and store it in b_private. Generic
-	 * DIO code keeps b_private set and furthermore passes the value to
-	 * our completion callback in 'private' argument.
+	 * once we spot unwritten extent and store it in iocb->private.
 	 */
 	if (!ret && buffer_unwritten(bh_result)) {
-		if (!bh_result->b_private) {
+		if (!iocb->private) {
 			ext4_io_end_t *io_end;
 
 			io_end = ext4_init_io_end(inode, GFP_KERNEL);
 			if (!io_end)
 				return -ENOMEM;
-			bh_result->b_private = io_end;
+			iocb->private = io_end;
 			ext4_set_io_unwritten_flag(inode, io_end);
 		}
 		set_buffer_defer_completion(bh_result);
@@ -3617,7 +3615,7 @@ const struct iomap_ops ext4_iomap_ops = {
 static int ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
 			    ssize_t size, void *private)
 {
-        ext4_io_end_t *io_end = private;
+        ext4_io_end_t *io_end = iocb->private;
 
 	/* if not async direct IO just return */
 	if (!io_end)
-- 
2.18.0

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

* [RFC PATCH v2 3/6] ocfs2: use iocb->private instead of bh->b_private
  2018-08-28  0:03 [RFC PATCH v2 0/6] Btrfs: stop abusing current->journal_info for direct I/O Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 1/6] fs: pass iocb to direct I/O get_block() Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 2/6] ext4: use iocb->private instead of bh->b_private Omar Sandoval
@ 2018-08-28  0:03 ` Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 4/6] fs: stop propagating bh->b_private for direct I/O Omar Sandoval
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Omar Sandoval @ 2018-08-28  0:03 UTC (permalink / raw)
  To: linux-fsdevel, linux-btrfs, Al Viro
  Cc: David Sterba, kernel-team, Mark Fasheh, Joel Becker

From: Omar Sandoval <osandov@fb.com>

As part of simplifying all of the private data passed around for direct
I/O, bh->b_private will no longer be passed to dio_iodone_t. Instead,
filesystems should use iocb->private. ocfs2 already uses iocb->private
for storing a couple of flag bits, but we can use it as a tagged pointer
and hide all of the messiness in helpers.

Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 fs/ocfs2/aops.c | 19 ++++++++-------
 fs/ocfs2/aops.h | 64 +++++++++++++++++++++++++++++++++----------------
 2 files changed, 54 insertions(+), 29 deletions(-)

diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 93ca23c56b07..fc4a18b6ad3c 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -2104,12 +2104,13 @@ struct ocfs2_dio_write_ctxt {
 };
 
 static struct ocfs2_dio_write_ctxt *
-ocfs2_dio_alloc_write_ctx(struct buffer_head *bh, int *alloc)
+ocfs2_dio_alloc_write_ctx(struct kiocb *iocb, int *alloc)
 {
-	struct ocfs2_dio_write_ctxt *dwc = NULL;
+	struct ocfs2_dio_write_ctxt *dwc;
 
-	if (bh->b_private)
-		return bh->b_private;
+	dwc = ocfs2_iocb_private(iocb);
+	if (dwc)
+		return dwc;
 
 	dwc = kmalloc(sizeof(struct ocfs2_dio_write_ctxt), GFP_NOFS);
 	if (dwc == NULL)
@@ -2118,7 +2119,7 @@ ocfs2_dio_alloc_write_ctx(struct buffer_head *bh, int *alloc)
 	dwc->dw_zero_count = 0;
 	dwc->dw_orphaned = 0;
 	dwc->dw_writer_pid = task_pid_nr(current);
-	bh->b_private = dwc;
+	ocfs2_iocb_set_private(iocb, dwc);
 	*alloc = 1;
 
 	return dwc;
@@ -2184,7 +2185,7 @@ static int ocfs2_dio_wr_get_block(struct kiocb *iocb, struct inode *inode,
 		bh_result->b_state = 0;
 	}
 
-	dwc = ocfs2_dio_alloc_write_ctx(bh_result, &first_get_block);
+	dwc = ocfs2_dio_alloc_write_ctx(iocb, &first_get_block);
 	if (unlikely(dwc == NULL)) {
 		ret = -ENOMEM;
 		mlog_errno(ret);
@@ -2408,6 +2409,7 @@ static int ocfs2_dio_end_io(struct kiocb *iocb,
 			    ssize_t bytes,
 			    void *private)
 {
+	struct ocfs2_dio_write_ctxt *dwc;
 	struct inode *inode = file_inode(iocb->ki_filp);
 	int level;
 	int ret = 0;
@@ -2415,8 +2417,9 @@ static int ocfs2_dio_end_io(struct kiocb *iocb,
 	/* this io's submitter should not have unlocked this before we could */
 	BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
 
-	if (bytes > 0 && private)
-		ret = ocfs2_dio_end_io_write(inode, private, offset, bytes);
+	dwc = ocfs2_iocb_private(iocb);
+	if (bytes > 0 && dwc)
+		ret = ocfs2_dio_end_io_write(inode, dwc, offset, bytes);
 
 	ocfs2_iocb_clear_rw_locked(iocb);
 
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 3494a62ed749..2c3219e0c010 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -63,32 +63,54 @@ int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size);
 
 int ocfs2_get_block(struct inode *inode, sector_t iblock,
 		    struct buffer_head *bh_result, int create);
-/* all ocfs2_dio_end_io()'s fault */
-#define ocfs2_iocb_is_rw_locked(iocb) \
-	test_bit(0, (unsigned long *)&iocb->private)
+
+/*
+ * Direct I/O uses iocb->private as a tagged pointer. The bottom two bits
+ * defined below are used for communication between ocfs2_dio_end_io() and
+ * ocfs2_file_write/read_iter().
+ */
+#define OCFS2_IOCB_RW_LOCK 1
+#define OCFS2_IOCB_RW_LOCK_LEVEL 2
+
+static inline void *ocfs2_iocb_private(struct kiocb *iocb)
+{
+	return (void *)((unsigned long)iocb->private & ~3);
+}
+
+static inline void ocfs2_iocb_set_private(struct kiocb *iocb, void *private)
+{
+	iocb->private = (void *)(((unsigned long)iocb->private & 3) |
+				 ((unsigned long)private & ~3));
+}
+
+static inline bool ocfs2_iocb_is_rw_locked(struct kiocb *iocb)
+{
+	return (unsigned long)iocb->private & OCFS2_IOCB_RW_LOCK;
+}
+
 static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level)
 {
-	set_bit(0, (unsigned long *)&iocb->private);
+	unsigned long private = (unsigned long)iocb->private;
+
+	private |= OCFS2_IOCB_RW_LOCK;
 	if (level)
-		set_bit(1, (unsigned long *)&iocb->private);
+		private |= OCFS2_IOCB_RW_LOCK_LEVEL;
 	else
-		clear_bit(1, (unsigned long *)&iocb->private);
+		private &= ~OCFS2_IOCB_RW_LOCK_LEVEL;
+	iocb->private = (void *)private;
 }
 
-/*
- * Using a named enum representing lock types in terms of #N bit stored in
- * iocb->private, which is going to be used for communication between
- * ocfs2_dio_end_io() and ocfs2_file_write/read_iter().
- */
-enum ocfs2_iocb_lock_bits {
-	OCFS2_IOCB_RW_LOCK = 0,
-	OCFS2_IOCB_RW_LOCK_LEVEL,
-	OCFS2_IOCB_NUM_LOCKS
-};
-
-#define ocfs2_iocb_clear_rw_locked(iocb) \
-	clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)
-#define ocfs2_iocb_rw_locked_level(iocb) \
-	test_bit(OCFS2_IOCB_RW_LOCK_LEVEL, (unsigned long *)&iocb->private)
+static inline void ocfs2_iocb_clear_rw_locked(struct kiocb *iocb)
+{
+	unsigned long private = (unsigned long)iocb->private;
+
+	private &= ~OCFS2_IOCB_RW_LOCK;
+	iocb->private = (void *)private;
+}
+
+static inline bool ocfs2_iocb_rw_locked_level(struct kiocb *iocb)
+{
+	return (unsigned long)iocb->private & OCFS2_IOCB_RW_LOCK_LEVEL;
+}
 
 #endif /* OCFS2_FILE_H */
-- 
2.18.0

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

* [RFC PATCH v2 4/6] fs: stop propagating bh->b_private for direct I/O
  2018-08-28  0:03 [RFC PATCH v2 0/6] Btrfs: stop abusing current->journal_info for direct I/O Omar Sandoval
                   ` (2 preceding siblings ...)
  2018-08-28  0:03 ` [RFC PATCH v2 3/6] ocfs2: " Omar Sandoval
@ 2018-08-28  0:03 ` Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 5/6] fs: pass iocb to direct I/O submit_io() Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 6/6] Btrfs: stop abusing current->journal_info in btrfs_direct_IO() Omar Sandoval
  5 siblings, 0 replies; 7+ messages in thread
From: Omar Sandoval @ 2018-08-28  0:03 UTC (permalink / raw)
  To: linux-fsdevel, linux-btrfs, Al Viro; +Cc: David Sterba, kernel-team

From: Omar Sandoval <osandov@fb.com>

Currently, the direct I/O code saves the value of bh->b_private set
by the filesystem and passes it to the end_io callback. However, struct
kiocb already has a ->private member which can be used for this purpose,
with the added benefit of being available before get_block is called,
too. The only users of the bh->b_private functionality have been
converted to use iocb->private, so stop passing it around.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 fs/direct-io.c     | 7 +------
 fs/ext4/inode.c    | 3 +--
 fs/ocfs2/aops.c    | 5 +----
 include/linux/fs.h | 3 +--
 4 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/fs/direct-io.c b/fs/direct-io.c
index f631aa98849b..80e488afe6c6 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -122,8 +122,6 @@ struct dio {
 	loff_t i_size;			/* i_size when submitted */
 	dio_iodone_t *end_io;		/* IO completion function */
 
-	void *private;			/* copy from map_bh.b_private */
-
 	/* BIO completion state */
 	spinlock_t bio_lock;		/* protects BIO fields below */
 	int page_errors;		/* errno from get_user_pages() */
@@ -288,7 +286,7 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, unsigned int flags)
 
 	if (dio->end_io) {
 		// XXX: ki_pos??
-		err = dio->end_io(dio->iocb, offset, ret, dio->private);
+		err = dio->end_io(dio->iocb, offset, ret);
 		if (err)
 			ret = err;
 	}
@@ -716,9 +714,6 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio,
 		ret = (*sdio->get_block)(dio->iocb, dio->inode, fs_startblk,
 					 map_bh, create);
 
-		/* Store for completion */
-		dio->private = map_bh->b_private;
-
 		if (ret == 0 && buffer_defer_completion(map_bh))
 			ret = dio_set_defer_completion(dio);
 	}
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 841d79919cef..0f42793765bf 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3612,8 +3612,7 @@ const struct iomap_ops ext4_iomap_ops = {
 	.iomap_end		= ext4_iomap_end,
 };
 
-static int ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
-			    ssize_t size, void *private)
+static int ext4_end_io_dio(struct kiocb *iocb, loff_t offset, ssize_t size)
 {
         ext4_io_end_t *io_end = iocb->private;
 
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index fc4a18b6ad3c..c1232df20be5 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -2404,10 +2404,7 @@ static int ocfs2_dio_end_io_write(struct inode *inode,
  * particularly interested in the aio/dio case.  We use the rw_lock DLM lock
  * to protect io on one node from truncation on another.
  */
-static int ocfs2_dio_end_io(struct kiocb *iocb,
-			    loff_t offset,
-			    ssize_t bytes,
-			    void *private)
+static int ocfs2_dio_end_io(struct kiocb *iocb, loff_t offset, ssize_t bytes)
 {
 	struct ocfs2_dio_write_ctxt *dwc;
 	struct inode *inode = file_inode(iocb->ki_filp);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 85db69835023..f1a235f0fa21 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -83,8 +83,7 @@ typedef int (get_block_t)(struct inode *inode, sector_t iblock,
 typedef int (dio_get_block_t)(struct kiocb *iocb, struct inode *inode,
 			      sector_t iblock, struct buffer_head *bh_result,
 			      int create);
-typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
-			ssize_t bytes, void *private);
+typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, ssize_t bytes);
 
 #define MAY_EXEC		0x00000001
 #define MAY_WRITE		0x00000002
-- 
2.18.0

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

* [RFC PATCH v2 5/6] fs: pass iocb to direct I/O submit_io()
  2018-08-28  0:03 [RFC PATCH v2 0/6] Btrfs: stop abusing current->journal_info for direct I/O Omar Sandoval
                   ` (3 preceding siblings ...)
  2018-08-28  0:03 ` [RFC PATCH v2 4/6] fs: stop propagating bh->b_private for direct I/O Omar Sandoval
@ 2018-08-28  0:03 ` Omar Sandoval
  2018-08-28  0:03 ` [RFC PATCH v2 6/6] Btrfs: stop abusing current->journal_info in btrfs_direct_IO() Omar Sandoval
  5 siblings, 0 replies; 7+ messages in thread
From: Omar Sandoval @ 2018-08-28  0:03 UTC (permalink / raw)
  To: linux-fsdevel, linux-btrfs, Al Viro; +Cc: David Sterba, kernel-team

From: Omar Sandoval <osandov@fb.com>

Btrfs abuses current->journal_info in btrfs_direct_IO() in order to pass
around some state to get_block() and submit_io(). However, iocb->private
is free for Btrfs to use, we just need it passed to submit_io(). Btrfs
is the only user of submit_io(), so this doesn't affect any other
filesystems.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 fs/btrfs/inode.c   | 4 ++--
 fs/direct-io.c     | 3 ++-
 include/linux/fs.h | 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b61ea6dd9956..6efa6a6e3e20 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8427,8 +8427,8 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip)
 	return 0;
 }
 
-static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode,
-				loff_t file_offset)
+static void btrfs_submit_direct(struct kiocb *iocb, struct bio *dio_bio,
+				struct inode *inode, loff_t file_offset)
 {
 	struct btrfs_dio_private *dip = NULL;
 	struct bio *bio = NULL;
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 80e488afe6c6..aa367e70456d 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -473,7 +473,8 @@ static inline void dio_bio_submit(struct dio *dio, struct dio_submit *sdio)
 	dio->bio_disk = bio->bi_disk;
 
 	if (sdio->submit_io) {
-		sdio->submit_io(bio, dio->inode, sdio->logical_offset_in_bio);
+		sdio->submit_io(dio->iocb, bio, dio->inode,
+				sdio->logical_offset_in_bio);
 		dio->bio_cookie = BLK_QC_T_NONE;
 	} else
 		dio->bio_cookie = submit_bio(bio);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f1a235f0fa21..daf1df811f67 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3003,8 +3003,8 @@ extern int generic_file_open(struct inode * inode, struct file * filp);
 extern int nonseekable_open(struct inode * inode, struct file * filp);
 
 #ifdef CONFIG_BLOCK
-typedef void (dio_submit_t)(struct bio *bio, struct inode *inode,
-			    loff_t file_offset);
+typedef void (dio_submit_t)(struct kiocb *iocb, struct bio *bio,
+			    struct inode *inode, loff_t file_offset);
 
 enum {
 	/* need locking between buffered and direct access */
-- 
2.18.0

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

* [RFC PATCH v2 6/6] Btrfs: stop abusing current->journal_info in btrfs_direct_IO()
  2018-08-28  0:03 [RFC PATCH v2 0/6] Btrfs: stop abusing current->journal_info for direct I/O Omar Sandoval
                   ` (4 preceding siblings ...)
  2018-08-28  0:03 ` [RFC PATCH v2 5/6] fs: pass iocb to direct I/O submit_io() Omar Sandoval
@ 2018-08-28  0:03 ` Omar Sandoval
  5 siblings, 0 replies; 7+ messages in thread
From: Omar Sandoval @ 2018-08-28  0:03 UTC (permalink / raw)
  To: linux-fsdevel, linux-btrfs, Al Viro; +Cc: David Sterba, kernel-team

From: Omar Sandoval <osandov@fb.com>

Now that we can pass around the struct btrfs_dio_data through the
different callbacks generically, we don't need to shove it in
current->journal_info.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
 fs/btrfs/inode.c | 29 ++++++-----------------------
 1 file changed, 6 insertions(+), 23 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 6efa6a6e3e20..38a41e9d6e93 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7654,7 +7654,6 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
 	WARN_ON(dio_data->reserve < len);
 	dio_data->reserve -= len;
 	dio_data->unsubmitted_oe_range_end = start + len;
-	current->journal_info = dio_data;
 out:
 	return ret;
 }
@@ -7666,7 +7665,7 @@ static int btrfs_get_blocks_direct(struct kiocb *iocb, struct inode *inode,
 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 	struct extent_map *em;
 	struct extent_state *cached_state = NULL;
-	struct btrfs_dio_data *dio_data = NULL;
+	struct btrfs_dio_data *dio_data = iocb->private;
 	u64 start = iblock << inode->i_blkbits;
 	u64 lockstart, lockend;
 	u64 len = bh_result->b_size;
@@ -7681,25 +7680,13 @@ static int btrfs_get_blocks_direct(struct kiocb *iocb, struct inode *inode,
 	lockstart = start;
 	lockend = start + len - 1;
 
-	if (current->journal_info) {
-		/*
-		 * Need to pull our outstanding extents and set journal_info to NULL so
-		 * that anything that needs to check if there's a transaction doesn't get
-		 * confused.
-		 */
-		dio_data = current->journal_info;
-		current->journal_info = NULL;
-	}
-
 	/*
 	 * If this errors out it's because we couldn't invalidate pagecache for
 	 * this range and we need to fallback to buffered.
 	 */
 	if (lock_extent_direct(inode, lockstart, lockend, &cached_state,
-			       create)) {
-		ret = -ENOTBLK;
-		goto err;
-	}
+			       create))
+		return -ENOTBLK;
 
 	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, start, len, 0);
 	if (IS_ERR(em)) {
@@ -7767,9 +7754,6 @@ static int btrfs_get_blocks_direct(struct kiocb *iocb, struct inode *inode,
 unlock_err:
 	clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend,
 			 unlock_bits, 1, 0, &cached_state);
-err:
-	if (dio_data)
-		current->journal_info = dio_data;
 	return ret;
 }
 
@@ -8470,7 +8454,7 @@ static void btrfs_submit_direct(struct kiocb *iocb, struct bio *dio_bio,
 	 * time by btrfs_direct_IO().
 	 */
 	if (write) {
-		struct btrfs_dio_data *dio_data = current->journal_info;
+		struct btrfs_dio_data *dio_data = iocb->private;
 
 		dio_data->unsubmitted_oe_range_end = dip->logical_offset +
 			dip->bytes;
@@ -8612,13 +8596,13 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 		/*
 		 * We need to know how many extents we reserved so that we can
 		 * do the accounting properly if we go over the number we
-		 * originally calculated.  Abuse current->journal_info for this.
+		 * originally calculated.
 		 */
 		dio_data.reserve = round_up(count,
 					    fs_info->sectorsize);
 		dio_data.unsubmitted_oe_range_start = (u64)offset;
 		dio_data.unsubmitted_oe_range_end = (u64)offset;
-		current->journal_info = &dio_data;
+		iocb->private = &dio_data;
 		down_read(&BTRFS_I(inode)->dio_sem);
 	} else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK,
 				     &BTRFS_I(inode)->runtime_flags)) {
@@ -8633,7 +8617,6 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 				   btrfs_submit_direct, flags);
 	if (iov_iter_rw(iter) == WRITE) {
 		up_read(&BTRFS_I(inode)->dio_sem);
-		current->journal_info = NULL;
 		if (ret < 0 && ret != -EIOCBQUEUED) {
 			if (dio_data.reserve)
 				btrfs_delalloc_release_space(inode, data_reserved,
-- 
2.18.0

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

end of thread, other threads:[~2018-08-28  3:52 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-28  0:03 [RFC PATCH v2 0/6] Btrfs: stop abusing current->journal_info for direct I/O Omar Sandoval
2018-08-28  0:03 ` [RFC PATCH v2 1/6] fs: pass iocb to direct I/O get_block() Omar Sandoval
2018-08-28  0:03 ` [RFC PATCH v2 2/6] ext4: use iocb->private instead of bh->b_private Omar Sandoval
2018-08-28  0:03 ` [RFC PATCH v2 3/6] ocfs2: " Omar Sandoval
2018-08-28  0:03 ` [RFC PATCH v2 4/6] fs: stop propagating bh->b_private for direct I/O Omar Sandoval
2018-08-28  0:03 ` [RFC PATCH v2 5/6] fs: pass iocb to direct I/O submit_io() Omar Sandoval
2018-08-28  0:03 ` [RFC PATCH v2 6/6] Btrfs: stop abusing current->journal_info in btrfs_direct_IO() Omar Sandoval

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).