Skip to content

Commit 231eb76

Browse files
YuezhangMonamjaejeon
authored andcommitted
exfat: do not fallback to buffered write
After commit(11a347f exfat: change to get file size from DataLength), the remaining area or hole had been filled with zeros before calling exfat_direct_IO(), so there is no need to fallback to buffered write, and ->i_size_aligned is no longer needed, drop it. Signed-off-by: Yuezhang Mo <[email protected]> Signed-off-by: Namjae Jeon <[email protected]>
1 parent fba27cf commit 231eb76

File tree

5 files changed

+15
-74
lines changed

5 files changed

+15
-74
lines changed

fs/exfat/exfat_fs.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,6 @@ struct exfat_inode_info {
309309
/* for avoiding the race between alloc and free */
310310
unsigned int cache_valid_id;
311311

312-
/* block-aligned i_size (used in cont_write_begin) */
313-
loff_t i_size_aligned;
314312
/* on-disk position of directory entry or 0 */
315313
loff_t i_pos;
316314
loff_t valid_size;

fs/exfat/file.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ static int exfat_cont_expand(struct inode *inode, loff_t size)
7474
/* Expanded range not zeroed, do not update valid_size */
7575
i_size_write(inode, size);
7676

77-
ei->i_size_aligned = round_up(size, sb->s_blocksize);
7877
inode->i_blocks = round_up(size, sbi->cluster_size) >> 9;
7978
mark_inode_dirty(inode);
8079

@@ -244,8 +243,6 @@ void exfat_truncate(struct inode *inode)
244243
struct super_block *sb = inode->i_sb;
245244
struct exfat_sb_info *sbi = EXFAT_SB(sb);
246245
struct exfat_inode_info *ei = EXFAT_I(inode);
247-
unsigned int blocksize = i_blocksize(inode);
248-
loff_t aligned_size;
249246
int err;
250247

251248
mutex_lock(&sbi->s_lock);
@@ -263,14 +260,6 @@ void exfat_truncate(struct inode *inode)
263260

264261
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
265262
write_size:
266-
aligned_size = i_size_read(inode);
267-
if (aligned_size & (blocksize - 1)) {
268-
aligned_size |= (blocksize - 1);
269-
aligned_size++;
270-
}
271-
272-
if (ei->i_size_aligned > i_size_read(inode))
273-
ei->i_size_aligned = aligned_size;
274263
mutex_unlock(&sbi->s_lock);
275264
}
276265

fs/exfat/inode.c

Lines changed: 15 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -258,21 +258,6 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
258258
return 0;
259259
}
260260

261-
static int exfat_map_new_buffer(struct exfat_inode_info *ei,
262-
struct buffer_head *bh, loff_t pos)
263-
{
264-
if (buffer_delay(bh) && pos > ei->i_size_aligned)
265-
return -EIO;
266-
set_buffer_new(bh);
267-
268-
/*
269-
* Adjust i_size_aligned if ondisk_size is bigger than it.
270-
*/
271-
if (exfat_ondisk_size(&ei->vfs_inode) > ei->i_size_aligned)
272-
ei->i_size_aligned = exfat_ondisk_size(&ei->vfs_inode);
273-
return 0;
274-
}
275-
276261
static int exfat_get_block(struct inode *inode, sector_t iblock,
277262
struct buffer_head *bh_result, int create)
278263
{
@@ -286,7 +271,6 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
286271
sector_t last_block;
287272
sector_t phys = 0;
288273
sector_t valid_blks;
289-
loff_t pos;
290274

291275
mutex_lock(&sbi->s_lock);
292276
last_block = EXFAT_B_TO_BLK_ROUND_UP(i_size_read(inode), sb);
@@ -314,8 +298,6 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
314298
mapped_blocks = sbi->sect_per_clus - sec_offset;
315299
max_blocks = min(mapped_blocks, max_blocks);
316300

317-
pos = EXFAT_BLK_TO_B((iblock + 1), sb);
318-
319301
map_bh(bh_result, sb, phys);
320302
if (buffer_delay(bh_result))
321303
clear_buffer_delay(bh_result);
@@ -336,13 +318,7 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
336318
}
337319

338320
/* The area has not been written, map and mark as new. */
339-
err = exfat_map_new_buffer(ei, bh_result, pos);
340-
if (err) {
341-
exfat_fs_error(sb,
342-
"requested for bmap out of range(pos : (%llu) > i_size_aligned(%llu)\n",
343-
pos, ei->i_size_aligned);
344-
goto unlock_ret;
345-
}
321+
set_buffer_new(bh_result);
346322

347323
ei->valid_size = EXFAT_BLK_TO_B(iblock + max_blocks, sb);
348324
mark_inode_dirty(inode);
@@ -365,7 +341,7 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
365341
* The block has been partially written,
366342
* zero the unwritten part and map the block.
367343
*/
368-
loff_t size, off;
344+
loff_t size, off, pos;
369345

370346
max_blocks = 1;
371347

@@ -376,7 +352,7 @@ static int exfat_get_block(struct inode *inode, sector_t iblock,
376352
if (!bh_result->b_folio)
377353
goto done;
378354

379-
pos -= sb->s_blocksize;
355+
pos = EXFAT_BLK_TO_B(iblock, sb);
380356
size = ei->valid_size - pos;
381357
off = pos & (PAGE_SIZE - 1);
382358

@@ -463,14 +439,6 @@ static int exfat_write_end(struct file *file, struct address_space *mapping,
463439
int err;
464440

465441
err = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
466-
467-
if (ei->i_size_aligned < i_size_read(inode)) {
468-
exfat_fs_error(inode->i_sb,
469-
"invalid size(size(%llu) > aligned(%llu)\n",
470-
i_size_read(inode), ei->i_size_aligned);
471-
return -EIO;
472-
}
473-
474442
if (err < len)
475443
exfat_write_failed(mapping, pos+len);
476444

@@ -498,20 +466,6 @@ static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
498466
int rw = iov_iter_rw(iter);
499467
ssize_t ret;
500468

501-
if (rw == WRITE) {
502-
/*
503-
* FIXME: blockdev_direct_IO() doesn't use ->write_begin(),
504-
* so we need to update the ->i_size_aligned to block boundary.
505-
*
506-
* But we must fill the remaining area or hole by nul for
507-
* updating ->i_size_aligned
508-
*
509-
* Return 0, and fallback to normal buffered write.
510-
*/
511-
if (EXFAT_I(inode)->i_size_aligned < size)
512-
return 0;
513-
}
514-
515469
/*
516470
* Need to use the DIO_LOCKING for avoiding the race
517471
* condition of exfat_get_block() and ->truncate().
@@ -525,8 +479,18 @@ static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
525479
} else
526480
size = pos + ret;
527481

528-
/* zero the unwritten part in the partially written block */
529-
if (rw == READ && pos < ei->valid_size && ei->valid_size < size) {
482+
if (rw == WRITE) {
483+
/*
484+
* If the block had been partially written before this write,
485+
* ->valid_size will not be updated in exfat_get_block(),
486+
* update it here.
487+
*/
488+
if (ei->valid_size < size) {
489+
ei->valid_size = size;
490+
mark_inode_dirty(inode);
491+
}
492+
} else if (pos < ei->valid_size && ei->valid_size < size) {
493+
/* zero the unwritten part in the partially written block */
530494
iov_iter_revert(iter, size - ei->valid_size);
531495
iov_iter_zero(size - ei->valid_size, iter);
532496
}
@@ -661,14 +625,6 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info)
661625

662626
i_size_write(inode, size);
663627

664-
/* ondisk and aligned size should be aligned with block size */
665-
if (size & (inode->i_sb->s_blocksize - 1)) {
666-
size |= (inode->i_sb->s_blocksize - 1);
667-
size++;
668-
}
669-
670-
ei->i_size_aligned = size;
671-
672628
exfat_save_attr(inode, info->attr);
673629

674630
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;

fs/exfat/namei.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,6 @@ static int exfat_find_empty_entry(struct inode *inode,
372372

373373
/* directory inode should be updated in here */
374374
i_size_write(inode, size);
375-
ei->i_size_aligned += sbi->cluster_size;
376375
ei->valid_size += sbi->cluster_size;
377376
ei->flags = p_dir->flags;
378377
inode->i_blocks += sbi->cluster_size >> 9;

fs/exfat/super.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,6 @@ static int exfat_read_root(struct inode *inode)
370370

371371
inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
372372
ei->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff;
373-
ei->i_size_aligned = i_size_read(inode);
374373

375374
exfat_save_attr(inode, EXFAT_ATTR_SUBDIR);
376375
ei->i_crtime = simple_inode_init_ts(inode);

0 commit comments

Comments
 (0)