[f2fs-dev] [PATCH V2 00/13] Consolidate FS read I/O callbacks code

2019-04-27 Thread Chandan Rajendra
This patchset moves the "FS read I/O callbacks" code into a file of its
own (i.e. fs/read_callbacks.c) and modifies the generic
do_mpage_readpge() to make use of the functionality provided.

"FS read I/O callbacks" code implements the state machine that needs
to be executed after reading data from files that are encrypted and/or
have verity metadata associated with them.

With these changes in place, the patchset changes Ext4 to use
mpage_readpage[s] instead of its own custom ext4_readpage[s]()
functions. This is done to reduce duplicity of code across
filesystems. Also, "FS read I/O callbacks" source files will be built
only if one of CONFIG_FS_ENCRYPTION and CONFIG_FS_VERITY is enabled.

The patchset also modifies fs/buffer.c and fscrypt functionality to
get file encryption/decryption to work with subpage-sized blocks.

The following fixes from Eric Biggers are prerequisites for this
patchset,
  fscrypt: fix race where ->lookup() marks plaintext dentry as ciphertext
  fscrypt: only set dentry_operations on ciphertext dentries
  fscrypt: clear DCACHE_ENCRYPTED_NAME when unaliasing directory
  fscrypt: fix race allowing rename() and link() of ciphertext dentries
  fscrypt: clean up and improve dentry revalidation

The patches can also be obtained from,
"https://github.com/chandanr/linux.git subpage-encryption-v2"

Changelog:
V1 -> V2:
1. Removed the phrase "post_read_process" from file names and
   functions. Instead we now use the phrase "read_callbacks" in its
   place.
2. When performing changes associated with (1), the changes made by
   the patch "Remove the term 'bio' from post read processing" are
   made in the earlier patch "Consolidate 'read callbacks' into a new
   file". Hence the patch "Remove the term 'bio' from post read
   processing" is removed from the patchset.

RFC V2 -> V1:
1. Test and verify FS_CFLG_OWN_PAGES subset of fscrypt_encrypt_page()
   code by executing fstests on UBIFS.
2. Implement F2fs function call back to check if the contents of a
   page holding a verity file's data needs to be verified.

RFC V1 -> RFC V2:
1. Describe the purpose of "Post processing code" in the cover letter.
2. Fix build errors when CONFIG_FS_VERITY is enabled.

Chandan Rajendra (13):
  ext4: Clear BH_Uptodate flag on decryption error
  Consolidate "read callbacks" into a new file
  fsverity: Add call back to decide if verity check has to be performed
  fsverity: Add call back to determine readpage limit
  fs/mpage.c: Integrate read callbacks
  ext4: Wire up ext4_readpage[s] to use mpage_readpage[s]
  Add decryption support for sub-pagesized blocks
  ext4: Decrypt all boundary blocks when doing buffered write
  ext4: Decrypt the block that needs to be partially zeroed
  fscrypt_encrypt_page: Loop across all blocks mapped by a page range
  ext4: Compute logical block and the page range to be encrypted
  fscrypt_zeroout_range: Encrypt all zeroed out blocks of a page
  ext4: Enable encryption for subpage-sized blocks

 Documentation/filesystems/fscrypt.rst |   4 +-
 fs/Kconfig|   4 +
 fs/Makefile   |   4 +
 fs/buffer.c   |  83 +++--
 fs/crypto/Kconfig |   1 +
 fs/crypto/bio.c   | 111 ---
 fs/crypto/crypto.c|  73 +++--
 fs/crypto/fscrypt_private.h   |   3 +
 fs/ext4/Makefile  |   2 +-
 fs/ext4/ext4.h|   2 -
 fs/ext4/inode.c   |  47 ++-
 fs/ext4/page-io.c |   9 +-
 fs/ext4/readpage.c| 445 --
 fs/ext4/super.c   |  39 ++-
 fs/f2fs/data.c| 148 ++---
 fs/f2fs/super.c   |  15 +-
 fs/mpage.c|  51 ++-
 fs/read_callbacks.c   | 155 +
 fs/verity/Kconfig |   1 +
 fs/verity/verify.c|  12 +
 include/linux/buffer_head.h   |   1 +
 include/linux/fscrypt.h   |  20 +-
 include/linux/fsverity.h  |   2 +
 include/linux/read_callbacks.h|  22 ++
 24 files changed, 522 insertions(+), 732 deletions(-)
 delete mode 100644 fs/ext4/readpage.c
 create mode 100644 fs/read_callbacks.c
 create mode 100644 include/linux/read_callbacks.h

-- 
2.19.1



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


[f2fs-dev] [PATCH V2 05/13] fs/mpage.c: Integrate read callbacks

2019-04-27 Thread Chandan Rajendra
This commit adds code to make do_mpage_readpage() to be "read
callbacks" aware i.e. for files requiring decryption/verification,
do_mpage_readpage() now allocates a context structure and assigns the
corresponding pointer to bio->bi_private. At endio time, a non-zero
bio->bi_private indicates that after the read operation is performed, the
bio's payload needs to be processed further before handing over the data
to user space.

The context structure is used for tracking the state machine associated
with post read processing.

Signed-off-by: Chandan Rajendra 
---
 fs/mpage.c | 51 ---
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/fs/mpage.c b/fs/mpage.c
index 3f19da75178b..e342b859ee44 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -30,6 +30,10 @@
 #include 
 #include 
 #include 
+#include 
+#if defined(CONFIG_FS_ENCRYPTION) || defined(CONFIG_FS_VERITY)
+#include 
+#endif
 #include "internal.h"
 
 /*
@@ -50,6 +54,20 @@ static void mpage_end_io(struct bio *bio)
int i;
struct bvec_iter_all iter_all;
 
+#if defined(CONFIG_FS_ENCRYPTION) || defined(CONFIG_FS_VERITY)
+   if (!bio->bi_status && bio->bi_private) {
+   struct read_callbacks_ctx *ctx;
+
+   ctx = bio->bi_private;
+
+   read_callbacks(ctx);
+   return;
+   }
+
+   if (bio->bi_private)
+   put_read_callbacks_ctx((struct read_callbacks_ctx 
*)(bio->bi_private));
+#endif
+
bio_for_each_segment_all(bv, bio, i, iter_all) {
struct page *page = bv->bv_page;
page_endio(page, bio_op(bio),
@@ -189,7 +207,13 @@ static struct bio *do_mpage_readpage(struct 
mpage_readpage_args *args)
 
block_in_file = (sector_t)page->index << (PAGE_SHIFT - blkbits);
last_block = block_in_file + args->nr_pages * blocks_per_page;
-   last_block_in_file = (i_size_read(inode) + blocksize - 1) >> blkbits;
+#ifdef CONFIG_FS_VERITY
+   if (IS_VERITY(inode) && inode->i_sb->s_vop->readpage_limit)
+   last_block_in_file = inode->i_sb->s_vop->readpage_limit(inode);
+   else
+#endif
+   last_block_in_file = (i_size_read(inode) + blocksize - 1)
+   >> blkbits;
if (last_block > last_block_in_file)
last_block = last_block_in_file;
page_block = 0;
@@ -277,6 +301,14 @@ static struct bio *do_mpage_readpage(struct 
mpage_readpage_args *args)
if (first_hole != blocks_per_page) {
zero_user_segment(page, first_hole << blkbits, PAGE_SIZE);
if (first_hole == 0) {
+#ifdef CONFIG_FS_VERITY
+   if (IS_VERITY(inode)) {
+   if (!fsverity_check_hole(inode, page)) {
+   SetPageError(page);
+   goto confused;
+   }
+   }
+#endif
SetPageUptodate(page);
unlock_page(page);
goto out;
@@ -299,7 +331,11 @@ static struct bio *do_mpage_readpage(struct 
mpage_readpage_args *args)
 
 alloc_new:
if (args->bio == NULL) {
-   if (first_hole == blocks_per_page) {
+#if defined(CONFIG_FS_ENCRYPTION) || defined(CONFIG_FS_VERITY)
+   struct read_callbacks_ctx *ctx;
+#endif
+   if (first_hole == blocks_per_page
+   && !(IS_ENCRYPTED(inode) || IS_VERITY(inode))) {
if (!bdev_read_page(bdev, blocks[0] << (blkbits - 9),
page))
goto out;
@@ -310,6 +346,15 @@ static struct bio *do_mpage_readpage(struct 
mpage_readpage_args *args)
gfp);
if (args->bio == NULL)
goto confused;
+
+#if defined(CONFIG_FS_ENCRYPTION) || defined(CONFIG_FS_VERITY)
+   ctx = get_read_callbacks_ctx(inode, args->bio, page->index);
+   if (IS_ERR(ctx)) {
+   bio_put(args->bio);
+   args->bio = NULL;
+   goto confused;
+   }
+#endif
}
 
length = first_hole << blkbits;
@@ -331,7 +376,7 @@ static struct bio *do_mpage_readpage(struct 
mpage_readpage_args *args)
 confused:
if (args->bio)
args->bio = mpage_bio_submit(REQ_OP_READ, op_flags, args->bio);
-   if (!PageUptodate(page))
+   if (!PageUptodate(page) && !PageError(page))
block_read_full_page(page, args->get_block);
else
unlock_page(page);
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 13/13] ext4: Enable encryption for subpage-sized blocks

2019-04-27 Thread Chandan Rajendra
Now that we have the code to support encryption for subpage-sized
blocks, this commit removes the conditional check in filesystem mount
code.

The commit also changes the support statement in
Documentation/filesystems/fscrypt.rst to reflect the fact that
encryption of filesystems with blocksize less than page size now works.

Signed-off-by: Chandan Rajendra 
---
 Documentation/filesystems/fscrypt.rst | 4 ++--
 fs/ext4/super.c   | 7 ---
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/Documentation/filesystems/fscrypt.rst 
b/Documentation/filesystems/fscrypt.rst
index 08c23b60e016..ff2fea121da9 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -213,8 +213,8 @@ Contents encryption
 ---
 
 For file contents, each filesystem block is encrypted independently.
-Currently, only the case where the filesystem block size is equal to
-the system's page size (usually 4096 bytes) is supported.
+Starting from Linux kernel 5.3, encryption of filesystems with block
+size less than system's page size is supported.
 
 Each block's IV is set to the logical block number within the file as
 a little endian number, except that:
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8e483afbaa2e..4acfefa98ec5 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4432,13 +4432,6 @@ static int ext4_fill_super(struct super_block *sb, void 
*data, int silent)
}
}
 
-   if ((DUMMY_ENCRYPTION_ENABLED(sbi) || ext4_has_feature_encrypt(sb)) &&
-   (blocksize != PAGE_SIZE)) {
-   ext4_msg(sb, KERN_ERR,
-"Unsupported blocksize for fs encryption");
-   goto failed_mount_wq;
-   }
-
if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) &&
!ext4_has_feature_encrypt(sb)) {
ext4_set_feature_encrypt(sb);
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 04/13] fsverity: Add call back to determine readpage limit

2019-04-27 Thread Chandan Rajendra
Ext4 and F2FS store verity metadata beyond i_size. This commit adds a
call back pointer to "struct fsverity_operations" which helps in
determining the the real file size limit upto which data can be read
from the file.

This call back will be required in order to get do_mpage_readpage()
to read files having verity metadata appended beyond i_size.

Signed-off-by: Chandan Rajendra 
---
 fs/ext4/super.c  | 17 +
 include/linux/fsverity.h |  1 +
 2 files changed, 18 insertions(+)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 63d73b360f1d..8e483afbaa2e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1428,6 +1428,22 @@ static struct page 
*ext4_read_verity_metadata_page(struct inode *inode,
return read_mapping_page(inode->i_mapping, index, NULL);
 }
 
+static loff_t ext4_readpage_limit(struct inode *inode)
+{
+   if (IS_VERITY(inode)) {
+   if (inode->i_verity_info)
+   /* limit to end of metadata region */
+   return fsverity_full_i_size(inode);
+   /*
+* fsverity_info is currently being set up and no user reads are
+* allowed yet.  It's easiest to just not enforce a limit yet.
+*/
+   return inode->i_sb->s_maxbytes;
+   }
+
+   return i_size_read(inode);
+}
+
 static bool ext4_verity_required(struct inode *inode, pgoff_t index)
 {
return index < (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -1438,6 +1454,7 @@ static const struct fsverity_operations ext4_verityops = {
.get_metadata_end   = ext4_get_verity_metadata_end,
.read_metadata_page = ext4_read_verity_metadata_page,
.verity_required= ext4_verity_required,
+   .readpage_limit = ext4_readpage_limit,
 };
 #endif /* CONFIG_FS_VERITY */
 
diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
index b83712d6c79a..fc8113acbbfe 100644
--- a/include/linux/fsverity.h
+++ b/include/linux/fsverity.h
@@ -19,6 +19,7 @@ struct fsverity_operations {
int (*get_metadata_end)(struct inode *inode, loff_t *metadata_end_ret);
struct page *(*read_metadata_page)(struct inode *inode, pgoff_t index);
bool (*verity_required)(struct inode *inode, pgoff_t index);
+   loff_t (*readpage_limit)(struct inode *inode);
 };
 
 #ifdef CONFIG_FS_VERITY
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 02/13] Consolidate "read callbacks" into a new file

2019-04-27 Thread Chandan Rajendra
The "read callbacks" code is used by both Ext4 and F2FS. Hence to
remove duplicity, this commit moves the code into
include/linux/read_callbacks.h and fs/read_callbacks.c.

The corresponding decrypt and verity "work" functions have been moved
inside fscrypt and fsverity sources. With these in place, the read
callbacks code now has to just invoke enqueue functions provided by
fscrypt and fsverity.

Signed-off-by: Chandan Rajendra 
---
 fs/Kconfig |   4 +
 fs/Makefile|   4 +
 fs/crypto/Kconfig  |   1 +
 fs/crypto/bio.c|  23 ++---
 fs/crypto/crypto.c |  17 +--
 fs/crypto/fscrypt_private.h|   3 +
 fs/ext4/ext4.h |   2 -
 fs/ext4/readpage.c | 183 +
 fs/ext4/super.c|   9 +-
 fs/f2fs/data.c | 148 --
 fs/f2fs/super.c|   9 +-
 fs/read_callbacks.c| 136 
 fs/verity/Kconfig  |   1 +
 fs/verity/verify.c |  12 +++
 include/linux/fscrypt.h|  20 +---
 include/linux/read_callbacks.h |  21 
 16 files changed, 251 insertions(+), 342 deletions(-)
 create mode 100644 fs/read_callbacks.c
 create mode 100644 include/linux/read_callbacks.h

diff --git a/fs/Kconfig b/fs/Kconfig
index 97f9eb8df713..03084f2dbeaf 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -308,6 +308,10 @@ config NFS_COMMON
depends on NFSD || NFS_FS || LOCKD
default y
 
+config FS_READ_CALLBACKS
+   bool
+   default n
+
 source "net/sunrpc/Kconfig"
 source "fs/ceph/Kconfig"
 source "fs/cifs/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index 9dd2186e74b5..e0c0fce8cf40 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -21,6 +21,10 @@ else
 obj-y +=   no-block.o
 endif
 
+ifeq ($(CONFIG_FS_READ_CALLBACKS),y)
+obj-y +=   read_callbacks.o
+endif
+
 obj-$(CONFIG_PROC_FS) += proc_namespace.o
 
 obj-y  += notify/
diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig
index f0de238000c0..163c328bcbd4 100644
--- a/fs/crypto/Kconfig
+++ b/fs/crypto/Kconfig
@@ -8,6 +8,7 @@ config FS_ENCRYPTION
select CRYPTO_CTS
select CRYPTO_SHA256
select KEYS
+   select FS_READ_CALLBACKS
help
  Enable encryption of files and directories.  This
  feature is similar to ecryptfs, but it is more memory
diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c
index 5759bcd018cd..27f5618174f2 100644
--- a/fs/crypto/bio.c
+++ b/fs/crypto/bio.c
@@ -24,6 +24,8 @@
 #include 
 #include 
 #include 
+#include 
+
 #include "fscrypt_private.h"
 
 static void __fscrypt_decrypt_bio(struct bio *bio, bool done)
@@ -54,24 +56,15 @@ void fscrypt_decrypt_bio(struct bio *bio)
 }
 EXPORT_SYMBOL(fscrypt_decrypt_bio);
 
-static void completion_pages(struct work_struct *work)
+void fscrypt_decrypt_work(struct work_struct *work)
 {
-   struct fscrypt_ctx *ctx =
-   container_of(work, struct fscrypt_ctx, r.work);
-   struct bio *bio = ctx->r.bio;
+   struct read_callbacks_ctx *ctx =
+   container_of(work, struct read_callbacks_ctx, work);
 
-   __fscrypt_decrypt_bio(bio, true);
-   fscrypt_release_ctx(ctx);
-   bio_put(bio);
-}
+   fscrypt_decrypt_bio(ctx->bio);
 
-void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, struct bio *bio)
-{
-   INIT_WORK(>r.work, completion_pages);
-   ctx->r.bio = bio;
-   fscrypt_enqueue_decrypt_work(>r.work);
+   read_callbacks(ctx);
 }
-EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio);
 
 void fscrypt_pullback_bio_page(struct page **page, bool restore)
 {
@@ -87,7 +80,7 @@ void fscrypt_pullback_bio_page(struct page **page, bool 
restore)
ctx = (struct fscrypt_ctx *)page_private(bounce_page);
 
/* restore control page */
-   *page = ctx->w.control_page;
+   *page = ctx->control_page;
 
if (restore)
fscrypt_restore_control_page(bounce_page);
diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index 3fc84bf2b1e5..ffa9302a7351 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -53,6 +53,7 @@ struct kmem_cache *fscrypt_info_cachep;
 
 void fscrypt_enqueue_decrypt_work(struct work_struct *work)
 {
+   INIT_WORK(work, fscrypt_decrypt_work);
queue_work(fscrypt_read_workqueue, work);
 }
 EXPORT_SYMBOL(fscrypt_enqueue_decrypt_work);
@@ -70,11 +71,11 @@ void fscrypt_release_ctx(struct fscrypt_ctx *ctx)
 {
unsigned long flags;
 
-   if (ctx->flags & FS_CTX_HAS_BOUNCE_BUFFER_FL && ctx->w.bounce_page) {
-   mempool_free(ctx->w.bounce_page, fscrypt_bounce_page_pool);
-   ctx->w.bounce_page = NULL;
+   if (ctx->flags & FS_CTX_HAS_BOUNCE_BUFFER_FL && ctx->bounce_page) {
+   mempool_free(ctx->bounce_page, fscrypt_bounce_page_pool);
+   ctx->bounce_page = NULL;
}
-   ctx->w.control_page = NULL;
+   ctx->control_page = 

[f2fs-dev] [PATCH V2 08/13] ext4: Decrypt all boundary blocks when doing buffered write

2019-04-27 Thread Chandan Rajendra
With subpage sized blocks, ext4_block_write_begin() can have up to two
blocks to decrypt. Hence this commit invokes fscrypt_decrypt_page() for
each of those blocks.

Signed-off-by: Chandan Rajendra 
---
 fs/ext4/inode.c | 33 +++--
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 1327e04334df..51744a3c3964 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1156,12 +1156,14 @@ static int ext4_block_write_begin(struct page *page, 
loff_t pos, unsigned len,
unsigned to = from + len;
struct inode *inode = page->mapping->host;
unsigned block_start, block_end;
-   sector_t block;
+   sector_t block, page_blk_nr;
int err = 0;
unsigned blocksize = inode->i_sb->s_blocksize;
unsigned bbits;
-   struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
+   struct buffer_head *bh, *head, *wait[2];
+   int nr_wait = 0;
bool decrypt = false;
+   int i;
 
BUG_ON(!PageLocked(page));
BUG_ON(from > PAGE_SIZE);
@@ -1213,25 +1215,36 @@ static int ext4_block_write_begin(struct page *page, 
loff_t pos, unsigned len,
!buffer_unwritten(bh) &&
(block_start < from || block_end > to)) {
ll_rw_block(REQ_OP_READ, 0, 1, );
-   *wait_bh++ = bh;
+   wait[nr_wait++] = bh;
decrypt = IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
}
}
/*
 * If we issued read requests, let them complete.
 */
-   while (wait_bh > wait) {
-   wait_on_buffer(*--wait_bh);
-   if (!buffer_uptodate(*wait_bh))
+   for (i = 0; i < nr_wait; i++) {
+   wait_on_buffer(wait[i]);
+   if (!buffer_uptodate(wait[i]))
err = -EIO;
}
if (unlikely(err)) {
page_zero_new_buffers(page, from, to);
} else if (decrypt) {
-   err = fscrypt_decrypt_page(page->mapping->host, page,
-   PAGE_SIZE, 0, page->index);
-   if (err)
-   clear_buffer_uptodate(*wait_bh);
+   page_blk_nr = (sector_t)page->index << (PAGE_SHIFT - bbits);
+
+   for (i = 0; i < nr_wait; i++) {
+   int err2;
+
+   block = page_blk_nr + (bh_offset(wait[i]) >> bbits);
+   err2 = fscrypt_decrypt_page(page->mapping->host, page,
+   wait[i]->b_size,
+   bh_offset(wait[i]),
+   block);
+   if (err2) {
+   clear_buffer_uptodate(wait[i]);
+   err = err2;
+   }
+   }
}
 
return err;
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 06/13] ext4: Wire up ext4_readpage[s] to use mpage_readpage[s]

2019-04-27 Thread Chandan Rajendra
Now that do_mpage_readpage() is "post read process" aware, this commit
gets ext4_readpage[s] to use mpage_readpage[s] and deletes ext4's
readpage.c since the associated functionality is not required anymore.

Signed-off-by: Chandan Rajendra 
---
 fs/ext4/Makefile   |   2 +-
 fs/ext4/inode.c|   5 +-
 fs/ext4/readpage.c | 314 -
 3 files changed, 3 insertions(+), 318 deletions(-)
 delete mode 100644 fs/ext4/readpage.c

diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
index 8fdfcd3c3e04..7c38803a808d 100644
--- a/fs/ext4/Makefile
+++ b/fs/ext4/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_EXT4_FS) += ext4.o
 ext4-y := balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \
extents_status.o file.o fsmap.o fsync.o hash.o ialloc.o \
indirect.o inline.o inode.o ioctl.o mballoc.o migrate.o \
-   mmp.o move_extent.o namei.o page-io.o readpage.o resize.o \
+   mmp.o move_extent.o namei.o page-io.o resize.o \
super.o symlink.o sysfs.o xattr.o xattr_trusted.o xattr_user.o
 
 ext4-$(CONFIG_EXT4_FS_POSIX_ACL)   += acl.o
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 05b258db8673..1327e04334df 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3353,8 +3353,7 @@ static int ext4_readpage(struct file *file, struct page 
*page)
ret = ext4_readpage_inline(inode, page);
 
if (ret == -EAGAIN)
-   return ext4_mpage_readpages(page->mapping, NULL, page, 1,
-   false);
+   return mpage_readpage(page, ext4_get_block);
 
return ret;
 }
@@ -3369,7 +3368,7 @@ ext4_readpages(struct file *file, struct address_space 
*mapping,
if (ext4_has_inline_data(inode))
return 0;
 
-   return ext4_mpage_readpages(mapping, pages, NULL, nr_pages, true);
+   return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
 }
 
 static void ext4_invalidatepage(struct page *page, unsigned int offset,
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
deleted file mode 100644
index e363dededc21..
--- a/fs/ext4/readpage.c
+++ /dev/null
@@ -1,314 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/fs/ext4/readpage.c
- *
- * Copyright (C) 2002, Linus Torvalds.
- * Copyright (C) 2015, Google, Inc.
- *
- * This was originally taken from fs/mpage.c
- *
- * The intent is the ext4_mpage_readpages() function here is intended
- * to replace mpage_readpages() in the general case, not just for
- * encrypted files.  It has some limitations (see below), where it
- * will fall back to read_block_full_page(), but these limitations
- * should only be hit when page_size != block_size.
- *
- * This will allow us to attach a callback function to support ext4
- * encryption.
- *
- * If anything unusual happens, such as:
- *
- * - encountering a page which has buffers
- * - encountering a page which has a non-hole after a hole
- * - encountering a page with non-contiguous blocks
- *
- * then this code just gives up and calls the buffer_head-based read function.
- * It does handle a page which has holes at the end - that is a common case:
- * the end-of-file on blocksize < PAGE_SIZE setups.
- *
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "ext4.h"
-
-static inline bool ext4_bio_encrypted(struct bio *bio)
-{
-#ifdef CONFIG_FS_ENCRYPTION
-   return unlikely(bio->bi_private != NULL);
-#else
-   return false;
-#endif
-}
-
-/*
- * I/O completion handler for multipage BIOs.
- *
- * The mpage code never puts partial pages into a BIO (except for end-of-file).
- * If a page does not map to a contiguous run of blocks then it simply falls
- * back to block_read_full_page().
- *
- * Why is this?  If a page's completion depends on a number of different BIOs
- * which can complete in any order (or at the same time) then determining the
- * status of that page is hard.  See end_buffer_async_read() for the details.
- * There is no point in duplicating all that complexity.
- */
-static void mpage_end_io(struct bio *bio)
-{
-   struct bio_vec *bv;
-   int i;
-   struct bvec_iter_all iter_all;
-#if defined(CONFIG_FS_ENCRYPTION) || defined(CONFIG_FS_VERITY)
-   if (read_callbacks_required(bio)) {
-   struct read_callbacks_ctx *ctx = bio->bi_private;
-
-   read_callbacks(ctx);
-   return;
-   }
-#endif
-   bio_for_each_segment_all(bv, bio, i, iter_all) {
-   struct page *page = bv->bv_page;
-
-   if (!bio->bi_status) {
-   SetPageUptodate(page);
-   } else {
-   ClearPageUptodate(page);
-   SetPageError(page);
-   }
-   unlock_page(page);
-   }
-
-   bio_put(bio);

[f2fs-dev] [PATCH V2 01/13] ext4: Clear BH_Uptodate flag on decryption error

2019-04-27 Thread Chandan Rajendra
On an error return from fscrypt_decrypt_page(), ext4_block_write_begin()
can return with the page's buffer_head marked with BH_Uptodate
flag. This commit clears the BH_Uptodate flag in such cases.

Signed-off-by: Chandan Rajendra 
---
 fs/ext4/inode.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 3c2e7f5a6c84..05b258db8673 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1225,11 +1225,15 @@ static int ext4_block_write_begin(struct page *page, 
loff_t pos, unsigned len,
if (!buffer_uptodate(*wait_bh))
err = -EIO;
}
-   if (unlikely(err))
+   if (unlikely(err)) {
page_zero_new_buffers(page, from, to);
-   else if (decrypt)
+   } else if (decrypt) {
err = fscrypt_decrypt_page(page->mapping->host, page,
PAGE_SIZE, 0, page->index);
+   if (err)
+   clear_buffer_uptodate(*wait_bh);
+   }
+
return err;
 }
 #endif
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 12/13] fscrypt_zeroout_range: Encrypt all zeroed out blocks of a page

2019-04-27 Thread Chandan Rajendra
For subpage-sized blocks, this commit adds code to encrypt all zeroed
out blocks mapped by a page.

Signed-off-by: Chandan Rajendra 
---
 fs/crypto/bio.c | 40 ++--
 1 file changed, 18 insertions(+), 22 deletions(-)

diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c
index 856f4694902d..46dd2ec50c7d 100644
--- a/fs/crypto/bio.c
+++ b/fs/crypto/bio.c
@@ -108,29 +108,23 @@ EXPORT_SYMBOL(fscrypt_pullback_bio_page);
 int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
sector_t pblk, unsigned int len)
 {
-   struct fscrypt_ctx *ctx;
struct page *ciphertext_page = NULL;
struct bio *bio;
+   u64 total_bytes, page_bytes;
int ret, err = 0;
 
-   BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE);
-
-   ctx = fscrypt_get_ctx(inode, GFP_NOFS);
-   if (IS_ERR(ctx))
-   return PTR_ERR(ctx);
+   total_bytes = len << inode->i_blkbits;
 
-   ciphertext_page = fscrypt_alloc_bounce_page(ctx, GFP_NOWAIT);
-   if (IS_ERR(ciphertext_page)) {
-   err = PTR_ERR(ciphertext_page);
-   goto errout;
-   }
+   while (total_bytes) {
+   page_bytes = min_t(u64, total_bytes, PAGE_SIZE);
 
-   while (len--) {
-   err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk,
-ZERO_PAGE(0), ciphertext_page,
-PAGE_SIZE, 0, GFP_NOFS);
-   if (err)
+   ciphertext_page = fscrypt_encrypt_page(inode, ZERO_PAGE(0),
+   page_bytes, 0, lblk, GFP_NOFS);
+   if (IS_ERR(ciphertext_page)) {
+   err = PTR_ERR(ciphertext_page);
+   ciphertext_page = NULL;
goto errout;
+   }
 
bio = bio_alloc(GFP_NOWAIT, 1);
if (!bio) {
@@ -141,9 +135,8 @@ int fscrypt_zeroout_range(const struct inode *inode, 
pgoff_t lblk,
bio->bi_iter.bi_sector =
pblk << (inode->i_sb->s_blocksize_bits - 9);
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
-   ret = bio_add_page(bio, ciphertext_page,
-   inode->i_sb->s_blocksize, 0);
-   if (ret != inode->i_sb->s_blocksize) {
+   ret = bio_add_page(bio, ciphertext_page, page_bytes, 0);
+   if (ret != page_bytes) {
/* should never happen! */
WARN_ON(1);
bio_put(bio);
@@ -156,12 +149,15 @@ int fscrypt_zeroout_range(const struct inode *inode, 
pgoff_t lblk,
bio_put(bio);
if (err)
goto errout;
-   lblk++;
-   pblk++;
+
+   lblk += page_bytes >> inode->i_blkbits;
+   pblk += page_bytes >> inode->i_blkbits;
+   total_bytes -= page_bytes;
}
err = 0;
 errout:
-   fscrypt_release_ctx(ctx);
+   if (!IS_ERR_OR_NULL(ciphertext_page))
+   fscrypt_restore_control_page(ciphertext_page);
return err;
 }
 EXPORT_SYMBOL(fscrypt_zeroout_range);
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 11/13] ext4: Compute logical block and the page range to be encrypted

2019-04-27 Thread Chandan Rajendra
For subpage-sized blocks, the initial logical block number mapped by a
page can be different from page->index. Hence this commit adds code to
compute the first logical block mapped by the page and also the page
range to be encrypted.

Signed-off-by: Chandan Rajendra 
---
 fs/ext4/page-io.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 3e9298e6a705..75485ee9e800 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -418,6 +418,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
 {
struct page *data_page = NULL;
struct inode *inode = page->mapping->host;
+   u64 page_blk;
unsigned block_start;
struct buffer_head *bh, *head;
int ret = 0;
@@ -478,10 +479,14 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
 
if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && nr_to_submit) {
gfp_t gfp_flags = GFP_NOFS;
+   unsigned int page_bytes;
+
+   page_bytes = round_up(len, i_blocksize(inode));
+   page_blk = page->index << (PAGE_SHIFT - inode->i_blkbits);
 
retry_encrypt:
-   data_page = fscrypt_encrypt_page(inode, page, PAGE_SIZE, 0,
-   page->index, gfp_flags);
+   data_page = fscrypt_encrypt_page(inode, page, page_bytes, 0,
+   page_blk, gfp_flags);
if (IS_ERR(data_page)) {
ret = PTR_ERR(data_page);
if (ret == -ENOMEM && wbc->sync_mode == WB_SYNC_ALL) {
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 07/13] Add decryption support for sub-pagesized blocks

2019-04-27 Thread Chandan Rajendra
To support decryption of sub-pagesized blocks this commit adds code to,
1. Track buffer head in "struct read_callbacks_ctx".
2. Pass buffer head argument to all read callbacks.
3. In the corresponding endio, loop across all the blocks mapped by the
   page, decrypting each block in turn.

Signed-off-by: Chandan Rajendra 
---
 fs/buffer.c| 83 +-
 fs/crypto/bio.c| 50 +---
 fs/crypto/crypto.c | 19 +++-
 fs/f2fs/data.c |  2 +-
 fs/mpage.c |  2 +-
 fs/read_callbacks.c| 53 ++
 include/linux/buffer_head.h|  1 +
 include/linux/read_callbacks.h |  5 +-
 8 files changed, 154 insertions(+), 61 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index ce357602f471..f324727e24bb 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -45,6 +45,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
@@ -245,11 +246,7 @@ __find_get_block_slow(struct block_device *bdev, sector_t 
block)
return ret;
 }
 
-/*
- * I/O completion handler for block_read_full_page() - pages
- * which come unlocked at the end of I/O.
- */
-static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
+void end_buffer_page_read(struct buffer_head *bh)
 {
unsigned long flags;
struct buffer_head *first;
@@ -257,17 +254,7 @@ static void end_buffer_async_read(struct buffer_head *bh, 
int uptodate)
struct page *page;
int page_uptodate = 1;
 
-   BUG_ON(!buffer_async_read(bh));
-
page = bh->b_page;
-   if (uptodate) {
-   set_buffer_uptodate(bh);
-   } else {
-   clear_buffer_uptodate(bh);
-   buffer_io_error(bh, ", async page read");
-   SetPageError(page);
-   }
-
/*
 * Be _very_ careful from here on. Bad things can happen if
 * two buffer heads end IO at almost the same time and both
@@ -305,6 +292,44 @@ static void end_buffer_async_read(struct buffer_head *bh, 
int uptodate)
local_irq_restore(flags);
return;
 }
+EXPORT_SYMBOL(end_buffer_page_read);
+
+/*
+ * I/O completion handler for block_read_full_page() - pages
+ * which come unlocked at the end of I/O.
+ */
+static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
+{
+   struct page *page;
+
+   BUG_ON(!buffer_async_read(bh));
+
+#if defined(CONFIG_FS_ENCRYPTION) || defined(CONFIG_FS_VERITY)
+   if (uptodate && bh->b_private) {
+   struct read_callbacks_ctx *ctx = bh->b_private;
+
+   read_callbacks(ctx);
+   return;
+   }
+
+   if (bh->b_private) {
+   struct read_callbacks_ctx *ctx = bh->b_private;
+
+   WARN_ON(uptodate);
+   put_read_callbacks_ctx(ctx);
+   }
+#endif
+   page = bh->b_page;
+   if (uptodate) {
+   set_buffer_uptodate(bh);
+   } else {
+   clear_buffer_uptodate(bh);
+   buffer_io_error(bh, ", async page read");
+   SetPageError(page);
+   }
+
+   end_buffer_page_read(bh);
+}
 
 /*
  * Completion handler for block_write_full_page() - pages which are unlocked
@@ -2220,7 +2245,11 @@ int block_read_full_page(struct page *page, get_block_t 
*get_block)
 {
struct inode *inode = page->mapping->host;
sector_t iblock, lblock;
-   struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
+   struct buffer_head *bh, *head;
+   struct {
+   sector_t blk_nr;
+   struct buffer_head *bh;
+   } arr[MAX_BUF_PER_PAGE];
unsigned int blocksize, bbits;
int nr, i;
int fully_mapped = 1;
@@ -2262,7 +2291,9 @@ int block_read_full_page(struct page *page, get_block_t 
*get_block)
if (buffer_uptodate(bh))
continue;
}
-   arr[nr++] = bh;
+   arr[nr].blk_nr = iblock;
+   arr[nr].bh = bh;
+   ++nr;
} while (i++, iblock++, (bh = bh->b_this_page) != head);
 
if (fully_mapped)
@@ -2281,7 +2312,7 @@ int block_read_full_page(struct page *page, get_block_t 
*get_block)
 
/* Stage two: lock the buffers */
for (i = 0; i < nr; i++) {
-   bh = arr[i];
+   bh = arr[i].bh;
lock_buffer(bh);
mark_buffer_async_read(bh);
}
@@ -2292,11 +2323,21 @@ int block_read_full_page(struct page *page, get_block_t 
*get_block)
 * the underlying blockdev brought it uptodate (the sct fix).
 */
for (i = 0; i < nr; i++) {
-   bh = arr[i];
-   if (buffer_uptodate(bh))
+   bh = arr[i].bh;
+   if (buffer_uptodate(bh)) {
end_buffer_async_read(bh, 1);
-   else
+   

[f2fs-dev] [PATCH V2 03/13] fsverity: Add call back to decide if verity check has to be performed

2019-04-27 Thread Chandan Rajendra
Ext4 and F2FS store verity metadata in data extents (beyond
inode->i_size) associated with a file. But other filesystems might
choose alternative means to store verity metadata. Hence this commit
adds a callback function pointer to 'struct fsverity_operations' to help
in deciding if verity operation needs to performed against a page-cache
page holding file data.

Signed-off-by: Chandan Rajendra 
---
 fs/ext4/super.c  | 6 ++
 fs/f2fs/super.c  | 6 ++
 fs/read_callbacks.c  | 4 +++-
 include/linux/fsverity.h | 1 +
 4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index aba724f82cc3..63d73b360f1d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1428,10 +1428,16 @@ static struct page 
*ext4_read_verity_metadata_page(struct inode *inode,
return read_mapping_page(inode->i_mapping, index, NULL);
 }
 
+static bool ext4_verity_required(struct inode *inode, pgoff_t index)
+{
+   return index < (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+}
+
 static const struct fsverity_operations ext4_verityops = {
.set_verity = ext4_set_verity,
.get_metadata_end   = ext4_get_verity_metadata_end,
.read_metadata_page = ext4_read_verity_metadata_page,
+   .verity_required= ext4_verity_required,
 };
 #endif /* CONFIG_FS_VERITY */
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 2f75f06c784a..cd1299e1f92d 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2257,10 +2257,16 @@ static struct page 
*f2fs_read_verity_metadata_page(struct inode *inode,
return read_mapping_page(inode->i_mapping, index, NULL);
 }
 
+static bool f2fs_verity_required(struct inode *inode, pgoff_t index)
+{
+   return index < (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+}
+
 static const struct fsverity_operations f2fs_verityops = {
.set_verity = f2fs_set_verity,
.get_metadata_end   = f2fs_get_verity_metadata_end,
.read_metadata_page = f2fs_read_verity_metadata_page,
+   .verity_required= f2fs_verity_required,
 };
 #endif /* CONFIG_FS_VERITY */
 
diff --git a/fs/read_callbacks.c b/fs/read_callbacks.c
index b6d5b95e67d7..6dea54b0baa9 100644
--- a/fs/read_callbacks.c
+++ b/fs/read_callbacks.c
@@ -86,7 +86,9 @@ struct read_callbacks_ctx *get_read_callbacks_ctx(struct 
inode *inode,
read_callbacks_steps |= 1 << STEP_DECRYPT;
 #ifdef CONFIG_FS_VERITY
if (inode->i_verity_info != NULL &&
-   (index < ((i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT)))
+   ((inode->i_sb->s_vop->verity_required
+   && inode->i_sb->s_vop->verity_required(inode, index))
+   || (inode->i_sb->s_vop->verity_required == NULL)))
read_callbacks_steps |= 1 << STEP_VERITY;
 #endif
if (read_callbacks_steps) {
diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
index 7c33b42abf1b..b83712d6c79a 100644
--- a/include/linux/fsverity.h
+++ b/include/linux/fsverity.h
@@ -18,6 +18,7 @@ struct fsverity_operations {
int (*set_verity)(struct inode *inode, loff_t data_i_size);
int (*get_metadata_end)(struct inode *inode, loff_t *metadata_end_ret);
struct page *(*read_metadata_page)(struct inode *inode, pgoff_t index);
+   bool (*verity_required)(struct inode *inode, pgoff_t index);
 };
 
 #ifdef CONFIG_FS_VERITY
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 10/13] fscrypt_encrypt_page: Loop across all blocks mapped by a page range

2019-04-27 Thread Chandan Rajendra
For subpage-sized blocks, this commit now encrypts all blocks mapped by
a page range.

Signed-off-by: Chandan Rajendra 
---
 fs/crypto/crypto.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index 4f0d832cae71..2d65b431563f 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -242,18 +242,26 @@ struct page *fscrypt_encrypt_page(const struct inode 
*inode,
 {
struct fscrypt_ctx *ctx;
struct page *ciphertext_page = page;
+   int i, page_nr_blks;
int err;
 
BUG_ON(len % FS_CRYPTO_BLOCK_SIZE != 0);
 
+   page_nr_blks = len >> inode->i_blkbits;
+
if (inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES) {
/* with inplace-encryption we just encrypt the page */
-   err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk_num, page,
-ciphertext_page, len, offs,
-gfp_flags);
-   if (err)
-   return ERR_PTR(err);
-
+   for (i = 0; i < page_nr_blks; i++) {
+   err = fscrypt_do_page_crypto(inode, FS_ENCRYPT,
+   lblk_num, page,
+   ciphertext_page,
+   i_blocksize(inode), offs,
+   gfp_flags);
+   if (err)
+   return ERR_PTR(err);
+   ++lblk_num;
+   offs += i_blocksize(inode);
+   }
return ciphertext_page;
}
 
@@ -269,12 +277,17 @@ struct page *fscrypt_encrypt_page(const struct inode 
*inode,
goto errout;
 
ctx->control_page = page;
-   err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk_num,
-page, ciphertext_page, len, offs,
-gfp_flags);
-   if (err) {
-   ciphertext_page = ERR_PTR(err);
-   goto errout;
+
+   for (i = 0; i < page_nr_blks; i++) {
+   err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk_num,
+   page, ciphertext_page,
+   i_blocksize(inode), offs, gfp_flags);
+   if (err) {
+   ciphertext_page = ERR_PTR(err);
+   goto errout;
+   }
+   ++lblk_num;
+   offs += i_blocksize(inode);
}
SetPagePrivate(ciphertext_page);
set_page_private(ciphertext_page, (unsigned long)ctx);
-- 
2.19.1



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


[f2fs-dev] [PATCH V2 09/13] ext4: Decrypt the block that needs to be partially zeroed

2019-04-27 Thread Chandan Rajendra
__ext4_block_zero_page_range decrypts the entire page. This commit
decrypts the block to be partially zeroed instead of the whole page.

Signed-off-by: Chandan Rajendra 
---
 fs/ext4/inode.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 51744a3c3964..ade1816697a8 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4080,9 +4080,10 @@ static int __ext4_block_zero_page_range(handle_t *handle,
if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode)) {
/* We expect the key to be set. */
BUG_ON(!fscrypt_has_encryption_key(inode));
-   BUG_ON(blocksize != PAGE_SIZE);
WARN_ON_ONCE(fscrypt_decrypt_page(page->mapping->host,
-   page, PAGE_SIZE, 0, 
page->index));
+   page, blocksize,
+   round_down(offset, 
blocksize),
+   iblock));
}
}
if (ext4_should_journal_data(inode)) {
-- 
2.19.1



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


Re: [f2fs-dev] [PATCH] f2fs: Add option to limit required GC for checkpoint=disable

2019-04-27 Thread Chao Yu
Hi Daniel,

On 2019/4/24 9:25, Daniel Rosenberg wrote:
> This extends the checkpoint option to allow checkpoint=disable:%u
> This allows you to specify what percent of the drive you are willing
> to lose access to while mounting with checkpoint=disable. If the amount
> lost would be higher, the mount will return -EAGAIN.
> Currently, we need to run garbage collection until the amount of holes
> is smaller than the OVP space. With the new option, f2fs can mark
> space as unusable up front instead of requiring that
> the space be freed up with garbage collection.
> 
> Signed-off-by: Daniel Rosenberg 
> ---
>  Documentation/ABI/testing/sysfs-fs-f2fs |  8 +
>  Documentation/filesystems/f2fs.txt  |  8 +++--
>  fs/f2fs/f2fs.h  |  6 +++-
>  fs/f2fs/segment.c   | 17 --
>  fs/f2fs/super.c | 44 +
>  fs/f2fs/sysfs.c | 16 +
>  6 files changed, 72 insertions(+), 27 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
> b/Documentation/ABI/testing/sysfs-fs-f2fs
> index 91822ce258317..d65b9ebc56190 100644
> --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> @@ -243,3 +243,11 @@ Description:
>- Del: echo '[h/c]!extension' > 
> /sys/fs/f2fs//extension_list
>- [h] means add/del hot file extension
>- [c] means add/del cold file extension
> +
> +What:/sys/fs/f2fs//unusable
> +Date April 2019
> +Contact: "Daniel Rosenberg" 
> +Description:
> + Displays the number of blocks that are unusable during 
> checkpoint=disable

Maybe it will be more clear to indicate what you implement in unusable_show():

If checkpoint=enable, it displays...
If checkpoint=disable, it displays...

> + or the number of blocks that would be unusable if 
> checkpoint=disable
> + were to be set.
> diff --git a/Documentation/filesystems/f2fs.txt 
> b/Documentation/filesystems/f2fs.txt
> index f7b5e4ff0de3e..b3b5534407da7 100644
> --- a/Documentation/filesystems/f2fs.txt
> +++ b/Documentation/filesystems/f2fs.txt
> @@ -214,11 +214,15 @@ fsync_mode=%s  Control the policy of fsync. 
> Currently supports "posix",
> non-atomic files likewise "nobarrier" mount option.
>  test_dummy_encryption  Enable dummy encryption, which provides a fake fscrypt
> context. The fake fscrypt context is used by xfstests.
> -checkpoint=%s  Set to "disable" to turn off checkpointing. Set to 
> "enable"
> +checkpoint=%s[:%u] Set to "disable" to turn off checkpointing. Set to 
> "enable"
> to reenable checkpointing. Is enabled by default. 
> While
> disabled, any unmounting or unexpected shutdowns will 
> cause
> the filesystem contents to appear as they did when the
> -   filesystem was mounted with that option.
> +   filesystem was mounted with that option. While 
> mounting
> +   with disabled, you may optionally add a percentage to
> +   limit the amount of space that checkpoint=disable 
> denies
> +   access to. If this is set, the mount may return 
> EAGAIN if
> +   additional garbage collection is required to meet the 
> limit
>  
>  
> 
>  DEBUGFS ENTRIES
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 30acde08822ef..d0477251cec56 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -136,6 +136,9 @@ struct f2fs_mount_info {
>   int alloc_mode; /* segment allocation policy */
>   int fsync_mode; /* fsync policy */
>   bool test_dummy_encryption; /* test dummy encryption */
> + block_t unusable_percent_cap;   /* Percent of space allowed to be
> +  * unusable when disabling checkpoint
> +  */
>  };
>  
>  #define F2FS_FEATURE_ENCRYPT 0x0001
> @@ -3049,7 +3052,8 @@ bool f2fs_issue_discard_timeout(struct f2fs_sb_info 
> *sbi);
>  void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
>   struct cp_control *cpc);
>  void f2fs_dirty_to_prefree(struct f2fs_sb_info *sbi);
> -int f2fs_disable_cp_again(struct f2fs_sb_info *sbi);
> +block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi);
> +int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
>  void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
>  int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
>  void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index a3380d1de6000..704224f4a2866 100644
> ---