Skip to content

Commit ed66da1

Browse files
committed
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 fixes from Ted Ts'o: "A large number of ext4 bug fixes and cleanups for v4.13" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: fix copy paste error in ext4_swap_extents() ext4: fix overflow caused by missing cast in ext4_resize_fs() ext4, project: expand inode extra size if possible ext4: cleanup ext4_expand_extra_isize_ea() ext4: restructure ext4_expand_extra_isize ext4: fix forgetten xattr lock protection in ext4_expand_extra_isize ext4: make xattr inode reads faster ext4: inplace xattr block update fails to deduplicate blocks ext4: remove unused mode parameter ext4: fix warning about stack corruption ext4: fix dir_nlink behaviour ext4: silence array overflow warning ext4: fix SEEK_HOLE/SEEK_DATA for blocksize < pagesize ext4: release discard bio after sending discard commands ext4: convert swap_inode_data() over to use swap() on most of the fields ext4: error should be cleared if ea_inode isn't added to the cache ext4: Don't clear SGID when inheriting ACLs ext4: preserve i_mode if __ext4_set_acl() fails ext4: remove unused metadata accounting variables ext4: correct comment references to ext4_ext_direct_IO()
2 parents 6ea1bc9 + 4e56201 commit ed66da1

File tree

13 files changed

+290
-196
lines changed

13 files changed

+290
-196
lines changed

fs/ext4/acl.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,6 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
193193
switch (type) {
194194
case ACL_TYPE_ACCESS:
195195
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
196-
if (acl) {
197-
error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
198-
if (error)
199-
return error;
200-
inode->i_ctime = current_time(inode);
201-
ext4_mark_inode_dirty(handle, inode);
202-
}
203196
break;
204197

205198
case ACL_TYPE_DEFAULT:
@@ -221,8 +214,9 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
221214
value, size, xattr_flags);
222215

223216
kfree(value);
224-
if (!error)
217+
if (!error) {
225218
set_cached_acl(inode, type, acl);
219+
}
226220

227221
return error;
228222
}
@@ -233,6 +227,8 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type)
233227
handle_t *handle;
234228
int error, credits, retries = 0;
235229
size_t acl_size = acl ? ext4_acl_size(acl->a_count) : 0;
230+
umode_t mode = inode->i_mode;
231+
int update_mode = 0;
236232

237233
error = dquot_initialize(inode);
238234
if (error)
@@ -247,7 +243,20 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type)
247243
if (IS_ERR(handle))
248244
return PTR_ERR(handle);
249245

246+
if ((type == ACL_TYPE_ACCESS) && acl) {
247+
error = posix_acl_update_mode(inode, &mode, &acl);
248+
if (error)
249+
goto out_stop;
250+
update_mode = 1;
251+
}
252+
250253
error = __ext4_set_acl(handle, inode, type, acl, 0 /* xattr_flags */);
254+
if (!error && update_mode) {
255+
inode->i_mode = mode;
256+
inode->i_ctime = current_time(inode);
257+
ext4_mark_inode_dirty(handle, inode);
258+
}
259+
out_stop:
251260
ext4_journal_stop(handle);
252261
if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
253262
goto retry;

fs/ext4/ext4.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ struct ext4_inode_info {
961961
/*
962962
* i_block_group is the number of the block group which contains
963963
* this file's inode. Constant across the lifetime of the inode,
964-
* it is ued for making block allocation decisions - we try to
964+
* it is used for making block allocation decisions - we try to
965965
* place a file's data blocks near its inode block, and new inodes
966966
* near to their parent directory's inode.
967967
*/
@@ -1049,10 +1049,8 @@ struct ext4_inode_info {
10491049
ext4_group_t i_last_alloc_group;
10501050

10511051
/* allocation reservation info for delalloc */
1052-
/* In case of bigalloc, these refer to clusters rather than blocks */
1052+
/* In case of bigalloc, this refer to clusters rather than blocks */
10531053
unsigned int i_reserved_data_blocks;
1054-
unsigned int i_reserved_meta_blocks;
1055-
unsigned int i_allocated_meta_blocks;
10561054
ext4_lblk_t i_da_metadata_calc_last_lblock;
10571055
int i_da_metadata_calc_len;
10581056

@@ -2022,7 +2020,8 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize)
20222020

20232021
#define is_dx(dir) (ext4_has_feature_dir_index((dir)->i_sb) && \
20242022
ext4_test_inode_flag((dir), EXT4_INODE_INDEX))
2025-
#define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
2023+
#define EXT4_DIR_LINK_MAX(dir) unlikely((dir)->i_nlink >= EXT4_LINK_MAX && \
2024+
!(ext4_has_feature_dir_nlink((dir)->i_sb) && is_dx(dir)))
20262025
#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
20272026

20282027
/* Legal values for the dx_root hash_version field: */
@@ -2462,6 +2461,8 @@ extern void ext4_process_freed_data(struct super_block *sb, tid_t commit_tid);
24622461
int ext4_inode_is_fast_symlink(struct inode *inode);
24632462
struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int);
24642463
struct buffer_head *ext4_bread(handle_t *, struct inode *, ext4_lblk_t, int);
2464+
int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count,
2465+
bool wait, struct buffer_head **bhs);
24652466
int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
24662467
struct buffer_head *bh_result, int create);
24672468
int ext4_get_block(struct inode *inode, sector_t iblock,
@@ -3074,7 +3075,7 @@ extern int ext4_handle_dirty_dirent_node(handle_t *handle,
30743075
struct inode *inode,
30753076
struct buffer_head *bh);
30763077
#define S_SHIFT 12
3077-
static const unsigned char ext4_type_by_mode[S_IFMT >> S_SHIFT] = {
3078+
static const unsigned char ext4_type_by_mode[(S_IFMT >> S_SHIFT) + 1] = {
30783079
[S_IFREG >> S_SHIFT] = EXT4_FT_REG_FILE,
30793080
[S_IFDIR >> S_SHIFT] = EXT4_FT_DIR,
30803081
[S_IFCHR >> S_SHIFT] = EXT4_FT_CHRDEV,

fs/ext4/ext4_jbd2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ int ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
227227

228228
int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
229229

230+
int ext4_expand_extra_isize(struct inode *inode,
231+
unsigned int new_extra_isize,
232+
struct ext4_iloc *iloc);
230233
/*
231234
* Wrapper functions with which ext4 calls into JBD.
232235
*/

fs/ext4/extents.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4652,7 +4652,7 @@ int ext4_ext_truncate(handle_t *handle, struct inode *inode)
46524652

46534653
static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
46544654
ext4_lblk_t len, loff_t new_size,
4655-
int flags, int mode)
4655+
int flags)
46564656
{
46574657
struct inode *inode = file_inode(file);
46584658
handle_t *handle;
@@ -4815,7 +4815,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
48154815
round_down(offset, 1 << blkbits) >> blkbits,
48164816
(round_up((offset + len), 1 << blkbits) -
48174817
round_down(offset, 1 << blkbits)) >> blkbits,
4818-
new_size, flags, mode);
4818+
new_size, flags);
48194819
if (ret)
48204820
goto out_dio;
48214821

@@ -4841,7 +4841,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
48414841
inode->i_mtime = inode->i_ctime = current_time(inode);
48424842

48434843
ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
4844-
flags, mode);
4844+
flags);
48454845
up_write(&EXT4_I(inode)->i_mmap_sem);
48464846
if (ret)
48474847
goto out_dio;
@@ -4976,8 +4976,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
49764976
ext4_inode_block_unlocked_dio(inode);
49774977
inode_dio_wait(inode);
49784978

4979-
ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
4980-
flags, mode);
4979+
ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags);
49814980
ext4_inode_resume_unlocked_dio(inode);
49824981
if (ret)
49834982
goto out;
@@ -5837,7 +5836,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
58375836
if (e1_blk > lblk1)
58385837
next1 = e1_blk;
58395838
if (e2_blk > lblk2)
5840-
next2 = e1_blk;
5839+
next2 = e2_blk;
58415840
/* Do we have something to swap */
58425841
if (next1 == EXT_MAX_BLOCKS || next2 == EXT_MAX_BLOCKS)
58435842
goto finish;

fs/ext4/file.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,8 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
537537
lastoff = page_offset(page);
538538
bh = head = page_buffers(page);
539539
do {
540+
if (lastoff + bh->b_size <= startoff)
541+
goto next;
540542
if (buffer_uptodate(bh) ||
541543
buffer_unwritten(bh)) {
542544
if (whence == SEEK_DATA)
@@ -551,6 +553,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
551553
unlock_page(page);
552554
goto out;
553555
}
556+
next:
554557
lastoff += bh->b_size;
555558
bh = bh->b_this_page;
556559
} while (bh != head);

0 commit comments

Comments
 (0)