Linux-FSCrypt Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto
@ 2020-07-17  1:45 Satya Tangirala
  2020-07-17  1:45 ` [PATCH v3 1/7] fscrypt: Add functions for direct I/O support Satya Tangirala
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Satya Tangirala @ 2020-07-17  1:45 UTC (permalink / raw)
  To: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4
  Cc: linux-xfs, Satya Tangirala

This patch series adds support for direct I/O with fscrypt using
blk-crypto. It has been rebased on fscrypt/master.

Patch 1 adds two functions to fscrypt that need to be called to determine
if direct I/O is supported for a request.

Patches 2 and 3 wire up direct-io and iomap respectively with the functions
introduced in Patch 1 and set bio crypt contexts on bios when appropriate
by calling into fscrypt.

Patches 4 and 5 allow ext4 and f2fs direct I/O to support fscrypt without
falling back to buffered I/O.

Patches 6 and 7 update the fscrypt documentation for inline encryption
support and direct I/O. The documentation now notes the required conditions
for inline encryption and direct I/O on encrypted files.

This patch series was tested by running xfstests with test_dummy_encryption
with and without the 'inlinecrypt' mount option, and there were no
meaningful regressions. One regression was for generic/587 on ext4,
but that test isn't compatible with test_dummy_encryption in the first
place, and the test "incorrectly" passes without the 'inlinecrypt' mount
option - a patch will be sent out to exclude that test when
test_dummy_encryption is turned on with ext4 (like the other quota related
tests that use user visible quota files). The other regression was for
generic/252 on ext4, which does direct I/O with a buffer aligned to the
block device's blocksize, but not necessarily aligned to the filesystem's
block size, which direct I/O with fscrypt requires.

Changes v2 => v3:
 - add changelog to coverletter

Changes v1 => v2:
 - Fix bug in f2fs caused by replacing f2fs_post_read_required() with
   !fscrypt_dio_supported() since the latter doesn't check for
   compressed inodes unlike the former.
 - Add patches 6 and 7 for fscrypt documentation
 - cleanups and comments

Eric Biggers (5):
  fscrypt: Add functions for direct I/O support
  direct-io: add support for fscrypt using blk-crypto
  iomap: support direct I/O with fscrypt using blk-crypto
  ext4: support direct I/O with fscrypt using blk-crypto
  f2fs: support direct I/O with fscrypt using blk-crypto

Satya Tangirala (2):
  fscrypt: document inline encryption support
  fscrypt: update documentation for direct I/O support

 Documentation/filesystems/fscrypt.rst | 36 +++++++++++-
 fs/crypto/crypto.c                    |  8 +++
 fs/crypto/inline_crypt.c              | 80 +++++++++++++++++++++++++++
 fs/direct-io.c                        | 15 ++++-
 fs/ext4/file.c                        | 10 ++--
 fs/f2fs/f2fs.h                        |  6 +-
 fs/iomap/direct-io.c                  |  8 +++
 include/linux/fscrypt.h               | 19 +++++++
 8 files changed, 173 insertions(+), 9 deletions(-)

-- 
2.28.0.rc0.105.gf9edc3c819-goog


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

* [PATCH v3 1/7] fscrypt: Add functions for direct I/O support
  2020-07-17  1:45 [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
@ 2020-07-17  1:45 ` Satya Tangirala
  2020-07-20 20:14   ` Eric Biggers
  2020-07-17  1:45 ` [PATCH v3 2/7] direct-io: add support for fscrypt using blk-crypto Satya Tangirala
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Satya Tangirala @ 2020-07-17  1:45 UTC (permalink / raw)
  To: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4
  Cc: linux-xfs, Eric Biggers, Satya Tangirala

From: Eric Biggers <ebiggers@google.com>

Introduce fscrypt_dio_supported() to check whether a direct I/O request
is unsupported due to encryption constraints, and
fscrypt_limit_io_pages() to check how many pages may be added to a bio
being prepared for direct I/O.

The IV_INO_LBLK_32 fscrypt policy introduced the possibility that DUNs
in logically continuous file blocks might wrap from 0xffffffff to 0.
Since this was particularly difficult to handle when block_size !=
PAGE_SIZE, fscrypt only supports blk-crypto en/decryption with
the IV_INO_LBLK_32 policy when block_size == PAGE_SIZE, and ensures that
the DUN never wraps around within any submitted bio.
fscrypt_limit_io_pages() can be used to determine the number of logically
contiguous blocks/pages that may be added to the bio without causing the
DUN to wrap around within the bio. This is an alternative to calling
fscrypt_mergeable_bio() on each page in a range of logically contiguous
pages.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Co-developed-by: Satya Tangirala <satyat@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
---
 fs/crypto/crypto.c       |  8 ++++
 fs/crypto/inline_crypt.c | 80 ++++++++++++++++++++++++++++++++++++++++
 include/linux/fscrypt.h  | 19 ++++++++++
 3 files changed, 107 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..f5af6a63e04c 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,82 @@ 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.
+ *
+ * For IV generation methods that can't cause DUN wraparounds
+ * within logically continuous data blocks, the maximum number of pages is
+ * simply @nr_pages. For those IV generation methods that *might* cause DUN
+ * wraparounds, the returned number of pages is the largest possible number of
+ * pages (less than @nr_pages) that can be added to the bio without causing a
+ * DUN wraparound within the bio.
+ *
+ * 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


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

* [PATCH v3 2/7] direct-io: add support for fscrypt using blk-crypto
  2020-07-17  1:45 [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
  2020-07-17  1:45 ` [PATCH v3 1/7] fscrypt: Add functions for direct I/O support Satya Tangirala
@ 2020-07-17  1:45 ` Satya Tangirala
  2020-07-17  1:45 ` [PATCH v3 3/7] iomap: support direct I/O with " Satya Tangirala
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Satya Tangirala @ 2020-07-17  1:45 UTC (permalink / raw)
  To: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4
  Cc: linux-xfs, Eric Biggers, Satya Tangirala

From: Eric Biggers <ebiggers@google.com>

Set bio crypt contexts on bios by calling into fscrypt when required,
and explicitly check for DUN continuity when adding pages to the bio.
(While DUN continuity is usually implied by logical block contiguity,
this is not the case when using certain fscrypt IV generation methods
like IV_INO_LBLK_32).

Signed-off-by: Eric Biggers <ebiggers@google.com>
Co-developed-by: Satya Tangirala <satyat@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
---
 fs/direct-io.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/fs/direct-io.c b/fs/direct-io.c
index 6d5370eac2a8..f27f7e3780ee 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fs.h>
+#include <linux/fscrypt.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/highmem.h>
@@ -411,6 +412,7 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio,
 	      sector_t first_sector, int nr_vecs)
 {
 	struct bio *bio;
+	struct inode *inode = dio->inode;
 
 	/*
 	 * bio_alloc() is guaranteed to return a bio when allowed to sleep and
@@ -418,6 +420,9 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio,
 	 */
 	bio = bio_alloc(GFP_KERNEL, nr_vecs);
 
+	fscrypt_set_bio_crypt_ctx(bio, inode,
+				  sdio->cur_page_fs_offset >> inode->i_blkbits,
+				  GFP_KERNEL);
 	bio_set_dev(bio, bdev);
 	bio->bi_iter.bi_sector = first_sector;
 	bio_set_op_attrs(bio, dio->op, dio->op_flags);
@@ -782,9 +787,17 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio,
 		 * current logical offset in the file does not equal what would
 		 * be the next logical offset in the bio, submit the bio we
 		 * have.
+		 *
+		 * When fscrypt inline encryption is used, data unit number
+		 * (DUN) contiguity is also required.  Normally that's implied
+		 * by logical contiguity.  However, certain IV generation
+		 * methods (e.g. IV_INO_LBLK_32) don't guarantee it.  So, we
+		 * must explicitly check fscrypt_mergeable_bio() too.
 		 */
 		if (sdio->final_block_in_bio != sdio->cur_page_block ||
-		    cur_offset != bio_next_offset)
+		    cur_offset != bio_next_offset ||
+		    !fscrypt_mergeable_bio(sdio->bio, dio->inode,
+					   cur_offset >> dio->inode->i_blkbits))
 			dio_bio_submit(dio, sdio);
 	}
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog


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

* [PATCH v3 3/7] iomap: support direct I/O with fscrypt using blk-crypto
  2020-07-17  1:45 [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
  2020-07-17  1:45 ` [PATCH v3 1/7] fscrypt: Add functions for direct I/O support Satya Tangirala
  2020-07-17  1:45 ` [PATCH v3 2/7] direct-io: add support for fscrypt using blk-crypto Satya Tangirala
@ 2020-07-17  1:45 ` Satya Tangirala
  2020-07-20 19:29   ` Eric Biggers
  2020-07-17  1:45 ` [PATCH v3 4/7] ext4: " Satya Tangirala
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Satya Tangirala @ 2020-07-17  1:45 UTC (permalink / raw)
  To: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4
  Cc: linux-xfs, Eric Biggers, Satya Tangirala

From: Eric Biggers <ebiggers@google.com>

Wire up iomap direct I/O with the fscrypt additions for direct I/O,
and set bio crypt contexts on bios when appropriate.

Make iomap_dio_bio_actor() call fscrypt_limit_io_pages() to ensure that
DUNs remain contiguous within a bio, since it works directly with logical
ranges and can't call fscrypt_mergeable_bio() on each page.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Co-developed-by: Satya Tangirala <satyat@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
---
 fs/iomap/direct-io.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index ec7b78e6feca..4507dc16dbe5 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -6,6 +6,7 @@
 #include <linux/module.h>
 #include <linux/compiler.h>
 #include <linux/fs.h>
+#include <linux/fscrypt.h>
 #include <linux/iomap.h>
 #include <linux/backing-dev.h>
 #include <linux/uio.h>
@@ -183,11 +184,14 @@ static void
 iomap_dio_zero(struct iomap_dio *dio, struct iomap *iomap, loff_t pos,
 		unsigned len)
 {
+	struct inode *inode = file_inode(dio->iocb->ki_filp);
 	struct page *page = ZERO_PAGE(0);
 	int flags = REQ_SYNC | REQ_IDLE;
 	struct bio *bio;
 
 	bio = bio_alloc(GFP_KERNEL, 1);
+	fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits,
+				  GFP_KERNEL);
 	bio_set_dev(bio, iomap->bdev);
 	bio->bi_iter.bi_sector = iomap_sector(iomap, pos);
 	bio->bi_private = dio;
@@ -253,6 +257,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
 		ret = nr_pages;
 		goto out;
 	}
+	nr_pages = fscrypt_limit_io_pages(inode, pos, nr_pages);
 
 	if (need_zeroout) {
 		/* zero out from the start of the block to the write offset */
@@ -270,6 +275,8 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
 		}
 
 		bio = bio_alloc(GFP_KERNEL, nr_pages);
+		fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits,
+					  GFP_KERNEL);
 		bio_set_dev(bio, iomap->bdev);
 		bio->bi_iter.bi_sector = iomap_sector(iomap, pos);
 		bio->bi_write_hint = dio->iocb->ki_hint;
@@ -307,6 +314,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
 		copied += n;
 
 		nr_pages = iov_iter_npages(dio->submit.iter, BIO_MAX_PAGES);
+		nr_pages = fscrypt_limit_io_pages(inode, pos, nr_pages);
 		iomap_dio_submit_bio(dio, iomap, bio, pos);
 		pos += n;
 	} while (nr_pages);
-- 
2.28.0.rc0.105.gf9edc3c819-goog


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

* [PATCH v3 4/7] ext4: support direct I/O with fscrypt using blk-crypto
  2020-07-17  1:45 [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
                   ` (2 preceding siblings ...)
  2020-07-17  1:45 ` [PATCH v3 3/7] iomap: support direct I/O with " Satya Tangirala
@ 2020-07-17  1:45 ` Satya Tangirala
  2020-07-17  1:45 ` [PATCH v3 5/7] f2fs: " Satya Tangirala
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Satya Tangirala @ 2020-07-17  1:45 UTC (permalink / raw)
  To: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4
  Cc: linux-xfs, Eric Biggers, Satya Tangirala

From: Eric Biggers <ebiggers@google.com>

Wire up ext4 with fscrypt direct I/O support. direct I/O with fscrypt is
only supported through blk-crypto (i.e. CONFIG_BLK_INLINE_ENCRYPTION must
have been enabled, the 'inlinecrypt' mount option must have been specified,
and either hardware inline encryption support must be present or
CONFIG_BLK_INLINE_ENCYRPTION_FALLBACK must have been enabled). Further,
direct I/O on encrypted files is only supported when I/O is aligned
to the filesystem block size (which is *not* necessarily the same as the
block device's block size).

Signed-off-by: Eric Biggers <ebiggers@google.com>
Co-developed-by: Satya Tangirala <satyat@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
---
 fs/ext4/file.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 2a01e31a032c..d534f72675d9 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -36,9 +36,11 @@
 #include "acl.h"
 #include "truncate.h"
 
-static bool ext4_dio_supported(struct inode *inode)
+static bool ext4_dio_supported(struct kiocb *iocb, struct iov_iter *iter)
 {
-	if (IS_ENABLED(CONFIG_FS_ENCRYPTION) && IS_ENCRYPTED(inode))
+	struct inode *inode = file_inode(iocb->ki_filp);
+
+	if (!fscrypt_dio_supported(iocb, iter))
 		return false;
 	if (fsverity_active(inode))
 		return false;
@@ -61,7 +63,7 @@ static ssize_t ext4_dio_read_iter(struct kiocb *iocb, struct iov_iter *to)
 		inode_lock_shared(inode);
 	}
 
-	if (!ext4_dio_supported(inode)) {
+	if (!ext4_dio_supported(iocb, to)) {
 		inode_unlock_shared(inode);
 		/*
 		 * Fallback to buffered I/O if the operation being performed on
@@ -490,7 +492,7 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	}
 
 	/* Fallback to buffered I/O if the inode does not support direct I/O. */
-	if (!ext4_dio_supported(inode)) {
+	if (!ext4_dio_supported(iocb, from)) {
 		if (ilock_shared)
 			inode_unlock_shared(inode);
 		else
-- 
2.28.0.rc0.105.gf9edc3c819-goog


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

* [PATCH v3 5/7] f2fs: support direct I/O with fscrypt using blk-crypto
  2020-07-17  1:45 [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
                   ` (3 preceding siblings ...)
  2020-07-17  1:45 ` [PATCH v3 4/7] ext4: " Satya Tangirala
@ 2020-07-17  1:45 ` Satya Tangirala
  2020-07-17  1:45 ` [PATCH v3 6/7] fscrypt: document inline encryption support Satya Tangirala
  2020-07-17  1:45 ` [PATCH v3 7/7] fscrypt: update documentation for direct I/O support Satya Tangirala
  6 siblings, 0 replies; 12+ messages in thread
From: Satya Tangirala @ 2020-07-17  1:45 UTC (permalink / raw)
  To: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4
  Cc: linux-xfs, Eric Biggers, Satya Tangirala

From: Eric Biggers <ebiggers@google.com>

Wire up f2fs with fscrypt direct I/O support. direct I/O with fscrypt is
only supported through blk-crypto (i.e. CONFIG_BLK_INLINE_ENCRYPTION must
have been enabled, the 'inlinecrypt' mount option must have been specified,
and either hardware inline encryption support must be present or
CONFIG_BLK_INLINE_ENCYRPTION_FALLBACK must have been enabled). Further,
direct I/O on encrypted files is only supported when I/O is aligned
to the filesystem block size (which is *not* necessarily the same as the
block device's block size).

Signed-off-by: Eric Biggers <ebiggers@google.com>
Co-developed-by: Satya Tangirala <satyat@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
---
 fs/f2fs/f2fs.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index b35a50f4953c..978130b5a195 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4082,7 +4082,11 @@ static inline bool f2fs_force_buffered_io(struct inode *inode,
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	int rw = iov_iter_rw(iter);
 
-	if (f2fs_post_read_required(inode))
+	if (!fscrypt_dio_supported(iocb, iter))
+		return true;
+	if (fsverity_active(inode))
+		return true;
+	if (f2fs_compressed_file(inode))
 		return true;
 	if (f2fs_is_multi_device(sbi))
 		return true;
-- 
2.28.0.rc0.105.gf9edc3c819-goog


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

* [PATCH v3 6/7] fscrypt: document inline encryption support
  2020-07-17  1:45 [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
                   ` (4 preceding siblings ...)
  2020-07-17  1:45 ` [PATCH v3 5/7] f2fs: " Satya Tangirala
@ 2020-07-17  1:45 ` Satya Tangirala
  2020-07-20 19:34   ` Eric Biggers
  2020-07-17  1:45 ` [PATCH v3 7/7] fscrypt: update documentation for direct I/O support Satya Tangirala
  6 siblings, 1 reply; 12+ messages in thread
From: Satya Tangirala @ 2020-07-17  1:45 UTC (permalink / raw)
  To: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4
  Cc: linux-xfs, Satya Tangirala

Update the fscrypt documentation file for inline encryption support.

Signed-off-by: Satya Tangirala <satyat@google.com>
---
 Documentation/filesystems/fscrypt.rst | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index f5d8b0303ddf..f3d87a1a0a7f 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -1204,6 +1204,18 @@ buffer.  Some filesystems, such as UBIFS, already use temporary
 buffers regardless of encryption.  Other filesystems, such as ext4 and
 F2FS, have to allocate bounce pages specially for encryption.
 
+Fscrypt is also able to use inline encryption hardware instead of the
+kernel crypto API for en/decryption of file contents.  When possible, and
+if directed to do so (by specifying the 'inlinecrypt' mount option for
+an ext4/F2FS filesystem), it adds encryption contexts to bios and
+uses blk-crypto to perform the en/decryption instead of making use
+of the above read/write path changes.  Of course, even if directed to make
+use of inline encryption, fscrypt will only be able to do so if either
+hardware inline encryption support is available for the selected encryption
+algorithm or CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK is selected.  If neither
+is the case, fscrypt will fall back to using the above mentioned read/write
+path changes for en/decryption.
+
 Filename hashing and encoding
 -----------------------------
 
@@ -1250,7 +1262,9 @@ Tests
 
 To test fscrypt, use xfstests, which is Linux's de facto standard
 filesystem test suite.  First, run all the tests in the "encrypt"
-group on the relevant filesystem(s).  For example, to test ext4 and
+group on the relevant filesystem(s).  One can also run the tests
+with the 'inlinecrypt' mount option to test the implementation for
+inline encryption support.  For example, to test ext4 and
 f2fs encryption using `kvm-xfstests
 <https://github.com/tytso/xfstests-bld/blob/master/Documentation/kvm-quickstart.md>`_::
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog


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

* [PATCH v3 7/7] fscrypt: update documentation for direct I/O support
  2020-07-17  1:45 [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
                   ` (5 preceding siblings ...)
  2020-07-17  1:45 ` [PATCH v3 6/7] fscrypt: document inline encryption support Satya Tangirala
@ 2020-07-17  1:45 ` Satya Tangirala
  2020-07-20 19:40   ` Eric Biggers
  6 siblings, 1 reply; 12+ messages in thread
From: Satya Tangirala @ 2020-07-17  1:45 UTC (permalink / raw)
  To: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4
  Cc: linux-xfs, Satya Tangirala

Update fscrypt documentation to reflect the addition of direct I/O support
and document the necessary conditions for direct I/O on encrypted files.

Signed-off-by: Satya Tangirala <satyat@google.com>
---
 Documentation/filesystems/fscrypt.rst | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index f3d87a1a0a7f..95c76a5f0567 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -1049,8 +1049,10 @@ astute users may notice some differences in behavior:
   may be used to overwrite the source files but isn't guaranteed to be
   effective on all filesystems and storage devices.
 
-- Direct I/O is not supported on encrypted files.  Attempts to use
-  direct I/O on such files will fall back to buffered I/O.
+- Direct I/O is supported on encrypted files only under some circumstances
+  (see `Direct I/O support`_ for details). When these circumstances are not
+  met, attempts to use direct I/O on such files will fall back to buffered
+  I/O.
 
 - The fallocate operations FALLOC_FL_COLLAPSE_RANGE and
   FALLOC_FL_INSERT_RANGE are not supported on encrypted files and will
@@ -1257,6 +1259,20 @@ without the key is subject to change in the future.  It is only meant
 as a way to temporarily present valid filenames so that commands like
 ``rm -r`` work as expected on encrypted directories.
 
+Direct I/O support
+------------------
+
+Direct I/O on encrypted files is supported through blk-crypto. In
+particular, this means the kernel must have CONFIG_BLK_INLINE_ENCRYPTION
+enabled, the filesystem must have had the 'inlinecrypt' mount option
+specified, and either hardware inline encryption must be present, or
+CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK must have been enabled. Further,
+any I/O must be aligned to the filesystem block size (*not* necessarily
+the same as the block device's block size) - in particular, any userspace
+buffer into which data is read/written from must also be aligned to the
+filesystem block size. If any of these conditions isn't met, attempts to do
+direct I/O on an encrypted file will fall back to buffered I/O.
+
 Tests
 =====
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog


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

* Re: [PATCH v3 3/7] iomap: support direct I/O with fscrypt using blk-crypto
  2020-07-17  1:45 ` [PATCH v3 3/7] iomap: support direct I/O with " Satya Tangirala
@ 2020-07-20 19:29   ` Eric Biggers
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2020-07-20 19:29 UTC (permalink / raw)
  To: Satya Tangirala
  Cc: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4, linux-xfs

On Fri, Jul 17, 2020 at 01:45:36AM +0000, Satya Tangirala wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Wire up iomap direct I/O with the fscrypt additions for direct I/O,
> and set bio crypt contexts on bios when appropriate.
> 
> Make iomap_dio_bio_actor() call fscrypt_limit_io_pages() to ensure that
> DUNs remain contiguous within a bio, since it works directly with logical
> ranges and can't call fscrypt_mergeable_bio() on each page.

This commit message is still confusing.

How about the following:

"Wire up iomap direct I/O with the fscrypt additions for direct I/O.
This allows ext4 to support direct I/O on encrypted files when inline
encryption is enabled.

This change consists of two parts:

- Set a bio_crypt_ctx on bios for encrypted files, so that the file
  contents get encrypted (or decrypted).

- Ensure that encryption data unit numbers (DUNs) are contiguous within
  each bio.  Use the new function fscrypt_limit_io_pages() for this,
  since the iomap code works directly with logical ranges and thus
  doesn't have a chance to call fscrypt_mergeable_bio() on each page.

Note that fscrypt_limit_io_pages() is normally a no-op, as normally the
DUNs simply increment along with the logical blocks.  But it's needed to
handle an edge case in one of the fscrypt IV generation methods."

> @@ -183,11 +184,14 @@ static void
>  iomap_dio_zero(struct iomap_dio *dio, struct iomap *iomap, loff_t pos,
>  		unsigned len)
>  {
> +	struct inode *inode = file_inode(dio->iocb->ki_filp);
>  	struct page *page = ZERO_PAGE(0);
>  	int flags = REQ_SYNC | REQ_IDLE;
>  	struct bio *bio;
>  
>  	bio = bio_alloc(GFP_KERNEL, 1);
> +	fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits,
> +				  GFP_KERNEL);
>  	bio_set_dev(bio, iomap->bdev);
>  	bio->bi_iter.bi_sector = iomap_sector(iomap, pos);
>  	bio->bi_private = dio;

iomap_dio_zero() is only used on partial filesystem blocks.  But, we
only allow direct I/O on encrypted files when the I/O is
filesystem-block-aligned.

So this part appears to be unnecessary.

How about replacing it with:

	/* encrypted direct I/O is guaranteed to be fs-block aligned */
	WARN_ON_ONCE(fscrypt_needs_contents_encryption(inode));

> @@ -253,6 +257,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
>  		ret = nr_pages;
>  		goto out;
>  	}
> +	nr_pages = fscrypt_limit_io_pages(inode, pos, nr_pages);
>  
>  	if (need_zeroout) {
>  		/* zero out from the start of the block to the write offset */
> @@ -270,6 +275,8 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
>  		}
>  
>  		bio = bio_alloc(GFP_KERNEL, nr_pages);
> +		fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits,
> +					  GFP_KERNEL);
>  		bio_set_dev(bio, iomap->bdev);
>  		bio->bi_iter.bi_sector = iomap_sector(iomap, pos);
>  		bio->bi_write_hint = dio->iocb->ki_hint;
> @@ -307,6 +314,7 @@ iomap_dio_bio_actor(struct inode *inode, loff_t pos, loff_t length,
>  		copied += n;
>  
>  		nr_pages = iov_iter_npages(dio->submit.iter, BIO_MAX_PAGES);
> +		nr_pages = fscrypt_limit_io_pages(inode, pos, nr_pages);
>  		iomap_dio_submit_bio(dio, iomap, bio, pos);
>  		pos += n;
>  	} while (nr_pages);

I think the part at the end is wrong.

We want to limit the *next* bio, not the current one.

So 'pos' needs to be updated first.

I think it should be:

                iomap_dio_submit_bio(dio, iomap, bio, pos);
                pos += n;
                nr_pages = iov_iter_npages(dio->submit.iter, BIO_MAX_PAGES);
                nr_pages = fscrypt_limit_io_pages(inode, pos, nr_pages);

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

* Re: [PATCH v3 6/7] fscrypt: document inline encryption support
  2020-07-17  1:45 ` [PATCH v3 6/7] fscrypt: document inline encryption support Satya Tangirala
@ 2020-07-20 19:34   ` Eric Biggers
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2020-07-20 19:34 UTC (permalink / raw)
  To: Satya Tangirala
  Cc: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4, linux-xfs

On Fri, Jul 17, 2020 at 01:45:39AM +0000, Satya Tangirala wrote:
> Update the fscrypt documentation file for inline encryption support.
> 
> Signed-off-by: Satya Tangirala <satyat@google.com>

Reviewed-by: Eric Biggers <ebiggers@google.com>

> diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
> index f5d8b0303ddf..f3d87a1a0a7f 100644
> --- a/Documentation/filesystems/fscrypt.rst
> +++ b/Documentation/filesystems/fscrypt.rst
> @@ -1204,6 +1204,18 @@ buffer.  Some filesystems, such as UBIFS, already use temporary
>  buffers regardless of encryption.  Other filesystems, such as ext4 and
>  F2FS, have to allocate bounce pages specially for encryption.
>  
> +Fscrypt is also able to use inline encryption hardware instead of the
> +kernel crypto API for en/decryption of file contents.  When possible, and
> +if directed to do so (by specifying the 'inlinecrypt' mount option for
> +an ext4/F2FS filesystem), it adds encryption contexts to bios and
> +uses blk-crypto to perform the en/decryption instead of making use
> +of the above read/write path changes.  Of course, even if directed to make
> +use of inline encryption, fscrypt will only be able to do so if either
> +hardware inline encryption support is available for the selected encryption
> +algorithm or CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK is selected.  If neither
> +is the case, fscrypt will fall back to using the above mentioned read/write
> +path changes for en/decryption.
> +

Nit: most of the text in this file is formatted with textwidth=70.

>  Filename hashing and encoding
>  -----------------------------
>  
> @@ -1250,7 +1262,9 @@ Tests
>  
>  To test fscrypt, use xfstests, which is Linux's de facto standard
>  filesystem test suite.  First, run all the tests in the "encrypt"
> -group on the relevant filesystem(s).  For example, to test ext4 and
> +group on the relevant filesystem(s).  One can also run the tests
> +with the 'inlinecrypt' mount option to test the implementation for
> +inline encryption support.  For example, to test ext4 and
>  f2fs encryption using `kvm-xfstests
>  <https://github.com/tytso/xfstests-bld/blob/master/Documentation/kvm-quickstart.md>`_::
>  
> -- 
> 2.28.0.rc0.105.gf9edc3c819-goog
> 

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

* Re: [PATCH v3 7/7] fscrypt: update documentation for direct I/O support
  2020-07-17  1:45 ` [PATCH v3 7/7] fscrypt: update documentation for direct I/O support Satya Tangirala
@ 2020-07-20 19:40   ` Eric Biggers
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2020-07-20 19:40 UTC (permalink / raw)
  To: Satya Tangirala
  Cc: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4, linux-xfs

On Fri, Jul 17, 2020 at 01:45:40AM +0000, Satya Tangirala wrote:
> Update fscrypt documentation to reflect the addition of direct I/O support
> and document the necessary conditions for direct I/O on encrypted files.
> 
> Signed-off-by: Satya Tangirala <satyat@google.com>
> ---
>  Documentation/filesystems/fscrypt.rst | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
> index f3d87a1a0a7f..95c76a5f0567 100644
> --- a/Documentation/filesystems/fscrypt.rst
> +++ b/Documentation/filesystems/fscrypt.rst
> @@ -1049,8 +1049,10 @@ astute users may notice some differences in behavior:
>    may be used to overwrite the source files but isn't guaranteed to be
>    effective on all filesystems and storage devices.
>  
> -- Direct I/O is not supported on encrypted files.  Attempts to use
> -  direct I/O on such files will fall back to buffered I/O.
> +- Direct I/O is supported on encrypted files only under some circumstances
> +  (see `Direct I/O support`_ for details). When these circumstances are not
> +  met, attempts to use direct I/O on such files will fall back to buffered
> +  I/O.

Nit: "such files" => "encrypted files".

Nit: most of the text in this file is formatted with textwidth=70.

>  
>  - The fallocate operations FALLOC_FL_COLLAPSE_RANGE and
>    FALLOC_FL_INSERT_RANGE are not supported on encrypted files and will
> @@ -1257,6 +1259,20 @@ without the key is subject to change in the future.  It is only meant
>  as a way to temporarily present valid filenames so that commands like
>  ``rm -r`` work as expected on encrypted directories.
>  
> +Direct I/O support
> +------------------
> +
> +Direct I/O on encrypted files is supported through blk-crypto. In
> +particular, this means the kernel must have CONFIG_BLK_INLINE_ENCRYPTION
> +enabled, the filesystem must have had the 'inlinecrypt' mount option
> +specified, and either hardware inline encryption must be present, or
> +CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK must have been enabled. Further,
> +any I/O must be aligned to the filesystem block size (*not* necessarily
> +the same as the block device's block size) - in particular, any userspace
> +buffer into which data is read/written from must also be aligned to the
> +filesystem block size. If any of these conditions isn't met, attempts to do
> +direct I/O on an encrypted file will fall back to buffered I/O.

This is placing "Direct I/O support" as a subsection of the
"Implementation details" section.

But the direct I/O support is more than just an implementation detail.

How about moving it to a top-level section?

I'd probably put it between "Access semantics" and
"Encryption policy enforcement".

- Eric

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

* Re: [PATCH v3 1/7] fscrypt: Add functions for direct I/O support
  2020-07-17  1:45 ` [PATCH v3 1/7] fscrypt: Add functions for direct I/O support Satya Tangirala
@ 2020-07-20 20:14   ` Eric Biggers
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2020-07-20 20:14 UTC (permalink / raw)
  To: Satya Tangirala
  Cc: linux-fscrypt, linux-fsdevel, linux-f2fs-devel, linux-ext4, linux-xfs

On Fri, Jul 17, 2020 at 01:45:34AM +0000, 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, and
> fscrypt_limit_io_pages() to check how many pages may be added to a bio
> being prepared for direct I/O.
> 
> The IV_INO_LBLK_32 fscrypt policy introduced the possibility that DUNs
> in logically continuous file blocks might wrap from 0xffffffff to 0.
> Since this was particularly difficult to handle when block_size !=
> PAGE_SIZE, fscrypt only supports blk-crypto en/decryption with
> the IV_INO_LBLK_32 policy when block_size == PAGE_SIZE, and ensures that
> the DUN never wraps around within any submitted bio.
> fscrypt_limit_io_pages() can be used to determine the number of logically
> contiguous blocks/pages that may be added to the bio without causing the
> DUN to wrap around within the bio. This is an alternative to calling
> fscrypt_mergeable_bio() on each page in a range of logically contiguous
> pages.

This is a bit hard to read, especially the second paragraph.  How about:


"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 thus needs doesn't have a chance to call
fscrypt_mergeable_bio() on every block or page.  So we need a function
which limits a logical range in one go."


In particular, the detail about PAGE_SIZE better belongs in the code, I think.

> +/**
> + * 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.
> + *
> + * For IV generation methods that can't cause DUN wraparounds
> + * within logically continuous data blocks, the maximum number of pages is
> + * simply @nr_pages. For those IV generation methods that *might* cause DUN
> + * wraparounds, the returned number of pages is the largest possible number of
> + * pages (less than @nr_pages) that can be added to the bio without causing a
> + * DUN wraparound within the bio.

How about replacing the second paragraph here with:
 
 * 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.

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

end of thread, back to index

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-17  1:45 [PATCH v3 0/7] add support for direct I/O with fscrypt using blk-crypto Satya Tangirala
2020-07-17  1:45 ` [PATCH v3 1/7] fscrypt: Add functions for direct I/O support Satya Tangirala
2020-07-20 20:14   ` Eric Biggers
2020-07-17  1:45 ` [PATCH v3 2/7] direct-io: add support for fscrypt using blk-crypto Satya Tangirala
2020-07-17  1:45 ` [PATCH v3 3/7] iomap: support direct I/O with " Satya Tangirala
2020-07-20 19:29   ` Eric Biggers
2020-07-17  1:45 ` [PATCH v3 4/7] ext4: " Satya Tangirala
2020-07-17  1:45 ` [PATCH v3 5/7] f2fs: " Satya Tangirala
2020-07-17  1:45 ` [PATCH v3 6/7] fscrypt: document inline encryption support Satya Tangirala
2020-07-20 19:34   ` Eric Biggers
2020-07-17  1:45 ` [PATCH v3 7/7] fscrypt: update documentation for direct I/O support Satya Tangirala
2020-07-20 19:40   ` Eric Biggers

Linux-FSCrypt Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-fscrypt/0 linux-fscrypt/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-fscrypt linux-fscrypt/ https://lore.kernel.org/linux-fscrypt \
		linux-fscrypt@vger.kernel.org
	public-inbox-index linux-fscrypt

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-fscrypt


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git