All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: Satya Tangirala <satyat@google.com>
Cc: linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-ext4@vger.kernel.org, linux-xfs@vger.kernel.org,
	Eric Biggers <ebiggers@google.com>
Subject: Re: [PATCH v4 1/7] fscrypt: Add functions for direct I/O support
Date: Wed, 22 Jul 2020 10:04:49 -0700	[thread overview]
Message-ID: <20200722170449.GD3912099@google.com> (raw)
In-Reply-To: <20200720233739.824943-2-satyat@google.com>

On 07/20, Satya Tangirala wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Introduce fscrypt_dio_supported() to check whether a direct I/O request
> is unsupported due to encryption constraints.
> 
> Also introduce fscrypt_limit_io_pages() to limit how many pages can be
> added to a bio being prepared for direct I/O. This is needed for the
> iomap direct I/O implementation to avoid DUN wraparound in the middle of
> a bio (which is possible with the IV_INO_LBLK_32 IV generation method).
> Elsewhere fscrypt_mergeable_bio() is used for this, but iomap operates
> on logical ranges directly and doesn't have a chance to call
> fscrypt_mergeable_bio() on every block or page. So we need this function
> which limits a logical range in one go.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>
> Co-developed-by: Satya Tangirala <satyat@google.com>
> Signed-off-by: Satya Tangirala <satyat@google.com>

Reviewed-by: Jaegeuk Kim <jaegeuk@kernel.org>

> ---
>  fs/crypto/crypto.c       |  8 ++++
>  fs/crypto/inline_crypt.c | 82 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/fscrypt.h  | 19 ++++++++++
>  3 files changed, 109 insertions(+)
> 
> diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
> index a52cf32733ab..fb34364360b3 100644
> --- a/fs/crypto/crypto.c
> +++ b/fs/crypto/crypto.c
> @@ -69,6 +69,14 @@ void fscrypt_free_bounce_page(struct page *bounce_page)
>  }
>  EXPORT_SYMBOL(fscrypt_free_bounce_page);
>  
> +/*
> + * Generate the IV for the given logical block number within the given file.
> + * For filenames encryption, lblk_num == 0.
> + *
> + * Keep this in sync with fscrypt_limit_io_pages().  fscrypt_limit_io_pages()
> + * needs to know about any IV generation methods where the low bits of IV don't
> + * simply contain the lblk_num (e.g., IV_INO_LBLK_32).
> + */
>  void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
>  			 const struct fscrypt_info *ci)
>  {
> diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c
> index d7aecadf33c1..578739712e00 100644
> --- a/fs/crypto/inline_crypt.c
> +++ b/fs/crypto/inline_crypt.c
> @@ -16,6 +16,7 @@
>  #include <linux/blkdev.h>
>  #include <linux/buffer_head.h>
>  #include <linux/sched/mm.h>
> +#include <linux/uio.h>
>  
>  #include "fscrypt_private.h"
>  
> @@ -362,3 +363,84 @@ bool fscrypt_mergeable_bio_bh(struct bio *bio,
>  	return fscrypt_mergeable_bio(bio, inode, next_lblk);
>  }
>  EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio_bh);
> +
> +/**
> + * fscrypt_dio_supported() - check whether a direct I/O request is unsupported
> + *			     due to encryption constraints
> + * @iocb: the file and position the I/O is targeting
> + * @iter: the I/O data segment(s)
> + *
> + * Return: true if direct I/O is supported
> + */
> +bool fscrypt_dio_supported(struct kiocb *iocb, struct iov_iter *iter)
> +{
> +	const struct inode *inode = file_inode(iocb->ki_filp);
> +	const unsigned int blocksize = i_blocksize(inode);
> +
> +	/* If the file is unencrypted, no veto from us. */
> +	if (!fscrypt_needs_contents_encryption(inode))
> +		return true;
> +
> +	/* We only support direct I/O with inline crypto, not fs-layer crypto */
> +	if (!fscrypt_inode_uses_inline_crypto(inode))
> +		return false;
> +
> +	/*
> +	 * Since the granularity of encryption is filesystem blocks, the I/O
> +	 * must be block aligned -- not just disk sector aligned.
> +	 */
> +	if (!IS_ALIGNED(iocb->ki_pos | iov_iter_alignment(iter), blocksize))
> +		return false;
> +
> +	return true;
> +}
> +EXPORT_SYMBOL_GPL(fscrypt_dio_supported);
> +
> +/**
> + * fscrypt_limit_io_pages() - limit I/O pages to avoid discontiguous DUNs
> + * @inode: the file on which I/O is being done
> + * @pos: the file position (in bytes) at which the I/O is being done
> + * @nr_pages: the number of pages we want to submit starting at @pos
> + *
> + * Determine the limit to the number of pages that can be submitted in the bio
> + * targeting @pos without causing a data unit number (DUN) discontinuity.
> + *
> + * This is normally just @nr_pages, as normally the DUNs just increment along
> + * with the logical blocks.  (Or the file is not encrypted.)
> + *
> + * In rare cases, fscrypt can be using an IV generation method that allows the
> + * DUN to wrap around within logically continuous blocks, and that wraparound
> + * will occur.  If this happens, a value less than @nr_pages will be returned so
> + * that the wraparound doesn't occur in the middle of the bio.  Note that we
> + * only support block_size == PAGE_SIZE (and page-aligned DIO) in such cases.
> + *
> + * Return: the actual number of pages that can be submitted
> + */
> +int fscrypt_limit_io_pages(const struct inode *inode, loff_t pos, int nr_pages)
> +{
> +	const struct fscrypt_info *ci = inode->i_crypt_info;
> +	u32 dun;
> +
> +	if (!fscrypt_inode_uses_inline_crypto(inode))
> +		return nr_pages;
> +
> +	if (nr_pages <= 1)
> +		return nr_pages;
> +
> +	if (!(fscrypt_policy_flags(&ci->ci_policy) &
> +	      FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
> +		return nr_pages;
> +
> +	/*
> +	 * fscrypt_select_encryption_impl() ensures that block_size == PAGE_SIZE
> +	 * when using FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32.
> +	 */
> +	if (WARN_ON_ONCE(i_blocksize(inode) != PAGE_SIZE))
> +		return 1;
> +
> +	/* With IV_INO_LBLK_32, the DUN can wrap around from U32_MAX to 0. */
> +
> +	dun = ci->ci_hashed_ino + (pos >> inode->i_blkbits);
> +
> +	return min_t(u64, nr_pages, (u64)U32_MAX + 1 - dun);
> +}
> diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
> index bb257411365f..c205c214b35e 100644
> --- a/include/linux/fscrypt.h
> +++ b/include/linux/fscrypt.h
> @@ -559,6 +559,11 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode,
>  bool fscrypt_mergeable_bio_bh(struct bio *bio,
>  			      const struct buffer_head *next_bh);
>  
> +bool fscrypt_dio_supported(struct kiocb *iocb, struct iov_iter *iter);
> +
> +int fscrypt_limit_io_pages(const struct inode *inode, loff_t pos,
> +			   int nr_pages);
> +
>  #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
>  
>  static inline bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode)
> @@ -587,6 +592,20 @@ static inline bool fscrypt_mergeable_bio_bh(struct bio *bio,
>  {
>  	return true;
>  }
> +
> +static inline bool fscrypt_dio_supported(struct kiocb *iocb,
> +					 struct iov_iter *iter)
> +{
> +	const struct inode *inode = file_inode(iocb->ki_filp);
> +
> +	return !fscrypt_needs_contents_encryption(inode);
> +}
> +
> +static inline int fscrypt_limit_io_pages(const struct inode *inode, loff_t pos,
> +					 int nr_pages)
> +{
> +	return nr_pages;
> +}
>  #endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
>  
>  /**
> -- 
> 2.28.0.rc0.105.gf9edc3c819-goog

WARNING: multiple messages have this Message-ID (diff)
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: Satya Tangirala <satyat@google.com>
Cc: Eric Biggers <ebiggers@google.com>,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-xfs@vger.kernel.org, linux-fscrypt@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org
Subject: Re: [f2fs-dev] [PATCH v4 1/7] fscrypt: Add functions for direct I/O support
Date: Wed, 22 Jul 2020 10:04:49 -0700	[thread overview]
Message-ID: <20200722170449.GD3912099@google.com> (raw)
In-Reply-To: <20200720233739.824943-2-satyat@google.com>

On 07/20, Satya Tangirala wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Introduce fscrypt_dio_supported() to check whether a direct I/O request
> is unsupported due to encryption constraints.
> 
> Also introduce fscrypt_limit_io_pages() to limit how many pages can be
> added to a bio being prepared for direct I/O. This is needed for the
> iomap direct I/O implementation to avoid DUN wraparound in the middle of
> a bio (which is possible with the IV_INO_LBLK_32 IV generation method).
> Elsewhere fscrypt_mergeable_bio() is used for this, but iomap operates
> on logical ranges directly and doesn't have a chance to call
> fscrypt_mergeable_bio() on every block or page. So we need this function
> which limits a logical range in one go.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>
> Co-developed-by: Satya Tangirala <satyat@google.com>
> Signed-off-by: Satya Tangirala <satyat@google.com>

Reviewed-by: Jaegeuk Kim <jaegeuk@kernel.org>

> ---
>  fs/crypto/crypto.c       |  8 ++++
>  fs/crypto/inline_crypt.c | 82 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/fscrypt.h  | 19 ++++++++++
>  3 files changed, 109 insertions(+)
> 
> diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
> index a52cf32733ab..fb34364360b3 100644
> --- a/fs/crypto/crypto.c
> +++ b/fs/crypto/crypto.c
> @@ -69,6 +69,14 @@ void fscrypt_free_bounce_page(struct page *bounce_page)
>  }
>  EXPORT_SYMBOL(fscrypt_free_bounce_page);
>  
> +/*
> + * Generate the IV for the given logical block number within the given file.
> + * For filenames encryption, lblk_num == 0.
> + *
> + * Keep this in sync with fscrypt_limit_io_pages().  fscrypt_limit_io_pages()
> + * needs to know about any IV generation methods where the low bits of IV don't
> + * simply contain the lblk_num (e.g., IV_INO_LBLK_32).
> + */
>  void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
>  			 const struct fscrypt_info *ci)
>  {
> diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c
> index d7aecadf33c1..578739712e00 100644
> --- a/fs/crypto/inline_crypt.c
> +++ b/fs/crypto/inline_crypt.c
> @@ -16,6 +16,7 @@
>  #include <linux/blkdev.h>
>  #include <linux/buffer_head.h>
>  #include <linux/sched/mm.h>
> +#include <linux/uio.h>
>  
>  #include "fscrypt_private.h"
>  
> @@ -362,3 +363,84 @@ bool fscrypt_mergeable_bio_bh(struct bio *bio,
>  	return fscrypt_mergeable_bio(bio, inode, next_lblk);
>  }
>  EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio_bh);
> +
> +/**
> + * fscrypt_dio_supported() - check whether a direct I/O request is unsupported
> + *			     due to encryption constraints
> + * @iocb: the file and position the I/O is targeting
> + * @iter: the I/O data segment(s)
> + *
> + * Return: true if direct I/O is supported
> + */
> +bool fscrypt_dio_supported(struct kiocb *iocb, struct iov_iter *iter)
> +{
> +	const struct inode *inode = file_inode(iocb->ki_filp);
> +	const unsigned int blocksize = i_blocksize(inode);
> +
> +	/* If the file is unencrypted, no veto from us. */
> +	if (!fscrypt_needs_contents_encryption(inode))
> +		return true;
> +
> +	/* We only support direct I/O with inline crypto, not fs-layer crypto */
> +	if (!fscrypt_inode_uses_inline_crypto(inode))
> +		return false;
> +
> +	/*
> +	 * Since the granularity of encryption is filesystem blocks, the I/O
> +	 * must be block aligned -- not just disk sector aligned.
> +	 */
> +	if (!IS_ALIGNED(iocb->ki_pos | iov_iter_alignment(iter), blocksize))
> +		return false;
> +
> +	return true;
> +}
> +EXPORT_SYMBOL_GPL(fscrypt_dio_supported);
> +
> +/**
> + * fscrypt_limit_io_pages() - limit I/O pages to avoid discontiguous DUNs
> + * @inode: the file on which I/O is being done
> + * @pos: the file position (in bytes) at which the I/O is being done
> + * @nr_pages: the number of pages we want to submit starting at @pos
> + *
> + * Determine the limit to the number of pages that can be submitted in the bio
> + * targeting @pos without causing a data unit number (DUN) discontinuity.
> + *
> + * This is normally just @nr_pages, as normally the DUNs just increment along
> + * with the logical blocks.  (Or the file is not encrypted.)
> + *
> + * In rare cases, fscrypt can be using an IV generation method that allows the
> + * DUN to wrap around within logically continuous blocks, and that wraparound
> + * will occur.  If this happens, a value less than @nr_pages will be returned so
> + * that the wraparound doesn't occur in the middle of the bio.  Note that we
> + * only support block_size == PAGE_SIZE (and page-aligned DIO) in such cases.
> + *
> + * Return: the actual number of pages that can be submitted
> + */
> +int fscrypt_limit_io_pages(const struct inode *inode, loff_t pos, int nr_pages)
> +{
> +	const struct fscrypt_info *ci = inode->i_crypt_info;
> +	u32 dun;
> +
> +	if (!fscrypt_inode_uses_inline_crypto(inode))
> +		return nr_pages;
> +
> +	if (nr_pages <= 1)
> +		return nr_pages;
> +
> +	if (!(fscrypt_policy_flags(&ci->ci_policy) &
> +	      FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
> +		return nr_pages;
> +
> +	/*
> +	 * fscrypt_select_encryption_impl() ensures that block_size == PAGE_SIZE
> +	 * when using FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32.
> +	 */
> +	if (WARN_ON_ONCE(i_blocksize(inode) != PAGE_SIZE))
> +		return 1;
> +
> +	/* With IV_INO_LBLK_32, the DUN can wrap around from U32_MAX to 0. */
> +
> +	dun = ci->ci_hashed_ino + (pos >> inode->i_blkbits);
> +
> +	return min_t(u64, nr_pages, (u64)U32_MAX + 1 - dun);
> +}
> diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
> index bb257411365f..c205c214b35e 100644
> --- a/include/linux/fscrypt.h
> +++ b/include/linux/fscrypt.h
> @@ -559,6 +559,11 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode,
>  bool fscrypt_mergeable_bio_bh(struct bio *bio,
>  			      const struct buffer_head *next_bh);
>  
> +bool fscrypt_dio_supported(struct kiocb *iocb, struct iov_iter *iter);
> +
> +int fscrypt_limit_io_pages(const struct inode *inode, loff_t pos,
> +			   int nr_pages);
> +
>  #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
>  
>  static inline bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode)
> @@ -587,6 +592,20 @@ static inline bool fscrypt_mergeable_bio_bh(struct bio *bio,
>  {
>  	return true;
>  }
> +
> +static inline bool fscrypt_dio_supported(struct kiocb *iocb,
> +					 struct iov_iter *iter)
> +{
> +	const struct inode *inode = file_inode(iocb->ki_filp);
> +
> +	return !fscrypt_needs_contents_encryption(inode);
> +}
> +
> +static inline int fscrypt_limit_io_pages(const struct inode *inode, loff_t pos,
> +					 int nr_pages)
> +{
> +	return nr_pages;
> +}
>  #endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
>  
>  /**
> -- 
> 2.28.0.rc0.105.gf9edc3c819-goog


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  reply	other threads:[~2020-07-22 17:04 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-20 23:37 [PATCH v4 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
2020-07-20 23:37 ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-07-20 23:37 ` [PATCH v4 1/7] fscrypt: Add functions for direct I/O support Satya Tangirala
2020-07-20 23:37   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-07-22 17:04   ` Jaegeuk Kim [this message]
2020-07-22 17:04     ` Jaegeuk Kim
2020-07-20 23:37 ` [PATCH v4 2/7] direct-io: add support for fscrypt using blk-crypto Satya Tangirala
2020-07-20 23:37   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-07-22 17:05   ` Jaegeuk Kim
2020-07-22 17:05     ` [f2fs-dev] " Jaegeuk Kim
2020-07-20 23:37 ` [PATCH v4 3/7] iomap: support direct I/O with " Satya Tangirala
2020-07-20 23:37   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-07-22 17:06   ` Jaegeuk Kim
2020-07-22 17:06     ` [f2fs-dev] " Jaegeuk Kim
2020-07-22 21:16   ` Dave Chinner
2020-07-22 21:16     ` [f2fs-dev] " Dave Chinner
2020-07-22 22:34     ` Eric Biggers
2020-07-22 22:34       ` [f2fs-dev] " Eric Biggers
2020-07-22 22:44       ` Matthew Wilcox
2020-07-22 22:44         ` [f2fs-dev] " Matthew Wilcox
2020-07-22 23:12         ` Eric Biggers
2020-07-22 23:12           ` [f2fs-dev] " Eric Biggers
2020-07-22 23:26       ` Eric Biggers
2020-07-22 23:26         ` [f2fs-dev] " Eric Biggers
2020-07-22 23:32         ` Darrick J. Wong
2020-07-22 23:32           ` [f2fs-dev] " Darrick J. Wong
2020-07-22 23:43           ` Eric Biggers
2020-07-22 23:43             ` [f2fs-dev] " Eric Biggers
2020-07-23 22:07       ` Dave Chinner
2020-07-23 22:07         ` [f2fs-dev] " Dave Chinner
2020-07-23 23:03         ` Eric Biggers
2020-07-23 23:03           ` [f2fs-dev] " Eric Biggers
2020-07-24  1:39           ` Dave Chinner
2020-07-24  1:39             ` [f2fs-dev] " Dave Chinner
2020-07-24  3:46             ` Eric Biggers
2020-07-24  3:46               ` [f2fs-dev] " Eric Biggers
2020-07-24  5:31               ` Dave Chinner
2020-07-24  5:31                 ` [f2fs-dev] " Dave Chinner
2020-07-24 17:41                 ` Eric Biggers
2020-07-24 17:41                   ` [f2fs-dev] " Eric Biggers
2020-07-25 23:47                   ` Dave Chinner
2020-07-25 23:47                     ` [f2fs-dev] " Dave Chinner
2020-07-25 23:59                     ` Dave Chinner
2020-07-25 23:59                       ` [f2fs-dev] " Dave Chinner
2020-07-26  2:42                     ` Eric Biggers
2020-07-26  2:42                       ` [f2fs-dev] " Eric Biggers
2020-07-27 17:16                       ` Eric Biggers
2020-07-27 17:16                         ` [f2fs-dev] " Eric Biggers
2020-07-20 23:37 ` [PATCH v4 4/7] ext4: " Satya Tangirala
2020-07-20 23:37   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-07-22 17:07   ` Jaegeuk Kim
2020-07-22 17:07     ` [f2fs-dev] " Jaegeuk Kim
2020-07-20 23:37 ` [PATCH v4 5/7] f2fs: " Satya Tangirala
2020-07-20 23:37   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-07-21 20:11   ` Jaegeuk Kim
2020-07-21 20:11     ` [f2fs-dev] " Jaegeuk Kim
2020-07-20 23:37 ` [PATCH v4 6/7] fscrypt: document inline encryption support Satya Tangirala
2020-07-20 23:37   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-07-22 17:01   ` Jaegeuk Kim
2020-07-22 17:01     ` [f2fs-dev] " Jaegeuk Kim
2020-07-20 23:37 ` [PATCH v4 7/7] fscrypt: update documentation for direct I/O support Satya Tangirala
2020-07-20 23:37   ` [f2fs-dev] " Satya Tangirala via Linux-f2fs-devel
2020-07-21  0:47   ` Eric Biggers
2020-07-21  0:47     ` [f2fs-dev] " Eric Biggers
2020-07-22 16:57     ` Jaegeuk Kim
2020-07-22 16:57       ` [f2fs-dev] " Jaegeuk Kim
2020-07-21  0:56 ` [PATCH v4 0/7] add support for direct I/O with fscrypt using blk-crypto Eric Biggers
2020-07-21  0:56   ` [f2fs-dev] " Eric Biggers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200722170449.GD3912099@google.com \
    --to=jaegeuk@kernel.org \
    --cc=ebiggers@google.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=satyat@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.