Skip to content

Commit cda6a60

Browse files
committed
Merge tag 'fixes_for_v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull udf and ext2 fixes from Jan Kara: - a couple of smaller cleanups and fixes for ext2 - fixes of a data corruption issues in udf when handling holes and preallocation extents - fixes and cleanups of several smaller issues in udf - add maintainer entry for isofs * tag 'fixes_for_v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: Fix extending file within last block udf: Discard preallocation before extending file with a hole udf: Do not bother looking for prealloc extents if i_lenExtents matches i_size udf: Fix preallocation discarding at indirect extent boundary udf: Increase UDF_MAX_READ_VERSION to 0x0260 fs/ext2: Fix code indentation ext2: unbugger ext2_empty_dir() udf: remove ->writepage ext2: remove ->writepage ext2: Don't flush page immediately for DIRSYNC directories ext2: Fix some kernel-doc warnings maintainers: Add ISOFS entry udf: Avoid double brelse() in udf_rename() fs: udf: Optimize udf_free_in_core_inode and udf_find_fileset function
2 parents 07d7a4d + 1f3868f commit cda6a60

File tree

10 files changed

+98
-119
lines changed

10 files changed

+98
-119
lines changed

MAINTAINERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10925,6 +10925,13 @@ F: drivers/isdn/Makefile
1092510925
F: drivers/isdn/hardware/
1092610926
F: drivers/isdn/mISDN/
1092710927

10928+
ISOFS FILESYSTEM
10929+
M: Jan Kara <[email protected]>
10930+
10931+
S: Maintained
10932+
F: Documentation/filesystems/isofs.rst
10933+
F: fs/isofs/
10934+
1092810935
IT87 HARDWARE MONITORING DRIVER
1092910936
M: Jean Delvare <[email protected]>
1093010937

fs/ext2/balloc.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ ext2_try_to_allocate(struct super_block *sb, int group,
667667
{
668668
ext2_fsblk_t group_first_block = ext2_group_first_block_no(sb, group);
669669
ext2_fsblk_t group_last_block = ext2_group_last_block_no(sb, group);
670-
ext2_grpblk_t start, end;
670+
ext2_grpblk_t start, end;
671671
unsigned long num = 0;
672672

673673
start = 0;
@@ -1481,11 +1481,11 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
14811481
desc_count, bitmap_count);
14821482
return bitmap_count;
14831483
#else
1484-
for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
1485-
desc = ext2_get_group_desc (sb, i, NULL);
1486-
if (!desc)
1487-
continue;
1488-
desc_count += le16_to_cpu(desc->bg_free_blocks_count);
1484+
for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
1485+
desc = ext2_get_group_desc(sb, i, NULL);
1486+
if (!desc)
1487+
continue;
1488+
desc_count += le16_to_cpu(desc->bg_free_blocks_count);
14891489
}
14901490
return desc_count;
14911491
#endif

fs/ext2/dir.c

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,10 @@ ext2_last_byte(struct inode *inode, unsigned long page_nr)
8181
return last_byte;
8282
}
8383

84-
static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
84+
static void ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
8585
{
8686
struct address_space *mapping = page->mapping;
8787
struct inode *dir = mapping->host;
88-
int err = 0;
8988

9089
inode_inc_iversion(dir);
9190
block_write_end(NULL, mapping, pos, len, len, page, NULL);
@@ -94,16 +93,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
9493
i_size_write(dir, pos+len);
9594
mark_inode_dirty(dir);
9695
}
97-
98-
if (IS_DIRSYNC(dir)) {
99-
err = write_one_page(page);
100-
if (!err)
101-
err = sync_inode_metadata(dir, 1);
102-
} else {
103-
unlock_page(page);
104-
}
105-
106-
return err;
96+
unlock_page(page);
10797
}
10898

10999
static bool ext2_check_page(struct page *page, int quiet, char *kaddr)
@@ -413,7 +403,7 @@ struct ext2_dir_entry_2 *ext2_find_entry (struct inode *dir,
413403
return de;
414404
}
415405

416-
/**
406+
/*
417407
* Return the '..' directory entry and the page in which the entry was found
418408
* (as a parameter - p).
419409
*
@@ -460,6 +450,17 @@ static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len)
460450
return __block_write_begin(page, pos, len, ext2_get_block);
461451
}
462452

453+
454+
static int ext2_handle_dirsync(struct inode *dir)
455+
{
456+
int err;
457+
458+
err = filemap_write_and_wait(dir->i_mapping);
459+
if (!err)
460+
err = sync_inode_metadata(dir, 1);
461+
return err;
462+
}
463+
463464
void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
464465
struct page *page, void *page_addr, struct inode *inode,
465466
int update_times)
@@ -474,11 +475,12 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
474475
BUG_ON(err);
475476
de->inode = cpu_to_le32(inode->i_ino);
476477
ext2_set_de_type(de, inode);
477-
err = ext2_commit_chunk(page, pos, len);
478+
ext2_commit_chunk(page, pos, len);
478479
if (update_times)
479480
dir->i_mtime = dir->i_ctime = current_time(dir);
480481
EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
481482
mark_inode_dirty(dir);
483+
ext2_handle_dirsync(dir);
482484
}
483485

484486
/*
@@ -566,10 +568,11 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
566568
memcpy(de->name, name, namelen);
567569
de->inode = cpu_to_le32(inode->i_ino);
568570
ext2_set_de_type (de, inode);
569-
err = ext2_commit_chunk(page, pos, rec_len);
571+
ext2_commit_chunk(page, pos, rec_len);
570572
dir->i_mtime = dir->i_ctime = current_time(dir);
571573
EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
572574
mark_inode_dirty(dir);
575+
err = ext2_handle_dirsync(dir);
573576
/* OFFSET_CACHE */
574577
out_put:
575578
ext2_put_page(page, page_addr);
@@ -615,10 +618,11 @@ int ext2_delete_entry (struct ext2_dir_entry_2 *dir, struct page *page,
615618
if (pde)
616619
pde->rec_len = ext2_rec_len_to_disk(to - from);
617620
dir->inode = 0;
618-
err = ext2_commit_chunk(page, pos, to - from);
621+
ext2_commit_chunk(page, pos, to - from);
619622
inode->i_ctime = inode->i_mtime = current_time(inode);
620623
EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
621624
mark_inode_dirty(inode);
625+
err = ext2_handle_dirsync(inode);
622626
out:
623627
return err;
624628
}
@@ -658,7 +662,8 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
658662
memcpy (de->name, "..\0", 4);
659663
ext2_set_de_type (de, inode);
660664
kunmap_atomic(kaddr);
661-
err = ext2_commit_chunk(page, 0, chunk_size);
665+
ext2_commit_chunk(page, 0, chunk_size);
666+
err = ext2_handle_dirsync(inode);
662667
fail:
663668
put_page(page);
664669
return err;
@@ -679,7 +684,7 @@ int ext2_empty_dir (struct inode * inode)
679684
page = ext2_get_page(inode, i, 0, &page_addr);
680685

681686
if (IS_ERR(page))
682-
goto not_empty;
687+
return 0;
683688

684689
kaddr = page_addr;
685690
de = (ext2_dirent *)kaddr;

fs/ext2/inode.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -869,11 +869,6 @@ int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
869869
return ret;
870870
}
871871

872-
static int ext2_writepage(struct page *page, struct writeback_control *wbc)
873-
{
874-
return block_write_full_page(page, ext2_get_block, wbc);
875-
}
876-
877872
static int ext2_read_folio(struct file *file, struct folio *folio)
878873
{
879874
return mpage_read_folio(folio, ext2_get_block);
@@ -948,7 +943,6 @@ const struct address_space_operations ext2_aops = {
948943
.invalidate_folio = block_invalidate_folio,
949944
.read_folio = ext2_read_folio,
950945
.readahead = ext2_readahead,
951-
.writepage = ext2_writepage,
952946
.write_begin = ext2_write_begin,
953947
.write_end = ext2_write_end,
954948
.bmap = ext2_bmap,

fs/ext2/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1648,7 +1648,7 @@ static int __init init_ext2_fs(void)
16481648
err = init_inodecache();
16491649
if (err)
16501650
return err;
1651-
err = register_filesystem(&ext2_fs_type);
1651+
err = register_filesystem(&ext2_fs_type);
16521652
if (err)
16531653
goto out;
16541654
return 0;

fs/udf/inode.c

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,6 @@ static void udf_write_failed(struct address_space *mapping, loff_t to)
182182
}
183183
}
184184

185-
static int udf_writepage(struct page *page, struct writeback_control *wbc)
186-
{
187-
return block_write_full_page(page, udf_get_block, wbc);
188-
}
189-
190185
static int udf_writepages(struct address_space *mapping,
191186
struct writeback_control *wbc)
192187
{
@@ -239,12 +234,12 @@ const struct address_space_operations udf_aops = {
239234
.invalidate_folio = block_invalidate_folio,
240235
.read_folio = udf_read_folio,
241236
.readahead = udf_readahead,
242-
.writepage = udf_writepage,
243237
.writepages = udf_writepages,
244238
.write_begin = udf_write_begin,
245239
.write_end = generic_write_end,
246240
.direct_IO = udf_direct_IO,
247241
.bmap = udf_bmap,
242+
.migrate_folio = buffer_migrate_folio,
248243
};
249244

250245
/*
@@ -439,6 +434,12 @@ static int udf_get_block(struct inode *inode, sector_t block,
439434
iinfo->i_next_alloc_goal++;
440435
}
441436

437+
/*
438+
* Block beyond EOF and prealloc extents? Just discard preallocation
439+
* as it is not useful and complicates things.
440+
*/
441+
if (((loff_t)block) << inode->i_blkbits > iinfo->i_lenExtents)
442+
udf_discard_prealloc(inode);
442443
udf_clear_extent_cache(inode);
443444
phys = inode_getblk(inode, block, &err, &new);
444445
if (!phys)
@@ -488,8 +489,6 @@ static int udf_do_extend_file(struct inode *inode,
488489
uint32_t add;
489490
int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
490491
struct super_block *sb = inode->i_sb;
491-
struct kernel_lb_addr prealloc_loc = {};
492-
uint32_t prealloc_len = 0;
493492
struct udf_inode_info *iinfo;
494493
int err;
495494

@@ -510,19 +509,6 @@ static int udf_do_extend_file(struct inode *inode,
510509
~(sb->s_blocksize - 1);
511510
}
512511

513-
/* Last extent are just preallocated blocks? */
514-
if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
515-
EXT_NOT_RECORDED_ALLOCATED) {
516-
/* Save the extent so that we can reattach it to the end */
517-
prealloc_loc = last_ext->extLocation;
518-
prealloc_len = last_ext->extLength;
519-
/* Mark the extent as a hole */
520-
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
521-
(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
522-
last_ext->extLocation.logicalBlockNum = 0;
523-
last_ext->extLocation.partitionReferenceNum = 0;
524-
}
525-
526512
/* Can we merge with the previous extent? */
527513
if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
528514
EXT_NOT_RECORDED_NOT_ALLOCATED) {
@@ -550,7 +536,7 @@ static int udf_do_extend_file(struct inode *inode,
550536
* more extents, we may need to enter possible following
551537
* empty indirect extent.
552538
*/
553-
if (new_block_bytes || prealloc_len)
539+
if (new_block_bytes)
554540
udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0);
555541
}
556542

@@ -584,17 +570,6 @@ static int udf_do_extend_file(struct inode *inode,
584570
}
585571

586572
out:
587-
/* Do we have some preallocated blocks saved? */
588-
if (prealloc_len) {
589-
err = udf_add_aext(inode, last_pos, &prealloc_loc,
590-
prealloc_len, 1);
591-
if (err)
592-
return err;
593-
last_ext->extLocation = prealloc_loc;
594-
last_ext->extLength = prealloc_len;
595-
count++;
596-
}
597-
598573
/* last_pos should point to the last written extent... */
599574
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
600575
last_pos->offset -= sizeof(struct short_ad);
@@ -610,13 +585,17 @@ static int udf_do_extend_file(struct inode *inode,
610585
static void udf_do_extend_final_block(struct inode *inode,
611586
struct extent_position *last_pos,
612587
struct kernel_long_ad *last_ext,
613-
uint32_t final_block_len)
588+
uint32_t new_elen)
614589
{
615-
struct super_block *sb = inode->i_sb;
616590
uint32_t added_bytes;
617591

618-
added_bytes = final_block_len -
619-
(last_ext->extLength & (sb->s_blocksize - 1));
592+
/*
593+
* Extent already large enough? It may be already rounded up to block
594+
* size...
595+
*/
596+
if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK))
597+
return;
598+
added_bytes = (last_ext->extLength & UDF_EXTENT_LENGTH_MASK) - new_elen;
620599
last_ext->extLength += added_bytes;
621600
UDF_I(inode)->i_lenExtents += added_bytes;
622601

@@ -633,12 +612,12 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
633612
int8_t etype;
634613
struct super_block *sb = inode->i_sb;
635614
sector_t first_block = newsize >> sb->s_blocksize_bits, offset;
636-
unsigned long partial_final_block;
615+
loff_t new_elen;
637616
int adsize;
638617
struct udf_inode_info *iinfo = UDF_I(inode);
639618
struct kernel_long_ad extent;
640619
int err = 0;
641-
int within_final_block;
620+
bool within_last_ext;
642621

643622
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
644623
adsize = sizeof(struct short_ad);
@@ -647,8 +626,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
647626
else
648627
BUG();
649628

629+
/*
630+
* When creating hole in file, just don't bother with preserving
631+
* preallocation. It likely won't be very useful anyway.
632+
*/
633+
udf_discard_prealloc(inode);
634+
650635
etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
651-
within_final_block = (etype != -1);
636+
within_last_ext = (etype != -1);
637+
/* We don't expect extents past EOF... */
638+
WARN_ON_ONCE(within_last_ext &&
639+
elen > ((loff_t)offset + 1) << inode->i_blkbits);
652640

653641
if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
654642
(epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
@@ -664,19 +652,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
664652
extent.extLength |= etype << 30;
665653
}
666654

667-
partial_final_block = newsize & (sb->s_blocksize - 1);
655+
new_elen = ((loff_t)offset << inode->i_blkbits) |
656+
(newsize & (sb->s_blocksize - 1));
668657

669658
/* File has extent covering the new size (could happen when extending
670659
* inside a block)?
671660
*/
672-
if (within_final_block) {
661+
if (within_last_ext) {
673662
/* Extending file within the last file block */
674-
udf_do_extend_final_block(inode, &epos, &extent,
675-
partial_final_block);
663+
udf_do_extend_final_block(inode, &epos, &extent, new_elen);
676664
} else {
677-
loff_t add = ((loff_t)offset << sb->s_blocksize_bits) |
678-
partial_final_block;
679-
err = udf_do_extend_file(inode, &epos, &extent, add);
665+
err = udf_do_extend_file(inode, &epos, &extent, new_elen);
680666
}
681667

682668
if (err < 0)
@@ -777,10 +763,11 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
777763
goto out_free;
778764
}
779765

780-
/* Are we beyond EOF? */
766+
/* Are we beyond EOF and preallocated extent? */
781767
if (etype == -1) {
782768
int ret;
783769
loff_t hole_len;
770+
784771
isBeyondEOF = true;
785772
if (count) {
786773
if (c)

fs/udf/namei.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,8 +1091,9 @@ static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
10911091
return -EINVAL;
10921092

10931093
ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
1094-
if (IS_ERR(ofi)) {
1095-
retval = PTR_ERR(ofi);
1094+
if (!ofi || IS_ERR(ofi)) {
1095+
if (IS_ERR(ofi))
1096+
retval = PTR_ERR(ofi);
10961097
goto end_rename;
10971098
}
10981099

@@ -1101,8 +1102,7 @@ static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
11011102

11021103
brelse(ofibh.sbh);
11031104
tloc = lelb_to_cpu(ocfi.icb.extLocation);
1104-
if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0)
1105-
!= old_inode->i_ino)
1105+
if (udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) != old_inode->i_ino)
11061106
goto end_rename;
11071107

11081108
nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi);

0 commit comments

Comments
 (0)