f2fs: fix kbytes written stat for multi-device case
authorChao Yu <yuchao0@huawei.com>
Fri, 27 Nov 2020 13:20:06 +0000 (21:20 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Thu, 3 Dec 2020 06:00:22 +0000 (22:00 -0800)
For multi-device case, one f2fs image includes multi devices, so it
needs to account bytes written of all block devices belong to the image
rather than one main block device, fix it.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/f2fs.h
fs/f2fs/super.c
fs/f2fs/sysfs.c

index e5d2ffa80b566f58d40f2cbc89b1f0e144cbb7a1..14ba1519639e6c607ba056ea54184282677d1b2b 100644 (file)
@@ -1385,6 +1385,27 @@ static void commit_checkpoint(struct f2fs_sb_info *sbi,
        f2fs_submit_merged_write(sbi, META_FLUSH);
 }
 
+static inline u64 get_sectors_written(struct block_device *bdev)
+{
+       return bdev->bd_part ?
+               (u64)part_stat_read(bdev->bd_part, sectors[STAT_WRITE]) : 0;
+}
+
+u64 f2fs_get_sectors_written(struct f2fs_sb_info *sbi)
+{
+       if (f2fs_is_multi_device(sbi)) {
+               u64 sectors = 0;
+               int i;
+
+               for (i = 0; i < sbi->s_ndevs; i++)
+                       sectors += get_sectors_written(FDEV(i).bdev);
+
+               return sectors;
+       }
+
+       return get_sectors_written(sbi->sb->s_bdev);
+}
+
 static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 {
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
@@ -1395,7 +1416,6 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
        __u32 crc32 = 0;
        int i;
        int cp_payload_blks = __cp_payload(sbi);
-       struct super_block *sb = sbi->sb;
        struct curseg_info *seg_i = CURSEG_I(sbi, CURSEG_HOT_NODE);
        u64 kbytes_written;
        int err;
@@ -1490,9 +1510,8 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 
        /* Record write statistics in the hot node summary */
        kbytes_written = sbi->kbytes_written;
-       if (sb->s_bdev->bd_part)
-               kbytes_written += BD_PART_WRITTEN(sbi);
-
+       kbytes_written += (f2fs_get_sectors_written(sbi) -
+                               sbi->sectors_written_start) >> 1;
        seg_i->journal->info.kbytes_written = cpu_to_le64(kbytes_written);
 
        if (__remain_node_summaries(cpc->reason)) {
index 0b314b2034d8644ab269c9591771e65d0b724671..90e1fe0ce4bbb47ed25ae01ab537de915465a627 100644 (file)
@@ -1603,13 +1603,6 @@ static inline bool f2fs_is_multi_device(struct f2fs_sb_info *sbi)
        return sbi->s_ndevs > 1;
 }
 
-/* For write statistics. Suppose sector size is 512 bytes,
- * and the return value is in kbytes. s is of struct f2fs_sb_info.
- */
-#define BD_PART_WRITTEN(s)                                              \
-(((u64)part_stat_read((s)->sb->s_bdev->bd_part, sectors[STAT_WRITE]) -   \
-               (s)->sectors_written_start) >> 1)
-
 static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type)
 {
        unsigned long now = jiffies;
@@ -3382,6 +3375,7 @@ void f2fs_update_dirty_page(struct inode *inode, struct page *page);
 void f2fs_remove_dirty_inode(struct inode *inode);
 int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type);
 void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type);
+u64 f2fs_get_sectors_written(struct f2fs_sb_info *sbi);
 int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc);
 void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi);
 int __init f2fs_create_checkpoint_caches(void);
index f3d919ee4dee68a4678c80a59ae4ecefd4c1540d..0ac4dbd6488a764b1c2ab6b56357b8c0a21c828b 100644 (file)
@@ -3701,10 +3701,7 @@ try_onemore:
        }
 
        /* For write statistics */
-       if (sb->s_bdev->bd_part)
-               sbi->sectors_written_start =
-                       (u64)part_stat_read(sb->s_bdev->bd_part,
-                                           sectors[STAT_WRITE]);
+       sbi->sectors_written_start = f2fs_get_sectors_written(sbi);
 
        /* Read accumulated write IO statistics if exists */
        seg_i = CURSEG_I(sbi, CURSEG_HOT_NODE);
index ec77ccfea923dc52bdb11eb9c25a209fd78ff460..fce2997382aff715a12cfb371469c02379feaac5 100644 (file)
@@ -97,7 +97,8 @@ static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a,
 
        return sprintf(buf, "%llu\n",
                        (unsigned long long)(sbi->kbytes_written +
-                       BD_PART_WRITTEN(sbi)));
+                       ((f2fs_get_sectors_written(sbi) -
+                               sbi->sectors_written_start) >> 1)));
 }
 
 static ssize_t features_show(struct f2fs_attr *a,