summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/super.c
diff options
context:
space:
mode:
authorDamien Le Moal <damien.lemoal@wdc.com>2016-10-28 04:45:05 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2016-11-23 15:11:22 -0500
commit178053e2f1f9ccdb61ff6c2bd8644b53fc98e72e (patch)
tree55cd63cf12864ca6da6f47d68fd26c1b42c2d6a4 /fs/f2fs/super.c
parent3adc57e97792e4ac9f228bde802829e2e9840afe (diff)
f2fs: Cache zoned block devices zone type
With the zoned block device feature enabled, section discard need to do a zone reset for sections contained in sequential zones, and a regular discard (if supported) for sections stored in conventional zones. Avoid the need for a costly report zones to obtain a section zone type when discarding it by caching the types of the device zones in the super block information. This cache is initialized at mount time for mounts with the zoned block device feature enabled. Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/super.c')
-rw-r--r--fs/f2fs/super.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 3312284aa245..12a4f3f44a2f 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1511,6 +1511,65 @@ static int init_percpu_info(struct f2fs_sb_info *sbi)
1511 GFP_KERNEL); 1511 GFP_KERNEL);
1512} 1512}
1513 1513
1514#ifdef CONFIG_BLK_DEV_ZONED
1515static int init_blkz_info(struct f2fs_sb_info *sbi)
1516{
1517 struct block_device *bdev = sbi->sb->s_bdev;
1518 sector_t nr_sectors = bdev->bd_part->nr_sects;
1519 sector_t sector = 0;
1520 struct blk_zone *zones;
1521 unsigned int i, nr_zones;
1522 unsigned int n = 0;
1523 int err = -EIO;
1524
1525 if (!f2fs_sb_mounted_blkzoned(sbi->sb))
1526 return 0;
1527
1528 sbi->blocks_per_blkz = SECTOR_TO_BLOCK(bdev_zone_size(bdev));
1529 sbi->log_blocks_per_blkz = __ilog2_u32(sbi->blocks_per_blkz);
1530 sbi->nr_blkz = SECTOR_TO_BLOCK(nr_sectors) >>
1531 sbi->log_blocks_per_blkz;
1532 if (nr_sectors & (bdev_zone_size(bdev) - 1))
1533 sbi->nr_blkz++;
1534
1535 sbi->blkz_type = kmalloc(sbi->nr_blkz, GFP_KERNEL);
1536 if (!sbi->blkz_type)
1537 return -ENOMEM;
1538
1539#define F2FS_REPORT_NR_ZONES 4096
1540
1541 zones = kcalloc(F2FS_REPORT_NR_ZONES, sizeof(struct blk_zone),
1542 GFP_KERNEL);
1543 if (!zones)
1544 return -ENOMEM;
1545
1546 /* Get block zones type */
1547 while (zones && sector < nr_sectors) {
1548
1549 nr_zones = F2FS_REPORT_NR_ZONES;
1550 err = blkdev_report_zones(bdev, sector,
1551 zones, &nr_zones,
1552 GFP_KERNEL);
1553 if (err)
1554 break;
1555 if (!nr_zones) {
1556 err = -EIO;
1557 break;
1558 }
1559
1560 for (i = 0; i < nr_zones; i++) {
1561 sbi->blkz_type[n] = zones[i].type;
1562 sector += zones[i].len;
1563 n++;
1564 }
1565 }
1566
1567 kfree(zones);
1568
1569 return err;
1570}
1571#endif
1572
1514/* 1573/*
1515 * Read f2fs raw super block. 1574 * Read f2fs raw super block.
1516 * Because we have two copies of super block, so read both of them 1575 * Because we have two copies of super block, so read both of them
@@ -1757,6 +1816,15 @@ try_onemore:
1757 1816
1758 init_ino_entry_info(sbi); 1817 init_ino_entry_info(sbi);
1759 1818
1819#ifdef CONFIG_BLK_DEV_ZONED
1820 err = init_blkz_info(sbi);
1821 if (err) {
1822 f2fs_msg(sb, KERN_ERR,
1823 "Failed to initialize F2FS blkzone information");
1824 goto free_blkz;
1825 }
1826#endif
1827
1760 /* setup f2fs internal modules */ 1828 /* setup f2fs internal modules */
1761 err = build_segment_manager(sbi); 1829 err = build_segment_manager(sbi);
1762 if (err) { 1830 if (err) {
@@ -1935,6 +2003,10 @@ free_nm:
1935 destroy_node_manager(sbi); 2003 destroy_node_manager(sbi);
1936free_sm: 2004free_sm:
1937 destroy_segment_manager(sbi); 2005 destroy_segment_manager(sbi);
2006#ifdef CONFIG_BLK_DEV_ZONED
2007free_blkz:
2008 kfree(sbi->blkz_type);
2009#endif
1938 kfree(sbi->ckpt); 2010 kfree(sbi->ckpt);
1939free_meta_inode: 2011free_meta_inode:
1940 make_bad_inode(sbi->meta_inode); 2012 make_bad_inode(sbi->meta_inode);