Message ID | HK2PR04MB38915D9ABDC81F7D5463C4E4811A9@HK2PR04MB3891.apcprd04.prod.outlook.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | exfat: reduce block requests when zeroing a cluster | expand |
On Fri, Mar 25, 2022 at 03:00:55AM +0000, Yuezhang.Mo@sony.com wrote:
> +#include <linux/blk_types.h>
blk_types.h is not a header for public use. What do you want it for?
Hi Christoph Hellwig, Thank you for your comment. > On Fri, Mar 25, 2022 at 03:00:55AM +0000, Yuezhang.Mo@sony.com wrote: > > +#include <linux/blk_types.h> > > blk_types.h is not a header for public use. What do you want it for? + struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; The type of 'sb->s_bdev' is 'struct block_device'. I want to include the definition of 'struct block_device'('struct block_device' is defined in <linux/blk_types.h>). Should I change to include <linux/blkdev.h>? Best Regards, Yuezhang Mo
On Fri, Mar 25, 2022 at 07:22:54AM +0000, Yuezhang.Mo@sony.com wrote: > Hi Christoph Hellwig, > > Thank you for your comment. > > > On Fri, Mar 25, 2022 at 03:00:55AM +0000, Yuezhang.Mo@sony.com wrote: > > > +#include <linux/blk_types.h> > > > > blk_types.h is not a header for public use. What do you want it for? > > + struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; > > The type of 'sb->s_bdev' is 'struct block_device'. > I want to include the definition of 'struct block_device'('struct block_device' is defined in <linux/blk_types.h>). Oh, I missed that. We really should not derefrence bd_inode in file systems. So maybe we need to add a sync_blockdev_range abstraction if we want to support this use case.
diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c index c3c9afee7418..b7de3d0758f4 100644 --- a/fs/exfat/fatent.c +++ b/fs/exfat/fatent.c @@ -6,6 +6,7 @@ #include <linux/slab.h> #include <asm/unaligned.h> #include <linux/buffer_head.h> +#include <linux/blk_types.h> #include "exfat_raw.h" #include "exfat_fs.h" @@ -233,10 +234,10 @@ int exfat_zeroed_cluster(struct inode *dir, unsigned int clu) { struct super_block *sb = dir->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct buffer_head *bhs[MAX_BUF_PER_PAGE]; - int nr_bhs = MAX_BUF_PER_PAGE; + struct buffer_head *bh; + struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; sector_t blknr, last_blknr; - int err, i, n; + int i; blknr = exfat_cluster_to_sector(sbi, clu); last_blknr = blknr + sbi->sect_per_clus; @@ -250,30 +251,23 @@ int exfat_zeroed_cluster(struct inode *dir, unsigned int clu) } /* Zeroing the unused blocks on this cluster */ - while (blknr < last_blknr) { - for (n = 0; n < nr_bhs && blknr < last_blknr; n++, blknr++) { - bhs[n] = sb_getblk(sb, blknr); - if (!bhs[n]) { - err = -ENOMEM; - goto release_bhs; - } - memset(bhs[n]->b_data, 0, sb->s_blocksize); - } - - err = exfat_update_bhs(bhs, n, IS_DIRSYNC(dir)); - if (err) - goto release_bhs; + for (i = blknr; i < last_blknr; i++) { + bh = sb_getblk(sb, i); + if (!bh) + return -ENOMEM; - for (i = 0; i < n; i++) - brelse(bhs[i]); + memset(bh->b_data, 0, sb->s_blocksize); + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + brelse(bh); } - return 0; -release_bhs: - exfat_err(sb, "failed zeroed sect %llu\n", (unsigned long long)blknr); - for (i = 0; i < n; i++) - bforget(bhs[i]); - return err; + if (IS_DIRSYNC(dir)) + return filemap_write_and_wait_range(mapping, + EXFAT_BLK_TO_B(blknr, sb), + EXFAT_BLK_TO_B(last_blknr, sb) - 1); + + return 0; } int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,