Re: [f2fs-dev] [PATCH 4/8] vfs: Fold casefolding into vfs

2020-01-03 Thread Theodore Y. Ts'o
On Mon, Dec 02, 2019 at 09:10:45PM -0800, Daniel Rosenberg wrote:
> @@ -228,6 +229,13 @@ static inline int dentry_string_cmp(const unsigned char 
> *cs, const unsigned char
>  
>  #endif
>  
> +bool needs_casefold(const struct inode *dir)
> +{
> + return IS_CASEFOLDED(dir) &&
> + (!IS_ENCRYPTED(dir) || fscrypt_has_encryption_key(dir));
> +}
> +EXPORT_SYMBOL(needs_casefold);
> +

I'd suggest adding a check to make sure that dir->i_sb->s_encoding is
non-NULL before needs_casefold() returns non-NULL.  Otherwise a bug
(or a fuzzed file system) which manages to set the S_CASEFOLD flag without 
having s_encoding be initialized might cause a NULL dereference.

Also, maybe make needs_casefold() an inline function which returns 0
if CONFIG_UNICODE is not defined?  That way the need for #ifdef
CONFIG_UNICODE could be reduced.

> @@ -247,7 +255,19 @@ static inline int dentry_cmp(const struct dentry 
> *dentry, const unsigned char *c
>* be no NUL in the ct/tcount data)
>*/
>   const unsigned char *cs = READ_ONCE(dentry->d_name.name);
> +#ifdef CONFIG_UNICODE
> + struct inode *parent = dentry->d_parent->d_inode;
>  
> + if (unlikely(needs_casefold(parent))) {
> + const struct qstr n1 = QSTR_INIT(cs, tcount);
> + const struct qstr n2 = QSTR_INIT(ct, tcount);
> + int result = utf8_strncasecmp(dentry->d_sb->s_encoding,
> + , );
> +
> + if (result >= 0 || sb_has_enc_strict_mode(dentry->d_sb))
> + return result;
> + }
> +#endif

This is an example of how we could drop the #ifdef CONFIG_UNICODE
(moving the declaration of 'parent' into the #if statement) if
needs_casefold() always returns 0 if !defined(CONFIG_UNICODE).

> @@ -2404,7 +2424,22 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, 
> struct qstr *name)
>* calculate the standard hash first, as the d_op->d_hash()
>* routine may choose to leave the hash value unchanged.
>*/
> +#ifdef CONFIG_UNICODE
> + unsigned char *hname = NULL;
> + int hlen = name->len;
> +
> + if (IS_CASEFOLDED(dir->d_inode)) {
> + hname = kmalloc(PATH_MAX, GFP_ATOMIC);
> + if (!hname)
> + return ERR_PTR(-ENOMEM);
> + hlen = utf8_casefold(dir->d_sb->s_encoding,
> + name, hname, PATH_MAX);
> + }
> + name->hash = full_name_hash(dir, hname ?: name->name, hlen);
> + kfree(hname);
> +#else
>   name->hash = full_name_hash(dir, name->name, name->len);
> +#endif

Perhaps this could be refactored out?  It's also used in
link_path_walk() and lookup_one_len_common().

(Note, there was some strageness in lookup_one_len_common(), where
hname is freed twice, the first time using kvfree() which I don't
believe is needed.  But this can be fixed as part of the refactoring.)

  - Ted


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


Re: [f2fs-dev] [PATCH] fsck.f2fs: do not access nat etnries in ckpt before initialization

2020-01-03 Thread Jaegeuk Kim
On 01/03, Chao Yu wrote:
> On 2019/12/11 0:47, Jaegeuk Kim wrote:
> > ckpt->entries is initialized by fsck_init(), but we tried to access it 
> > during
> > f2fs_do_mount().
> > 
> > The call sequence is:
> >  - f2fs_do_mount
> >   - record_fsync_data
> > - traverse_dnodes
> >  - do_record_fsync_data
> >   - ADDRS_PER_PAGE
> >- get_node_info
> > - node_info_from_raw_nat(fsck->entries[nid])
> >  - do_fsck
> >   - fsck_init
> >- build_nat_area_bitmap
> > - fsck->entries = calloc(fsck->nr_nat_entries);
> > 
> > Signed-off-by: Jaegeuk Kim 
> 
> Reviewed-by: Chao Yu 

Sorry, merged in master before.

> 
> Thanks,


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


Re: [f2fs-dev] [PATCH v2] fs-verity: implement readahead for FS_IOC_ENABLE_VERITY

2020-01-03 Thread Eric Biggers
On Tue, Dec 10, 2019 at 10:35:31AM -0800, Eric Biggers wrote:
> From: Eric Biggers 
> 
> When it builds the first level of the Merkle tree, FS_IOC_ENABLE_VERITY
> sequentially reads each page of the file using read_mapping_page().
> This works fine if the file's data is already in pagecache, which should
> normally be the case, since this ioctl is normally used immediately
> after writing out the file.
> 
> But in any other case this implementation performs very poorly, since
> only one page is read at a time.
> 
> Fix this by implementing readahead using the functions from
> mm/readahead.c.
> 
> This improves performance in the uncached case by about 20x, as seen in
> the following benchmarks done on a 250MB file (on x86_64 with SHA-NI):
> 
> FS_IOC_ENABLE_VERITY uncached (before) 3.299s
> FS_IOC_ENABLE_VERITY uncached (after)  0.160s
> FS_IOC_ENABLE_VERITY cached0.147s
> sha256sum uncached 0.191s
> sha256sum cached   0.145s
> 
> Note: we could instead switch to kernel_read().  But that would mean
> we'd no longer be hashing the data directly from the pagecache, which is
> a nice optimization of its own.  And using kernel_read() would require
> allocating another temporary buffer, hashing the data and tree pages
> separately, and explicitly zero-padding the last page -- so it wouldn't
> really be any simpler than direct pagecache access, at least for now.
> 
> Signed-off-by: Eric Biggers 
> ---
> 
> Changed v1 => v2:
> - Only do sync readahead when the page wasn't found in the pagecache at all.
> - Use ->f_mapping so that the inode doesn't have to be passed.
> 
> 
>  fs/verity/enable.c | 45 +++--
>  1 file changed, 39 insertions(+), 6 deletions(-)
> 

Applied to fscrypt.git#fsverity for 5.6.

- Eric


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


Re: [f2fs-dev] [PATCH] fscrypt: don't check for ENOKEY from fscrypt_get_encryption_info()

2020-01-03 Thread Eric Biggers
On Mon, Dec 09, 2019 at 01:23:48PM -0800, Eric Biggers wrote:
> From: Eric Biggers 
> 
> fscrypt_get_encryption_info() returns 0 if the encryption key is
> unavailable; it never returns ENOKEY.  So remove checks for ENOKEY.
> 
> Signed-off-by: Eric Biggers 
> ---
>  fs/ext4/dir.c  | 2 +-
>  fs/f2fs/dir.c  | 2 +-
>  fs/ubifs/dir.c | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
> index 9fdd2b269d617..4c9d3ff394a5d 100644
> --- a/fs/ext4/dir.c
> +++ b/fs/ext4/dir.c
> @@ -116,7 +116,7 @@ static int ext4_readdir(struct file *file, struct 
> dir_context *ctx)
>  
>   if (IS_ENCRYPTED(inode)) {
>   err = fscrypt_get_encryption_info(inode);
> - if (err && err != -ENOKEY)
> + if (err)
>   return err;
>   }
>  
> diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
> index c967cacf979ef..d9ad842945df5 100644
> --- a/fs/f2fs/dir.c
> +++ b/fs/f2fs/dir.c
> @@ -987,7 +987,7 @@ static int f2fs_readdir(struct file *file, struct 
> dir_context *ctx)
>  
>   if (IS_ENCRYPTED(inode)) {
>   err = fscrypt_get_encryption_info(inode);
> - if (err && err != -ENOKEY)
> + if (err)
>   goto out;
>  
>   err = fscrypt_fname_alloc_buffer(inode, F2FS_NAME_LEN, );
> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
> index 0b98e3c8b461d..acc4f942d25b6 100644
> --- a/fs/ubifs/dir.c
> +++ b/fs/ubifs/dir.c
> @@ -512,7 +512,7 @@ static int ubifs_readdir(struct file *file, struct 
> dir_context *ctx)
>  
>   if (encrypted) {
>   err = fscrypt_get_encryption_info(dir);
> - if (err && err != -ENOKEY)
> + if (err)
>   return err;
>  
>   err = fscrypt_fname_alloc_buffer(dir, UBIFS_MAX_NLEN, );
> -- 
> 2.24.0.393.g34dc348eaf-goog
> 

Applied to fscrypt.git#master for 5.6.

- Eric


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


Re: [f2fs-dev] [PATCH] fscrypt: introduce fscrypt_needs_contents_encryption()

2020-01-03 Thread Eric Biggers
On Mon, Dec 09, 2019 at 12:50:21PM -0800, Eric Biggers wrote:
> From: Eric Biggers 
> 
> Add a function fscrypt_needs_contents_encryption() which takes an inode
> and returns true if it's an encrypted regular file and the kernel was
> built with fscrypt support.
> 
> This will allow replacing duplicated checks of IS_ENCRYPTED() &&
> S_ISREG() on the I/O paths in ext4 and f2fs, while also optimizing out
> unneeded code when !CONFIG_FS_ENCRYPTION.
> 
> Signed-off-by: Eric Biggers 
> ---
>  include/linux/fscrypt.h | 20 
>  1 file changed, 20 insertions(+)
> 
> diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
> index cb18b5fbcef92..2a29f56b1a1cb 100644
> --- a/include/linux/fscrypt.h
> +++ b/include/linux/fscrypt.h
> @@ -72,6 +72,21 @@ static inline bool fscrypt_has_encryption_key(const struct 
> inode *inode)
>   return READ_ONCE(inode->i_crypt_info) != NULL;
>  }
>  
> +/**
> + * fscrypt_needs_contents_encryption() - check whether an inode needs
> + *contents encryption
> + *
> + * Return: %true iff the inode is an encrypted regular file and the kernel 
> was
> + * built with fscrypt support.
> + *
> + * If you need to know whether the encrypt bit is set even when the kernel 
> was
> + * built without fscrypt support, you must use IS_ENCRYPTED() directly 
> instead.
> + */
> +static inline bool fscrypt_needs_contents_encryption(const struct inode 
> *inode)
> +{
> + return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
> +}
> +
>  static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
>  {
>   return inode->i_sb->s_cop->dummy_context &&
> @@ -269,6 +284,11 @@ static inline bool fscrypt_has_encryption_key(const 
> struct inode *inode)
>   return false;
>  }
>  
> +static inline bool fscrypt_needs_contents_encryption(const struct inode 
> *inode)
> +{
> + return false;
> +}
> +
>  static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
>  {
>   return false;
> -- 
> 2.24.0.393.g34dc348eaf-goog
> 

Applied to fscrypt.git#master for 5.6.

- Eric


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


Re: [f2fs-dev] [PATCH v2] fscrypt: support passing a keyring key to FS_IOC_ADD_ENCRYPTION_KEY

2020-01-03 Thread Eric Biggers
On Tue, Nov 19, 2019 at 02:24:47PM -0800, Eric Biggers wrote:
> From: Eric Biggers 
> 
> Extend the FS_IOC_ADD_ENCRYPTION_KEY ioctl to allow the raw key to be
> specified by a Linux keyring key, rather than specified directly.
> 
> This is useful because fscrypt keys belong to a particular filesystem
> instance, so they are destroyed when that filesystem is unmounted.
> Usually this is desired.  But in some cases, userspace may need to
> unmount and re-mount the filesystem while keeping the keys, e.g. during
> a system update.  This requires keeping the keys somewhere else too.
> 
> The keys could be kept in memory in a userspace daemon.  But depending
> on the security architecture and assumptions, it can be preferable to
> keep them only in kernel memory, where they are unreadable by userspace.
> 
> We also can't solve this by going back to the original fscrypt API
> (where for each file, the master key was looked up in the process's
> keyring hierarchy) because that caused lots of problems of its own.
> 
> Therefore, add the ability for FS_IOC_ADD_ENCRYPTION_KEY to accept a
> Linux keyring key.  This solves the problem by allowing userspace to (if
> needed) save the keys securely in a Linux keyring for re-provisioning,
> while still using the new fscrypt key management ioctls.
> 
> This is analogous to how dm-crypt accepts a Linux keyring key, but the
> key is then stored internally in the dm-crypt data structures rather
> than being looked up again each time the dm-crypt device is accessed.
> 
> Use a custom key type "fscrypt-provisioning" rather than one of the
> existing key types such as "logon".  This is strongly desired because it
> enforces that these keys are only usable for a particular purpose: for
> fscrypt as input to a particular KDF.  Otherwise, the keys could also be
> passed to any kernel API that accepts a "logon" key with any service
> prefix, e.g. dm-crypt, UBIFS, or (recently proposed) AF_ALG.  This would
> risk leaking information about the raw key despite it ostensibly being
> unreadable.  Of course, this mistake has already been made for multiple
> kernel APIs; but since this is a new API, let's do it right.
> 
> This patch has been tested using an xfstest which I wrote to test it.
> 
> Signed-off-by: Eric Biggers 

Applied to fscrypt.git#master for 5.6.

- Eric


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


[f2fs-dev] [Bug 206057] 5.5.0-rc2-next: f2fs is extremely slow, with ext4 system works well

2020-01-03 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=206057

--- Comment #5 from David Heidelberg (okias) (da...@ixit.cz) ---
sadly, still same output. Also not sure why, sudo -i freezes and cannot be
stopped by CTRL-C.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.

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


[f2fs-dev] [PATCH TEST] f2fs: compress: fix deadlock in prepare_compress_overwrite()

2020-01-03 Thread Chao Yu
   100.00%13.65%  fsstress  [f2fs]  [k] 
prepare_compress_overwrite
|
|--86.35%--prepare_compress_overwrite
|  |
|  |--46.78%--f2fs_read_multi_pages
|  |  |
|  |  |--19.81%--f2fs_decompress_end_io
|  |  |  |
|  |  |   --5.77%--unlock_page
|  |  |
|  |  |--19.53%--f2fs_get_dnode_of_data

In prepare_compress_overwrite(), we need to check cluster state before
read cluster data, otherwise, read normal cluster as a compressed one
will always cause failure and retry.

Signed-off-by: Chao Yu 
---
 fs/f2fs/compress.c | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 9e8fba78db4d..f993b4ce1970 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -570,8 +570,7 @@ static void set_cluster_dirty(struct compress_ctx *cc)
 }
 
 static int prepare_compress_overwrite(struct compress_ctx *cc,
-   struct page **pagep, pgoff_t index, void **fsdata,
-   bool prealloc)
+   struct page **pagep, pgoff_t index, void **fsdata)
 {
struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode);
struct address_space *mapping = cc->inode->i_mapping;
@@ -582,11 +581,20 @@ static int prepare_compress_overwrite(struct compress_ctx 
*cc,
unsigned int start_idx = start_idx_of_cluster(cc);
int i, idx;
int ret;
+   bool prealloc;
+
+retry:
+   ret = is_compressed_cluster(cc);
+   if (ret <= 0)
+   return ret;
+
+   /* compressed case */
+   prealloc = (ret == CLUSTER_HAS_SPACE);
 
ret = f2fs_init_compress_ctx(cc);
if (ret)
return ret;
-retry:
+
/* keep page reference to avoid page reclaim */
for (i = 0; i < cc->cluster_size; i++) {
page = f2fs_pagecache_get_page(mapping, start_idx + i,
@@ -632,6 +640,7 @@ static int prepare_compress_overwrite(struct compress_ctx 
*cc,
(idx <= i) ? 1 : 0);
cc->rpages[idx] = NULL;
}
+   kvfree(cc->rpages);
cc->nr_rpages = 0;
goto retry;
}
@@ -687,14 +696,8 @@ int f2fs_prepare_compress_overwrite(struct inode *inode,
.rpages = NULL,
.nr_rpages = 0,
};
-   int ret = is_compressed_cluster();
-
-   if (ret <= 0)
-   return ret;
 
-   /* compressed case */
-   return prepare_compress_overwrite(, pagep, index,
-   fsdata, ret == CLUSTER_HAS_SPACE);
+   return prepare_compress_overwrite(, pagep, index, fsdata);
 }
 
 bool f2fs_compress_write_end(struct inode *inode, void *fsdata,
-- 
2.18.0.rc1



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


[f2fs-dev] [PATCH] f2fs: compress: fix NULL pointer dereference

2020-01-03 Thread Chao Yu
 BUG: kernel NULL pointer dereference, address: 
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x) - not-present page
 PGD 0 P4D 0
 Oops:  [#1] SMP PTI
 CPU: 11 PID: 70359 Comm: kworker/u256:4 Tainted: G   OE 5.5.0-rc1 
#36
 Hardware name: Xen HVM domU, BIOS 4.1.2_115-908.790. 06/05/2017
 Workqueue: writeback wb_workfn (flush-251:0)
 RIP: 0010:f2fs_write_single_data_page+0x4f/0x700 [f2fs]
 Call Trace:
  ? __next_timer_interrupt+0xc0/0xc0
  ? finish_wait+0x32/0x70
  ? congestion_wait+0xa5/0x120
  f2fs_write_multi_pages+0xc7/0x810 [f2fs]
  f2fs_write_cache_pages+0x6c0/0x790 [f2fs]
  ? select_task_rq_fair+0x584/0x800
  ? atomic_notifier_chain_unregister+0x30/0x70
  ? __set_page_dirty_nobuffers+0x101/0x150
  f2fs_write_data_pages+0x2cd/0x320 [f2fs]
  ? f2fs_update_inode+0x9c/0x4f0 [f2fs]
  ? do_writepages+0x1a/0x60
  do_writepages+0x1a/0x60
  __writeback_single_inode+0x3d/0x340
  writeback_sb_inodes+0x225/0x4a0
  wb_writeback+0xf7/0x320
  ? wb_workfn+0xa8/0x450
  ? _raw_spin_unlock_bh+0xa/0x20
  wb_workfn+0xa8/0x450
  ? finish_task_switch+0x75/0x2a0
  process_one_work+0x15e/0x3e0
  worker_thread+0x4c/0x440
  ? rescuer_thread+0x350/0x350
  kthread+0xf8/0x130
  ? kthread_unpark+0x70/0x70
  ret_from_fork+0x35/0x40

In scenario of truncate vs writeback, we need to check page's mapping
before access it during writeback.

Signed-off-by: Chao Yu 
---
 fs/f2fs/compress.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index fa67ffd9d79d..9e8fba78db4d 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -932,6 +932,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
enum iostat_type io_type,
bool compressed)
 {
+   struct address_space *mapping = cc->inode->i_mapping;
int i, _submitted;
int ret, err = 0;
 
@@ -939,6 +940,11 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
if (!cc->rpages[i])
continue;
 retry_write:
+   if (cc->rpages[i]->mapping != mapping) {
+   unlock_page(cc->rpages[i]);
+   continue;
+   }
+
BUG_ON(!PageLocked(cc->rpages[i]));
 
ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted,
-- 
2.18.0.rc1



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


Re: [f2fs-dev] [PATCH] fsck.f2fs: do not access nat etnries in ckpt before initialization

2020-01-03 Thread Chao Yu
On 2019/12/11 0:47, Jaegeuk Kim wrote:
> ckpt->entries is initialized by fsck_init(), but we tried to access it during
> f2fs_do_mount().
> 
> The call sequence is:
>  - f2fs_do_mount
>   - record_fsync_data
> - traverse_dnodes
>  - do_record_fsync_data
>   - ADDRS_PER_PAGE
>- get_node_info
> - node_info_from_raw_nat(fsck->entries[nid])
>  - do_fsck
>   - fsck_init
>- build_nat_area_bitmap
> - fsck->entries = calloc(fsck->nr_nat_entries);
> 
> Signed-off-by: Jaegeuk Kim 

Reviewed-by: Chao Yu 

Thanks,


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