Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93061f39 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 bugfixes from Ted Ts'o:
 "These changes contains a fix for overlayfs interacting with some
  (badly behaved) dentry code in various file systems.  These have been
  reviewed by Al and the respective file system mtinainers and are going
  through the ext4 tree for convenience.

  This also has a few ext4 encryption bug fixes that were discovered in
  Android testing (yes, we will need to get these sync'ed up with the
  fs/crypto code; I'll take care of that).  It also has some bug fixes
  and a change to ignore the legacy quota options to allow for xfstests
  regression testing of ext4's internal quota feature and to be more
  consistent with how xfs handles this case"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: ignore quota mount options if the quota feature is enabled
  ext4 crypto: fix some error handling
  ext4: avoid calling dquot_get_next_id() if quota is not enabled
  ext4: retry block allocation for failed DIO and DAX writes
  ext4: add lockdep annotations for i_data_sem
  ext4: allow readdir()'s of large empty directories to be interrupted
  btrfs: fix crash/invalid memory access on fsync when using overlayfs
  ext4 crypto: use dget_parent() in ext4_d_revalidate()
  ext4: use file_dentry()
  ext4: use dget_parent() in ext4_file_open()
  nfs: use file_dentry()
  fs: add file_dentry()
  ext4 crypto: don't let data integrity writebacks fail with ENOMEM
  ext4: check if in-inode xattr is corrupted in ext4_expand_extra_isize_ea()
parents 1c915b3a c325a67c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1905,7 +1905,7 @@ static int start_ordered_ops(struct inode *inode, loff_t start, loff_t end)
 */
int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
{
	struct dentry *dentry = file->f_path.dentry;
	struct dentry *dentry = file_dentry(file);
	struct inode *inode = d_inode(dentry);
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_trans_handle *trans;
+4 −1
Original line number Diff line number Diff line
@@ -1667,7 +1667,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
				DCACHE_OP_REVALIDATE	|
				DCACHE_OP_WEAK_REVALIDATE	|
				DCACHE_OP_DELETE	|
				DCACHE_OP_SELECT_INODE));
				DCACHE_OP_SELECT_INODE	|
				DCACHE_OP_REAL));
	dentry->d_op = op;
	if (!op)
		return;
@@ -1685,6 +1686,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
		dentry->d_flags |= DCACHE_OP_PRUNE;
	if (op->d_select_inode)
		dentry->d_flags |= DCACHE_OP_SELECT_INODE;
	if (op->d_real)
		dentry->d_flags |= DCACHE_OP_REAL;

}
EXPORT_SYMBOL(d_set_d_op);
+29 −20
Original line number Diff line number Diff line
@@ -91,7 +91,8 @@ void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx)
 * Return: An allocated and initialized encryption context on success; error
 * value or NULL otherwise.
 */
struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode,
					    gfp_t gfp_flags)
{
	struct ext4_crypto_ctx *ctx = NULL;
	int res = 0;
@@ -118,7 +119,7 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
		list_del(&ctx->free_list);
	spin_unlock_irqrestore(&ext4_crypto_ctx_lock, flags);
	if (!ctx) {
		ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, GFP_NOFS);
		ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, gfp_flags);
		if (!ctx) {
			res = -ENOMEM;
			goto out;
@@ -255,7 +256,8 @@ static int ext4_page_crypto(struct inode *inode,
			    ext4_direction_t rw,
			    pgoff_t index,
			    struct page *src_page,
			    struct page *dest_page)
			    struct page *dest_page,
			    gfp_t gfp_flags)

{
	u8 xts_tweak[EXT4_XTS_TWEAK_SIZE];
@@ -266,7 +268,7 @@ static int ext4_page_crypto(struct inode *inode,
	struct crypto_skcipher *tfm = ci->ci_ctfm;
	int res = 0;

	req = skcipher_request_alloc(tfm, GFP_NOFS);
	req = skcipher_request_alloc(tfm, gfp_flags);
	if (!req) {
		printk_ratelimited(KERN_ERR
				   "%s: crypto_request_alloc() failed\n",
@@ -307,9 +309,10 @@ static int ext4_page_crypto(struct inode *inode,
	return 0;
}

static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx)
static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx,
				      gfp_t gfp_flags)
{
	ctx->w.bounce_page = mempool_alloc(ext4_bounce_page_pool, GFP_NOWAIT);
	ctx->w.bounce_page = mempool_alloc(ext4_bounce_page_pool, gfp_flags);
	if (ctx->w.bounce_page == NULL)
		return ERR_PTR(-ENOMEM);
	ctx->flags |= EXT4_WRITE_PATH_FL;
@@ -332,7 +335,8 @@ static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx)
 * error value or NULL.
 */
struct page *ext4_encrypt(struct inode *inode,
			  struct page *plaintext_page)
			  struct page *plaintext_page,
			  gfp_t gfp_flags)
{
	struct ext4_crypto_ctx *ctx;
	struct page *ciphertext_page = NULL;
@@ -340,17 +344,17 @@ struct page *ext4_encrypt(struct inode *inode,

	BUG_ON(!PageLocked(plaintext_page));

	ctx = ext4_get_crypto_ctx(inode);
	ctx = ext4_get_crypto_ctx(inode, gfp_flags);
	if (IS_ERR(ctx))
		return (struct page *) ctx;

	/* The encryption operation will require a bounce page. */
	ciphertext_page = alloc_bounce_page(ctx);
	ciphertext_page = alloc_bounce_page(ctx, gfp_flags);
	if (IS_ERR(ciphertext_page))
		goto errout;
	ctx->w.control_page = plaintext_page;
	err = ext4_page_crypto(inode, EXT4_ENCRYPT, plaintext_page->index,
			       plaintext_page, ciphertext_page);
			       plaintext_page, ciphertext_page, gfp_flags);
	if (err) {
		ciphertext_page = ERR_PTR(err);
	errout:
@@ -378,8 +382,8 @@ int ext4_decrypt(struct page *page)
{
	BUG_ON(!PageLocked(page));

	return ext4_page_crypto(page->mapping->host,
				EXT4_DECRYPT, page->index, page, page);
	return ext4_page_crypto(page->mapping->host, EXT4_DECRYPT,
				page->index, page, page, GFP_NOFS);
}

int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
@@ -398,11 +402,11 @@ int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,

	BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE);

	ctx = ext4_get_crypto_ctx(inode);
	ctx = ext4_get_crypto_ctx(inode, GFP_NOFS);
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);

	ciphertext_page = alloc_bounce_page(ctx);
	ciphertext_page = alloc_bounce_page(ctx, GFP_NOWAIT);
	if (IS_ERR(ciphertext_page)) {
		err = PTR_ERR(ciphertext_page);
		goto errout;
@@ -410,11 +414,12 @@ int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,

	while (len--) {
		err = ext4_page_crypto(inode, EXT4_ENCRYPT, lblk,
				       ZERO_PAGE(0), ciphertext_page);
				       ZERO_PAGE(0), ciphertext_page,
				       GFP_NOFS);
		if (err)
			goto errout;

		bio = bio_alloc(GFP_KERNEL, 1);
		bio = bio_alloc(GFP_NOWAIT, 1);
		if (!bio) {
			err = -ENOMEM;
			goto errout;
@@ -473,13 +478,16 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size)
 */
static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
{
	struct inode *dir = d_inode(dentry->d_parent);
	struct ext4_crypt_info *ci = EXT4_I(dir)->i_crypt_info;
	struct dentry *dir;
	struct ext4_crypt_info *ci;
	int dir_has_key, cached_with_key;

	if (!ext4_encrypted_inode(dir))
	dir = dget_parent(dentry);
	if (!ext4_encrypted_inode(d_inode(dir))) {
		dput(dir);
		return 0;

	}
	ci = EXT4_I(d_inode(dir))->i_crypt_info;
	if (ci && ci->ci_keyring_key &&
	    (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
					  (1 << KEY_FLAG_REVOKED) |
@@ -489,6 +497,7 @@ static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
	/* this should eventually be an flag in d_flags */
	cached_with_key = dentry->d_fsdata != NULL;
	dir_has_key = (ci != NULL);
	dput(dir);

	/*
	 * If the dentry was cached without the key, and it is a
+5 −0
Original line number Diff line number Diff line
@@ -150,6 +150,11 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
	while (ctx->pos < inode->i_size) {
		struct ext4_map_blocks map;

		if (fatal_signal_pending(current)) {
			err = -ERESTARTSYS;
			goto errout;
		}
		cond_resched();
		map.m_lblk = ctx->pos >> EXT4_BLOCK_SIZE_BITS(sb);
		map.m_len = 1;
		err = ext4_map_blocks(NULL, inode, &map, 0);
+27 −2
Original line number Diff line number Diff line
@@ -911,6 +911,29 @@ do { \

#include "extents_status.h"

/*
 * Lock subclasses for i_data_sem in the ext4_inode_info structure.
 *
 * These are needed to avoid lockdep false positives when we need to
 * allocate blocks to the quota inode during ext4_map_blocks(), while
 * holding i_data_sem for a normal (non-quota) inode.  Since we don't
 * do quota tracking for the quota inode, this avoids deadlock (as
 * well as infinite recursion, since it isn't turtles all the way
 * down...)
 *
 *  I_DATA_SEM_NORMAL - Used for most inodes
 *  I_DATA_SEM_OTHER  - Used by move_inode.c for the second normal inode
 *			  where the second inode has larger inode number
 *			  than the first
 *  I_DATA_SEM_QUOTA  - Used for quota inodes only
 */
enum {
	I_DATA_SEM_NORMAL = 0,
	I_DATA_SEM_OTHER,
	I_DATA_SEM_QUOTA,
};


/*
 * fourth extended file system inode data in memory
 */
@@ -2282,11 +2305,13 @@ extern struct kmem_cache *ext4_crypt_info_cachep;
bool ext4_valid_contents_enc_mode(uint32_t mode);
uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size);
extern struct workqueue_struct *ext4_read_workqueue;
struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode);
struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode,
					    gfp_t gfp_flags);
void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx);
void ext4_restore_control_page(struct page *data_page);
struct page *ext4_encrypt(struct inode *inode,
			  struct page *plaintext_page);
			  struct page *plaintext_page,
			  gfp_t gfp_flags);
int ext4_decrypt(struct page *page);
int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
			   ext4_fsblk_t pblk, ext4_lblk_t len);
Loading