Skip to content

Commit edc6d01

Browse files
committed
f2fs: Convert to using invalidate_lock
Use invalidate_lock instead of f2fs' private i_mmap_sem. The intended purpose is exactly the same. By this conversion we fix a long standing race between hole punching and read(2) / readahead(2) paths that can lead to stale page cache contents. CC: Jaegeuk Kim <jaegeuk@kernel.org> CC: Chao Yu <yuchao0@huawei.com> CC: linux-f2fs-devel@lists.sourceforge.net Acked-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jan Kara <jack@suse.cz>
1 parent 448f949 commit edc6d01

File tree

4 files changed

+34
-38
lines changed

4 files changed

+34
-38
lines changed

fs/f2fs/data.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3187,12 +3187,12 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to)
31873187
/* In the fs-verity case, f2fs_end_enable_verity() does the truncate */
31883188
if (to > i_size && !f2fs_verity_in_progress(inode)) {
31893189
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
3190-
down_write(&F2FS_I(inode)->i_mmap_sem);
3190+
filemap_invalidate_lock(mapping);
31913191

31923192
truncate_pagecache(inode, i_size);
31933193
f2fs_truncate_blocks(inode, i_size, true);
31943194

3195-
up_write(&F2FS_I(inode)->i_mmap_sem);
3195+
filemap_invalidate_unlock(mapping);
31963196
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
31973197
}
31983198
}
@@ -3852,7 +3852,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk,
38523852
int ret = 0;
38533853

38543854
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
3855-
down_write(&F2FS_I(inode)->i_mmap_sem);
3855+
filemap_invalidate_lock(inode->i_mapping);
38563856

38573857
set_inode_flag(inode, FI_ALIGNED_WRITE);
38583858

@@ -3894,7 +3894,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk,
38943894
clear_inode_flag(inode, FI_DO_DEFRAG);
38953895
clear_inode_flag(inode, FI_ALIGNED_WRITE);
38963896

3897-
up_write(&F2FS_I(inode)->i_mmap_sem);
3897+
filemap_invalidate_unlock(inode->i_mapping);
38983898
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
38993899

39003900
return ret;

fs/f2fs/f2fs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,6 @@ struct f2fs_inode_info {
754754

755755
/* avoid racing between foreground op and gc */
756756
struct rw_semaphore i_gc_rwsem[2];
757-
struct rw_semaphore i_mmap_sem;
758757
struct rw_semaphore i_xattr_sem; /* avoid racing between reading and changing EAs */
759758

760759
int i_extra_isize; /* size of extra space located in i_addr */

fs/f2fs/file.c

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
3838
struct inode *inode = file_inode(vmf->vma->vm_file);
3939
vm_fault_t ret;
4040

41-
down_read(&F2FS_I(inode)->i_mmap_sem);
4241
ret = filemap_fault(vmf);
43-
up_read(&F2FS_I(inode)->i_mmap_sem);
44-
4542
if (!ret)
4643
f2fs_update_iostat(F2FS_I_SB(inode), APP_MAPPED_READ_IO,
4744
F2FS_BLKSIZE);
@@ -101,7 +98,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
10198
f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
10299

103100
file_update_time(vmf->vma->vm_file);
104-
down_read(&F2FS_I(inode)->i_mmap_sem);
101+
filemap_invalidate_lock_shared(inode->i_mapping);
105102
lock_page(page);
106103
if (unlikely(page->mapping != inode->i_mapping ||
107104
page_offset(page) > i_size_read(inode) ||
@@ -159,7 +156,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
159156

160157
trace_f2fs_vm_page_mkwrite(page, DATA);
161158
out_sem:
162-
up_read(&F2FS_I(inode)->i_mmap_sem);
159+
filemap_invalidate_unlock_shared(inode->i_mapping);
163160

164161
sb_end_pagefault(inode->i_sb);
165162
err:
@@ -940,7 +937,7 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
940937
}
941938

942939
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
943-
down_write(&F2FS_I(inode)->i_mmap_sem);
940+
filemap_invalidate_lock(inode->i_mapping);
944941

945942
truncate_setsize(inode, attr->ia_size);
946943

@@ -950,7 +947,7 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
950947
* do not trim all blocks after i_size if target size is
951948
* larger than i_size.
952949
*/
953-
up_write(&F2FS_I(inode)->i_mmap_sem);
950+
filemap_invalidate_unlock(inode->i_mapping);
954951
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
955952
if (err)
956953
return err;
@@ -1095,7 +1092,7 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
10951092
blk_end = (loff_t)pg_end << PAGE_SHIFT;
10961093

10971094
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
1098-
down_write(&F2FS_I(inode)->i_mmap_sem);
1095+
filemap_invalidate_lock(mapping);
10991096

11001097
truncate_inode_pages_range(mapping, blk_start,
11011098
blk_end - 1);
@@ -1104,7 +1101,7 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
11041101
ret = f2fs_truncate_hole(inode, pg_start, pg_end);
11051102
f2fs_unlock_op(sbi);
11061103

1107-
up_write(&F2FS_I(inode)->i_mmap_sem);
1104+
filemap_invalidate_unlock(mapping);
11081105
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
11091106
}
11101107
}
@@ -1339,15 +1336,15 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
13391336

13401337
/* avoid gc operation during block exchange */
13411338
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
1342-
down_write(&F2FS_I(inode)->i_mmap_sem);
1339+
filemap_invalidate_lock(inode->i_mapping);
13431340

13441341
f2fs_lock_op(sbi);
13451342
f2fs_drop_extent_tree(inode);
13461343
truncate_pagecache(inode, offset);
13471344
ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true);
13481345
f2fs_unlock_op(sbi);
13491346

1350-
up_write(&F2FS_I(inode)->i_mmap_sem);
1347+
filemap_invalidate_unlock(inode->i_mapping);
13511348
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
13521349
return ret;
13531350
}
@@ -1378,13 +1375,13 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
13781375
return ret;
13791376

13801377
/* write out all moved pages, if possible */
1381-
down_write(&F2FS_I(inode)->i_mmap_sem);
1378+
filemap_invalidate_lock(inode->i_mapping);
13821379
filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
13831380
truncate_pagecache(inode, offset);
13841381

13851382
new_size = i_size_read(inode) - len;
13861383
ret = f2fs_truncate_blocks(inode, new_size, true);
1387-
up_write(&F2FS_I(inode)->i_mmap_sem);
1384+
filemap_invalidate_unlock(inode->i_mapping);
13881385
if (!ret)
13891386
f2fs_i_size_write(inode, new_size);
13901387
return ret;
@@ -1484,7 +1481,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
14841481
pgoff_t end;
14851482

14861483
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
1487-
down_write(&F2FS_I(inode)->i_mmap_sem);
1484+
filemap_invalidate_lock(mapping);
14881485

14891486
truncate_pagecache_range(inode,
14901487
(loff_t)index << PAGE_SHIFT,
@@ -1496,7 +1493,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
14961493
ret = f2fs_get_dnode_of_data(&dn, index, ALLOC_NODE);
14971494
if (ret) {
14981495
f2fs_unlock_op(sbi);
1499-
up_write(&F2FS_I(inode)->i_mmap_sem);
1496+
filemap_invalidate_unlock(mapping);
15001497
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
15011498
goto out;
15021499
}
@@ -1508,7 +1505,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
15081505
f2fs_put_dnode(&dn);
15091506

15101507
f2fs_unlock_op(sbi);
1511-
up_write(&F2FS_I(inode)->i_mmap_sem);
1508+
filemap_invalidate_unlock(mapping);
15121509
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
15131510

15141511
f2fs_balance_fs(sbi, dn.node_changed);
@@ -1543,6 +1540,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
15431540
static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
15441541
{
15451542
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
1543+
struct address_space *mapping = inode->i_mapping;
15461544
pgoff_t nr, pg_start, pg_end, delta, idx;
15471545
loff_t new_size;
15481546
int ret = 0;
@@ -1565,14 +1563,14 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
15651563

15661564
f2fs_balance_fs(sbi, true);
15671565

1568-
down_write(&F2FS_I(inode)->i_mmap_sem);
1566+
filemap_invalidate_lock(mapping);
15691567
ret = f2fs_truncate_blocks(inode, i_size_read(inode), true);
1570-
up_write(&F2FS_I(inode)->i_mmap_sem);
1568+
filemap_invalidate_unlock(mapping);
15711569
if (ret)
15721570
return ret;
15731571

15741572
/* write out all dirty pages from offset */
1575-
ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
1573+
ret = filemap_write_and_wait_range(mapping, offset, LLONG_MAX);
15761574
if (ret)
15771575
return ret;
15781576

@@ -1583,7 +1581,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
15831581

15841582
/* avoid gc operation during block exchange */
15851583
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
1586-
down_write(&F2FS_I(inode)->i_mmap_sem);
1584+
filemap_invalidate_lock(mapping);
15871585
truncate_pagecache(inode, offset);
15881586

15891587
while (!ret && idx > pg_start) {
@@ -1599,14 +1597,14 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
15991597
idx + delta, nr, false);
16001598
f2fs_unlock_op(sbi);
16011599
}
1602-
up_write(&F2FS_I(inode)->i_mmap_sem);
1600+
filemap_invalidate_unlock(mapping);
16031601
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
16041602

16051603
/* write out all moved pages, if possible */
1606-
down_write(&F2FS_I(inode)->i_mmap_sem);
1607-
filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
1604+
filemap_invalidate_lock(mapping);
1605+
filemap_write_and_wait_range(mapping, offset, LLONG_MAX);
16081606
truncate_pagecache(inode, offset);
1609-
up_write(&F2FS_I(inode)->i_mmap_sem);
1607+
filemap_invalidate_unlock(mapping);
16101608

16111609
if (!ret)
16121610
f2fs_i_size_write(inode, new_size);
@@ -3440,7 +3438,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
34403438
goto out;
34413439

34423440
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
3443-
down_write(&F2FS_I(inode)->i_mmap_sem);
3441+
filemap_invalidate_lock(inode->i_mapping);
34443442

34453443
last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
34463444

@@ -3476,7 +3474,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
34763474
}
34773475

34783476
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
3479-
up_write(&F2FS_I(inode)->i_mmap_sem);
3477+
filemap_invalidate_unlock(inode->i_mapping);
34803478
out:
34813479
inode_unlock(inode);
34823480

@@ -3593,7 +3591,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
35933591
}
35943592

35953593
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
3596-
down_write(&F2FS_I(inode)->i_mmap_sem);
3594+
filemap_invalidate_lock(inode->i_mapping);
35973595

35983596
last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
35993597

@@ -3629,7 +3627,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
36293627
}
36303628

36313629
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
3632-
up_write(&F2FS_I(inode)->i_mmap_sem);
3630+
filemap_invalidate_unlock(inode->i_mapping);
36333631

36343632
if (ret >= 0) {
36353633
clear_inode_flag(inode, FI_COMPRESS_RELEASED);
@@ -3748,7 +3746,7 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg)
37483746
goto err;
37493747

37503748
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
3751-
down_write(&F2FS_I(inode)->i_mmap_sem);
3749+
filemap_invalidate_lock(mapping);
37523750

37533751
ret = filemap_write_and_wait_range(mapping, range.start,
37543752
to_end ? LLONG_MAX : end_addr - 1);
@@ -3835,7 +3833,7 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg)
38353833
ret = f2fs_secure_erase(prev_bdev, inode, prev_index,
38363834
prev_block, len, range.flags);
38373835
out:
3838-
up_write(&F2FS_I(inode)->i_mmap_sem);
3836+
filemap_invalidate_unlock(mapping);
38393837
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
38403838
err:
38413839
inode_unlock(inode);
@@ -4313,9 +4311,9 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
43134311
/* if we couldn't write data, we should deallocate blocks. */
43144312
if (preallocated && i_size_read(inode) < target_size) {
43154313
down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
4316-
down_write(&F2FS_I(inode)->i_mmap_sem);
4314+
filemap_invalidate_lock(inode->i_mapping);
43174315
f2fs_truncate(inode);
4318-
up_write(&F2FS_I(inode)->i_mmap_sem);
4316+
filemap_invalidate_unlock(inode->i_mapping);
43194317
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
43204318
}
43214319

fs/f2fs/super.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,6 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
12891289
mutex_init(&fi->inmem_lock);
12901290
init_rwsem(&fi->i_gc_rwsem[READ]);
12911291
init_rwsem(&fi->i_gc_rwsem[WRITE]);
1292-
init_rwsem(&fi->i_mmap_sem);
12931292
init_rwsem(&fi->i_xattr_sem);
12941293

12951294
/* Will be used by directory only */

0 commit comments

Comments
 (0)