Skip to content

Commit 8a98313

Browse files
zhangyi089gregkh
authored andcommitted
ext4: move out inode_lock into ext4_fallocate()
[ Upstream commit ea3f17e ] Currently, all five sub-functions of ext4_fallocate() acquire the inode's i_rwsem at the beginning and release it before exiting. This process can be simplified by factoring out the management of i_rwsem into the ext4_fallocate() function. Signed-off-by: Zhang Yi <[email protected]> Reviewed-by: Jan Kara <[email protected]> Reviewed-by: Ojaswin Mujoo <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Theodore Ts'o <[email protected]> Stable-dep-of: 29ec9be ("ext4: fix incorrect punch max_end") Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 1697ca5 commit 8a98313

File tree

2 files changed

+33
-70
lines changed

2 files changed

+33
-70
lines changed

fs/ext4/extents.c

Lines changed: 28 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4579,31 +4579,26 @@ static long ext4_zero_range(struct file *file, loff_t offset,
45794579
int ret, flags, credits;
45804580

45814581
trace_ext4_zero_range(inode, offset, len, mode);
4582+
WARN_ON_ONCE(!inode_is_locked(inode));
45824583

4583-
inode_lock(inode);
4584-
4585-
/*
4586-
* Indirect files do not support unwritten extents
4587-
*/
4588-
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
4589-
ret = -EOPNOTSUPP;
4590-
goto out;
4591-
}
4584+
/* Indirect files do not support unwritten extents */
4585+
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
4586+
return -EOPNOTSUPP;
45924587

45934588
if (!(mode & FALLOC_FL_KEEP_SIZE) &&
45944589
(end > inode->i_size || end > EXT4_I(inode)->i_disksize)) {
45954590
new_size = end;
45964591
ret = inode_newsize_ok(inode, new_size);
45974592
if (ret)
4598-
goto out;
4593+
return ret;
45994594
}
46004595

46014596
/* Wait all existing dio workers, newcomers will block on i_rwsem */
46024597
inode_dio_wait(inode);
46034598

46044599
ret = file_modified(file);
46054600
if (ret)
4606-
goto out;
4601+
return ret;
46074602

46084603
/*
46094604
* Prevent page faults from reinstantiating pages we have released
@@ -4685,8 +4680,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
46854680
ext4_journal_stop(handle);
46864681
out_invalidate_lock:
46874682
filemap_invalidate_unlock(mapping);
4688-
out:
4689-
inode_unlock(inode);
46904683
return ret;
46914684
}
46924685

@@ -4700,12 +4693,11 @@ static long ext4_do_fallocate(struct file *file, loff_t offset,
47004693
int ret;
47014694

47024695
trace_ext4_fallocate_enter(inode, offset, len, mode);
4696+
WARN_ON_ONCE(!inode_is_locked(inode));
47034697

47044698
start_lblk = offset >> inode->i_blkbits;
47054699
len_lblk = EXT4_MAX_BLOCKS(len, offset, inode->i_blkbits);
47064700

4707-
inode_lock(inode);
4708-
47094701
/* We only support preallocation for extent-based files only. */
47104702
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
47114703
ret = -EOPNOTSUPP;
@@ -4737,7 +4729,6 @@ static long ext4_do_fallocate(struct file *file, loff_t offset,
47374729
EXT4_I(inode)->i_sync_tid);
47384730
}
47394731
out:
4740-
inode_unlock(inode);
47414732
trace_ext4_fallocate_exit(inode, offset, len_lblk, ret);
47424733
return ret;
47434734
}
@@ -4772,9 +4763,8 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
47724763

47734764
inode_lock(inode);
47744765
ret = ext4_convert_inline_data(inode);
4775-
inode_unlock(inode);
47764766
if (ret)
4777-
return ret;
4767+
goto out_inode_lock;
47784768

47794769
if (mode & FALLOC_FL_PUNCH_HOLE)
47804770
ret = ext4_punch_hole(file, offset, len);
@@ -4786,7 +4776,8 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
47864776
ret = ext4_zero_range(file, offset, len, mode);
47874777
else
47884778
ret = ext4_do_fallocate(file, offset, len, mode);
4789-
4779+
out_inode_lock:
4780+
inode_unlock(inode);
47904781
return ret;
47914782
}
47924783

@@ -5291,36 +5282,27 @@ static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len)
52915282
int ret;
52925283

52935284
trace_ext4_collapse_range(inode, offset, len);
5294-
5295-
inode_lock(inode);
5285+
WARN_ON_ONCE(!inode_is_locked(inode));
52965286

52975287
/* Currently just for extent based files */
5298-
if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
5299-
ret = -EOPNOTSUPP;
5300-
goto out;
5301-
}
5302-
5288+
if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
5289+
return -EOPNOTSUPP;
53035290
/* Collapse range works only on fs cluster size aligned regions. */
5304-
if (!IS_ALIGNED(offset | len, EXT4_CLUSTER_SIZE(sb))) {
5305-
ret = -EINVAL;
5306-
goto out;
5307-
}
5308-
5291+
if (!IS_ALIGNED(offset | len, EXT4_CLUSTER_SIZE(sb)))
5292+
return -EINVAL;
53095293
/*
53105294
* There is no need to overlap collapse range with EOF, in which case
53115295
* it is effectively a truncate operation
53125296
*/
5313-
if (end >= inode->i_size) {
5314-
ret = -EINVAL;
5315-
goto out;
5316-
}
5297+
if (end >= inode->i_size)
5298+
return -EINVAL;
53175299

53185300
/* Wait for existing dio to complete */
53195301
inode_dio_wait(inode);
53205302

53215303
ret = file_modified(file);
53225304
if (ret)
5323-
goto out;
5305+
return ret;
53245306

53255307
/*
53265308
* Prevent page faults from reinstantiating pages we have released from
@@ -5395,8 +5377,6 @@ static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len)
53955377
ext4_journal_stop(handle);
53965378
out_invalidate_lock:
53975379
filemap_invalidate_unlock(mapping);
5398-
out:
5399-
inode_unlock(inode);
54005380
return ret;
54015381
}
54025382

@@ -5422,39 +5402,27 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
54225402
loff_t start;
54235403

54245404
trace_ext4_insert_range(inode, offset, len);
5425-
5426-
inode_lock(inode);
5405+
WARN_ON_ONCE(!inode_is_locked(inode));
54275406

54285407
/* Currently just for extent based files */
5429-
if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
5430-
ret = -EOPNOTSUPP;
5431-
goto out;
5432-
}
5433-
5408+
if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
5409+
return -EOPNOTSUPP;
54345410
/* Insert range works only on fs cluster size aligned regions. */
5435-
if (!IS_ALIGNED(offset | len, EXT4_CLUSTER_SIZE(sb))) {
5436-
ret = -EINVAL;
5437-
goto out;
5438-
}
5439-
5411+
if (!IS_ALIGNED(offset | len, EXT4_CLUSTER_SIZE(sb)))
5412+
return -EINVAL;
54405413
/* Offset must be less than i_size */
5441-
if (offset >= inode->i_size) {
5442-
ret = -EINVAL;
5443-
goto out;
5444-
}
5445-
5414+
if (offset >= inode->i_size)
5415+
return -EINVAL;
54465416
/* Check whether the maximum file size would be exceeded */
5447-
if (len > inode->i_sb->s_maxbytes - inode->i_size) {
5448-
ret = -EFBIG;
5449-
goto out;
5450-
}
5417+
if (len > inode->i_sb->s_maxbytes - inode->i_size)
5418+
return -EFBIG;
54515419

54525420
/* Wait for existing dio to complete */
54535421
inode_dio_wait(inode);
54545422

54555423
ret = file_modified(file);
54565424
if (ret)
5457-
goto out;
5425+
return ret;
54585426

54595427
/*
54605428
* Prevent page faults from reinstantiating pages we have released from
@@ -5555,8 +5523,6 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
55555523
ext4_journal_stop(handle);
55565524
out_invalidate_lock:
55575525
filemap_invalidate_unlock(mapping);
5558-
out:
5559-
inode_unlock(inode);
55605526
return ret;
55615527
}
55625528

fs/ext4/inode.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3997,15 +3997,14 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
39973997
loff_t end = offset + length;
39983998
handle_t *handle;
39993999
unsigned int credits;
4000-
int ret = 0;
4000+
int ret;
40014001

40024002
trace_ext4_punch_hole(inode, offset, length, 0);
4003-
4004-
inode_lock(inode);
4003+
WARN_ON_ONCE(!inode_is_locked(inode));
40054004

40064005
/* No need to punch hole beyond i_size */
40074006
if (offset >= inode->i_size)
4008-
goto out;
4007+
return 0;
40094008

40104009
/*
40114010
* If the hole extends beyond i_size, set the hole to end after
@@ -4025,15 +4024,15 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
40254024
if (!IS_ALIGNED(offset | end, sb->s_blocksize)) {
40264025
ret = ext4_inode_attach_jinode(inode);
40274026
if (ret < 0)
4028-
goto out;
4027+
return ret;
40294028
}
40304029

40314030
/* Wait all existing dio workers, newcomers will block on i_rwsem */
40324031
inode_dio_wait(inode);
40334032

40344033
ret = file_modified(file);
40354034
if (ret)
4036-
goto out;
4035+
return ret;
40374036

40384037
/*
40394038
* Prevent page faults from reinstantiating pages we have released from
@@ -4109,8 +4108,6 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
41094108
ext4_journal_stop(handle);
41104109
out_invalidate_lock:
41114110
filemap_invalidate_unlock(mapping);
4112-
out:
4113-
inode_unlock(inode);
41144111
return ret;
41154112
}
41164113

0 commit comments

Comments
 (0)