aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-02-19 16:44:12 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-02-19 16:44:12 -0500
commit020ecbba0548cefc91c3c5de32c28a62bcf37ed9 (patch)
tree2e6ba63b7332e15b30a2d7f7d930cde2ae4bfefe
parentce6b71432d42afe5c3ae25ab2980304c32ecb915 (diff)
parent74dae4278546b897eb81784fdfcce872ddd8b2b8 (diff)
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: "Miscellaneous ext4 bug fixes for v4.5" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: fix crashes in dioread_nolock mode ext4: fix bh->b_state corruption ext4: fix memleak in ext4_readdir() ext4: remove unused parameter "newblock" in convert_initialized_extent() ext4: don't read blocks from disk after extents being swapped ext4: fix potential integer overflow ext4: add a line break for proc mb_groups display ext4: ioctl: fix erroneous return value ext4: fix scheduling in atomic on group checksum failure ext4 crypto: move context consistency check to ext4_file_open() ext4 crypto: revalidate dentry after adding or removing the key
-rw-r--r--fs/ext4/balloc.c7
-rw-r--r--fs/ext4/crypto.c56
-rw-r--r--fs/ext4/dir.c13
-rw-r--r--fs/ext4/ext4.h1
-rw-r--r--fs/ext4/extents.c4
-rw-r--r--fs/ext4/file.c9
-rw-r--r--fs/ext4/ialloc.c6
-rw-r--r--fs/ext4/inode.c72
-rw-r--r--fs/ext4/ioctl.c2
-rw-r--r--fs/ext4/mballoc.c2
-rw-r--r--fs/ext4/move_extent.c15
-rw-r--r--fs/ext4/namei.c26
-rw-r--r--fs/ext4/resize.c2
13 files changed, 176 insertions, 39 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index ec0668a60678..fe1f50fe764f 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -191,7 +191,6 @@ static int ext4_init_block_bitmap(struct super_block *sb,
191 /* If checksum is bad mark all blocks used to prevent allocation 191 /* If checksum is bad mark all blocks used to prevent allocation
192 * essentially implementing a per-group read-only flag. */ 192 * essentially implementing a per-group read-only flag. */
193 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { 193 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
194 ext4_error(sb, "Checksum bad for group %u", block_group);
195 grp = ext4_get_group_info(sb, block_group); 194 grp = ext4_get_group_info(sb, block_group);
196 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) 195 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
197 percpu_counter_sub(&sbi->s_freeclusters_counter, 196 percpu_counter_sub(&sbi->s_freeclusters_counter,
@@ -442,14 +441,16 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
442 } 441 }
443 ext4_lock_group(sb, block_group); 442 ext4_lock_group(sb, block_group);
444 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 443 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
445
446 err = ext4_init_block_bitmap(sb, bh, block_group, desc); 444 err = ext4_init_block_bitmap(sb, bh, block_group, desc);
447 set_bitmap_uptodate(bh); 445 set_bitmap_uptodate(bh);
448 set_buffer_uptodate(bh); 446 set_buffer_uptodate(bh);
449 ext4_unlock_group(sb, block_group); 447 ext4_unlock_group(sb, block_group);
450 unlock_buffer(bh); 448 unlock_buffer(bh);
451 if (err) 449 if (err) {
450 ext4_error(sb, "Failed to init block bitmap for group "
451 "%u: %d", block_group, err);
452 goto out; 452 goto out;
453 }
453 goto verify; 454 goto verify;
454 } 455 }
455 ext4_unlock_group(sb, block_group); 456 ext4_unlock_group(sb, block_group);
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index c8021208a7eb..38f7562489bb 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -467,3 +467,59 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size)
467 return size; 467 return size;
468 return 0; 468 return 0;
469} 469}
470
471/*
472 * Validate dentries for encrypted directories to make sure we aren't
473 * potentially caching stale data after a key has been added or
474 * removed.
475 */
476static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
477{
478 struct inode *dir = d_inode(dentry->d_parent);
479 struct ext4_crypt_info *ci = EXT4_I(dir)->i_crypt_info;
480 int dir_has_key, cached_with_key;
481
482 if (!ext4_encrypted_inode(dir))
483 return 0;
484
485 if (ci && ci->ci_keyring_key &&
486 (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
487 (1 << KEY_FLAG_REVOKED) |
488 (1 << KEY_FLAG_DEAD))))
489 ci = NULL;
490
491 /* this should eventually be an flag in d_flags */
492 cached_with_key = dentry->d_fsdata != NULL;
493 dir_has_key = (ci != NULL);
494
495 /*
496 * If the dentry was cached without the key, and it is a
497 * negative dentry, it might be a valid name. We can't check
498 * if the key has since been made available due to locking
499 * reasons, so we fail the validation so ext4_lookup() can do
500 * this check.
501 *
502 * We also fail the validation if the dentry was created with
503 * the key present, but we no longer have the key, or vice versa.
504 */
505 if ((!cached_with_key && d_is_negative(dentry)) ||
506 (!cached_with_key && dir_has_key) ||
507 (cached_with_key && !dir_has_key)) {
508#if 0 /* Revalidation debug */
509 char buf[80];
510 char *cp = simple_dname(dentry, buf, sizeof(buf));
511
512 if (IS_ERR(cp))
513 cp = (char *) "???";
514 pr_err("revalidate: %s %p %d %d %d\n", cp, dentry->d_fsdata,
515 cached_with_key, d_is_negative(dentry),
516 dir_has_key);
517#endif
518 return 0;
519 }
520 return 1;
521}
522
523const struct dentry_operations ext4_encrypted_d_ops = {
524 .d_revalidate = ext4_d_revalidate,
525};
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 1d1bca74f844..33f5e2a50cf8 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -111,6 +111,12 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
111 int dir_has_error = 0; 111 int dir_has_error = 0;
112 struct ext4_str fname_crypto_str = {.name = NULL, .len = 0}; 112 struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
113 113
114 if (ext4_encrypted_inode(inode)) {
115 err = ext4_get_encryption_info(inode);
116 if (err && err != -ENOKEY)
117 return err;
118 }
119
114 if (is_dx_dir(inode)) { 120 if (is_dx_dir(inode)) {
115 err = ext4_dx_readdir(file, ctx); 121 err = ext4_dx_readdir(file, ctx);
116 if (err != ERR_BAD_DX_DIR) { 122 if (err != ERR_BAD_DX_DIR) {
@@ -157,8 +163,11 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
157 index, 1); 163 index, 1);
158 file->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT; 164 file->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
159 bh = ext4_bread(NULL, inode, map.m_lblk, 0); 165 bh = ext4_bread(NULL, inode, map.m_lblk, 0);
160 if (IS_ERR(bh)) 166 if (IS_ERR(bh)) {
161 return PTR_ERR(bh); 167 err = PTR_ERR(bh);
168 bh = NULL;
169 goto errout;
170 }
162 } 171 }
163 172
164 if (!bh) { 173 if (!bh) {
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0662b285dc8a..157b458a69d4 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2302,6 +2302,7 @@ struct page *ext4_encrypt(struct inode *inode,
2302int ext4_decrypt(struct page *page); 2302int ext4_decrypt(struct page *page);
2303int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk, 2303int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
2304 ext4_fsblk_t pblk, ext4_lblk_t len); 2304 ext4_fsblk_t pblk, ext4_lblk_t len);
2305extern const struct dentry_operations ext4_encrypted_d_ops;
2305 2306
2306#ifdef CONFIG_EXT4_FS_ENCRYPTION 2307#ifdef CONFIG_EXT4_FS_ENCRYPTION
2307int ext4_init_crypto(void); 2308int ext4_init_crypto(void);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 0ffabaf90aa5..3753ceb0b0dd 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3928,7 +3928,7 @@ static int
3928convert_initialized_extent(handle_t *handle, struct inode *inode, 3928convert_initialized_extent(handle_t *handle, struct inode *inode,
3929 struct ext4_map_blocks *map, 3929 struct ext4_map_blocks *map,
3930 struct ext4_ext_path **ppath, int flags, 3930 struct ext4_ext_path **ppath, int flags,
3931 unsigned int allocated, ext4_fsblk_t newblock) 3931 unsigned int allocated)
3932{ 3932{
3933 struct ext4_ext_path *path = *ppath; 3933 struct ext4_ext_path *path = *ppath;
3934 struct ext4_extent *ex; 3934 struct ext4_extent *ex;
@@ -4347,7 +4347,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
4347 (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN)) { 4347 (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN)) {
4348 allocated = convert_initialized_extent( 4348 allocated = convert_initialized_extent(
4349 handle, inode, map, &path, 4349 handle, inode, map, &path,
4350 flags, allocated, newblock); 4350 flags, allocated);
4351 goto out2; 4351 goto out2;
4352 } else if (!ext4_ext_is_unwritten(ex)) 4352 } else if (!ext4_ext_is_unwritten(ex))
4353 goto out; 4353 goto out;
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 1126436dada1..474f1a4d2ca8 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -350,6 +350,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
350 struct super_block *sb = inode->i_sb; 350 struct super_block *sb = inode->i_sb;
351 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 351 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
352 struct vfsmount *mnt = filp->f_path.mnt; 352 struct vfsmount *mnt = filp->f_path.mnt;
353 struct inode *dir = filp->f_path.dentry->d_parent->d_inode;
353 struct path path; 354 struct path path;
354 char buf[64], *cp; 355 char buf[64], *cp;
355 int ret; 356 int ret;
@@ -393,6 +394,14 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
393 if (ext4_encryption_info(inode) == NULL) 394 if (ext4_encryption_info(inode) == NULL)
394 return -ENOKEY; 395 return -ENOKEY;
395 } 396 }
397 if (ext4_encrypted_inode(dir) &&
398 !ext4_is_child_context_consistent_with_parent(dir, inode)) {
399 ext4_warning(inode->i_sb,
400 "Inconsistent encryption contexts: %lu/%lu\n",
401 (unsigned long) dir->i_ino,
402 (unsigned long) inode->i_ino);
403 return -EPERM;
404 }
396 /* 405 /*
397 * Set up the jbd2_inode if we are opening the inode for 406 * Set up the jbd2_inode if we are opening the inode for
398 * writing and the journal is present 407 * writing and the journal is present
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 3fcfd50a2e8a..acc0ad56bf2f 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -76,7 +76,6 @@ static int ext4_init_inode_bitmap(struct super_block *sb,
76 /* If checksum is bad mark all blocks and inodes use to prevent 76 /* If checksum is bad mark all blocks and inodes use to prevent
77 * allocation, essentially implementing a per-group read-only flag. */ 77 * allocation, essentially implementing a per-group read-only flag. */
78 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { 78 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
79 ext4_error(sb, "Checksum bad for group %u", block_group);
80 grp = ext4_get_group_info(sb, block_group); 79 grp = ext4_get_group_info(sb, block_group);
81 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) 80 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
82 percpu_counter_sub(&sbi->s_freeclusters_counter, 81 percpu_counter_sub(&sbi->s_freeclusters_counter,
@@ -191,8 +190,11 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
191 set_buffer_verified(bh); 190 set_buffer_verified(bh);
192 ext4_unlock_group(sb, block_group); 191 ext4_unlock_group(sb, block_group);
193 unlock_buffer(bh); 192 unlock_buffer(bh);
194 if (err) 193 if (err) {
194 ext4_error(sb, "Failed to init inode bitmap for group "
195 "%u: %d", block_group, err);
195 goto out; 196 goto out;
197 }
196 return bh; 198 return bh;
197 } 199 }
198 ext4_unlock_group(sb, block_group); 200 ext4_unlock_group(sb, block_group);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 83bc8bfb3bea..9cc57c3b4661 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -686,6 +686,34 @@ out_sem:
686 return retval; 686 return retval;
687} 687}
688 688
689/*
690 * Update EXT4_MAP_FLAGS in bh->b_state. For buffer heads attached to pages
691 * we have to be careful as someone else may be manipulating b_state as well.
692 */
693static void ext4_update_bh_state(struct buffer_head *bh, unsigned long flags)
694{
695 unsigned long old_state;
696 unsigned long new_state;
697
698 flags &= EXT4_MAP_FLAGS;
699
700 /* Dummy buffer_head? Set non-atomically. */
701 if (!bh->b_page) {
702 bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | flags;
703 return;
704 }
705 /*
706 * Someone else may be modifying b_state. Be careful! This is ugly but
707 * once we get rid of using bh as a container for mapping information
708 * to pass to / from get_block functions, this can go away.
709 */
710 do {
711 old_state = READ_ONCE(bh->b_state);
712 new_state = (old_state & ~EXT4_MAP_FLAGS) | flags;
713 } while (unlikely(
714 cmpxchg(&bh->b_state, old_state, new_state) != old_state));
715}
716
689/* Maximum number of blocks we map for direct IO at once. */ 717/* Maximum number of blocks we map for direct IO at once. */
690#define DIO_MAX_BLOCKS 4096 718#define DIO_MAX_BLOCKS 4096
691 719
@@ -722,7 +750,7 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock,
722 ext4_io_end_t *io_end = ext4_inode_aio(inode); 750 ext4_io_end_t *io_end = ext4_inode_aio(inode);
723 751
724 map_bh(bh, inode->i_sb, map.m_pblk); 752 map_bh(bh, inode->i_sb, map.m_pblk);
725 bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags; 753 ext4_update_bh_state(bh, map.m_flags);
726 if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN) 754 if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN)
727 set_buffer_defer_completion(bh); 755 set_buffer_defer_completion(bh);
728 bh->b_size = inode->i_sb->s_blocksize * map.m_len; 756 bh->b_size = inode->i_sb->s_blocksize * map.m_len;
@@ -1685,7 +1713,7 @@ int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
1685 return ret; 1713 return ret;
1686 1714
1687 map_bh(bh, inode->i_sb, map.m_pblk); 1715 map_bh(bh, inode->i_sb, map.m_pblk);
1688 bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags; 1716 ext4_update_bh_state(bh, map.m_flags);
1689 1717
1690 if (buffer_unwritten(bh)) { 1718 if (buffer_unwritten(bh)) {
1691 /* A delayed write to unwritten bh should be marked 1719 /* A delayed write to unwritten bh should be marked
@@ -3253,29 +3281,29 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
3253 * case, we allocate an io_end structure to hook to the iocb. 3281 * case, we allocate an io_end structure to hook to the iocb.
3254 */ 3282 */
3255 iocb->private = NULL; 3283 iocb->private = NULL;
3256 ext4_inode_aio_set(inode, NULL);
3257 if (!is_sync_kiocb(iocb)) {
3258 io_end = ext4_init_io_end(inode, GFP_NOFS);
3259 if (!io_end) {
3260 ret = -ENOMEM;
3261 goto retake_lock;
3262 }
3263 /*
3264 * Grab reference for DIO. Will be dropped in ext4_end_io_dio()
3265 */
3266 iocb->private = ext4_get_io_end(io_end);
3267 /*
3268 * we save the io structure for current async direct
3269 * IO, so that later ext4_map_blocks() could flag the
3270 * io structure whether there is a unwritten extents
3271 * needs to be converted when IO is completed.
3272 */
3273 ext4_inode_aio_set(inode, io_end);
3274 }
3275
3276 if (overwrite) { 3284 if (overwrite) {
3277 get_block_func = ext4_get_block_overwrite; 3285 get_block_func = ext4_get_block_overwrite;
3278 } else { 3286 } else {
3287 ext4_inode_aio_set(inode, NULL);
3288 if (!is_sync_kiocb(iocb)) {
3289 io_end = ext4_init_io_end(inode, GFP_NOFS);
3290 if (!io_end) {
3291 ret = -ENOMEM;
3292 goto retake_lock;
3293 }
3294 /*
3295 * Grab reference for DIO. Will be dropped in
3296 * ext4_end_io_dio()
3297 */
3298 iocb->private = ext4_get_io_end(io_end);
3299 /*
3300 * we save the io structure for current async direct
3301 * IO, so that later ext4_map_blocks() could flag the
3302 * io structure whether there is a unwritten extents
3303 * needs to be converted when IO is completed.
3304 */
3305 ext4_inode_aio_set(inode, io_end);
3306 }
3279 get_block_func = ext4_get_block_write; 3307 get_block_func = ext4_get_block_write;
3280 dio_flags = DIO_LOCKING; 3308 dio_flags = DIO_LOCKING;
3281 } 3309 }
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 0f6c36922c24..a99b010e2194 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -208,7 +208,7 @@ static int ext4_ioctl_setflags(struct inode *inode,
208{ 208{
209 struct ext4_inode_info *ei = EXT4_I(inode); 209 struct ext4_inode_info *ei = EXT4_I(inode);
210 handle_t *handle = NULL; 210 handle_t *handle = NULL;
211 int err = EPERM, migrate = 0; 211 int err = -EPERM, migrate = 0;
212 struct ext4_iloc iloc; 212 struct ext4_iloc iloc;
213 unsigned int oldflags, mask, i; 213 unsigned int oldflags, mask, i;
214 unsigned int jflag; 214 unsigned int jflag;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 61eaf74dca37..4424b7bf8ac6 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2285,7 +2285,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
2285 if (group == 0) 2285 if (group == 0)
2286 seq_puts(seq, "#group: free frags first [" 2286 seq_puts(seq, "#group: free frags first ["
2287 " 2^0 2^1 2^2 2^3 2^4 2^5 2^6 " 2287 " 2^0 2^1 2^2 2^3 2^4 2^5 2^6 "
2288 " 2^7 2^8 2^9 2^10 2^11 2^12 2^13 ]"); 2288 " 2^7 2^8 2^9 2^10 2^11 2^12 2^13 ]\n");
2289 2289
2290 i = (sb->s_blocksize_bits + 2) * sizeof(sg.info.bb_counters[0]) + 2290 i = (sb->s_blocksize_bits + 2) * sizeof(sg.info.bb_counters[0]) +
2291 sizeof(struct ext4_group_info); 2291 sizeof(struct ext4_group_info);
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index fb6f11709ae6..e032a0423e35 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -265,11 +265,12 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
265 ext4_lblk_t orig_blk_offset, donor_blk_offset; 265 ext4_lblk_t orig_blk_offset, donor_blk_offset;
266 unsigned long blocksize = orig_inode->i_sb->s_blocksize; 266 unsigned long blocksize = orig_inode->i_sb->s_blocksize;
267 unsigned int tmp_data_size, data_size, replaced_size; 267 unsigned int tmp_data_size, data_size, replaced_size;
268 int err2, jblocks, retries = 0; 268 int i, err2, jblocks, retries = 0;
269 int replaced_count = 0; 269 int replaced_count = 0;
270 int from = data_offset_in_page << orig_inode->i_blkbits; 270 int from = data_offset_in_page << orig_inode->i_blkbits;
271 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits; 271 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
272 struct super_block *sb = orig_inode->i_sb; 272 struct super_block *sb = orig_inode->i_sb;
273 struct buffer_head *bh = NULL;
273 274
274 /* 275 /*
275 * It needs twice the amount of ordinary journal buffers because 276 * It needs twice the amount of ordinary journal buffers because
@@ -380,8 +381,16 @@ data_copy:
380 } 381 }
381 /* Perform all necessary steps similar write_begin()/write_end() 382 /* Perform all necessary steps similar write_begin()/write_end()
382 * but keeping in mind that i_size will not change */ 383 * but keeping in mind that i_size will not change */
383 *err = __block_write_begin(pagep[0], from, replaced_size, 384 if (!page_has_buffers(pagep[0]))
384 ext4_get_block); 385 create_empty_buffers(pagep[0], 1 << orig_inode->i_blkbits, 0);
386 bh = page_buffers(pagep[0]);
387 for (i = 0; i < data_offset_in_page; i++)
388 bh = bh->b_this_page;
389 for (i = 0; i < block_len_in_page; i++) {
390 *err = ext4_get_block(orig_inode, orig_blk_offset + i, bh, 0);
391 if (*err < 0)
392 break;
393 }
385 if (!*err) 394 if (!*err)
386 *err = block_commit_write(pagep[0], from, from + replaced_size); 395 *err = block_commit_write(pagep[0], from, from + replaced_size);
387 396
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 06574dd77614..48e4b8907826 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1558,6 +1558,24 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
1558 struct ext4_dir_entry_2 *de; 1558 struct ext4_dir_entry_2 *de;
1559 struct buffer_head *bh; 1559 struct buffer_head *bh;
1560 1560
1561 if (ext4_encrypted_inode(dir)) {
1562 int res = ext4_get_encryption_info(dir);
1563
1564 /*
1565 * This should be a properly defined flag for
1566 * dentry->d_flags when we uplift this to the VFS.
1567 * d_fsdata is set to (void *) 1 if if the dentry is
1568 * created while the directory was encrypted and we
1569 * don't have access to the key.
1570 */
1571 dentry->d_fsdata = NULL;
1572 if (ext4_encryption_info(dir))
1573 dentry->d_fsdata = (void *) 1;
1574 d_set_d_op(dentry, &ext4_encrypted_d_ops);
1575 if (res && res != -ENOKEY)
1576 return ERR_PTR(res);
1577 }
1578
1561 if (dentry->d_name.len > EXT4_NAME_LEN) 1579 if (dentry->d_name.len > EXT4_NAME_LEN)
1562 return ERR_PTR(-ENAMETOOLONG); 1580 return ERR_PTR(-ENAMETOOLONG);
1563 1581
@@ -1585,11 +1603,15 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
1585 return ERR_PTR(-EFSCORRUPTED); 1603 return ERR_PTR(-EFSCORRUPTED);
1586 } 1604 }
1587 if (!IS_ERR(inode) && ext4_encrypted_inode(dir) && 1605 if (!IS_ERR(inode) && ext4_encrypted_inode(dir) &&
1588 (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || 1606 (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
1589 S_ISLNK(inode->i_mode)) &&
1590 !ext4_is_child_context_consistent_with_parent(dir, 1607 !ext4_is_child_context_consistent_with_parent(dir,
1591 inode)) { 1608 inode)) {
1609 int nokey = ext4_encrypted_inode(inode) &&
1610 !ext4_encryption_info(inode);
1611
1592 iput(inode); 1612 iput(inode);
1613 if (nokey)
1614 return ERR_PTR(-ENOKEY);
1593 ext4_warning(inode->i_sb, 1615 ext4_warning(inode->i_sb,
1594 "Inconsistent encryption contexts: %lu/%lu\n", 1616 "Inconsistent encryption contexts: %lu/%lu\n",
1595 (unsigned long) dir->i_ino, 1617 (unsigned long) dir->i_ino,
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index ad62d7acc315..34038e3598d5 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -198,7 +198,7 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size)
198 if (flex_gd == NULL) 198 if (flex_gd == NULL)
199 goto out3; 199 goto out3;
200 200
201 if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_flex_group_data)) 201 if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_group_data))
202 goto out2; 202 goto out2;
203 flex_gd->count = flexbg_size; 203 flex_gd->count = flexbg_size;
204 204