From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E172AC432C0 for ; Mon, 2 Dec 2019 09:41:28 +0000 (UTC) Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A605320705; Mon, 2 Dec 2019 09:41:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=sourceforge.net header.i=@sourceforge.net header.b="XrNLP+ou"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=sf.net header.i=@sf.net header.b="EirUF3xr"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="pltdDlbx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A605320705 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=linux-f2fs-devel-bounces@lists.sourceforge.net Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1ibiCu-0007JN-2t; Mon, 02 Dec 2019 09:41:28 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ibiCd-0007HZ-72 for linux-f2fs-devel@lists.sourceforge.net; Mon, 02 Dec 2019 09:41:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=A0YrLAWp+7RlgcXWMYO6SZhxG6kcSpYEz42g2S/jpoU=; b=XrNLP+oujjKAFZYw/vS93vkEkL qHZtJkm4A9q1TM+N5WuEtgydbEKd76DfwO68nMIVCKEaMaBy+WRfpntQB1+IekJXcWTsvSavwzf7U PWXikghdc+4/as1gdIlL7kTMEQfEoXCngQ1N7ZxppEQfPcTaXgiVVdGtIp/5lmZc+sIk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=A0YrLAWp+7RlgcXWMYO6SZhxG6kcSpYEz42g2S/jpoU=; b=EirUF3xrYxFt44GULOF0abjGOW zddiU6CqmCsQZvYR0wdlFoTRsEbK5DAkFT162Q/fmA04226/vGQa9XesfaHJ4tb4DoO3Gogg8/Fjv uJ1Pq67A4Zn1V2/GfZY8roXpkOmOAiwZadI3lqSgceT58QF3ztaFB/Nc56nqgRkrI/UM=; Received: from esa2.hgst.iphmx.com ([68.232.143.124]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1ibiCZ-002exm-Au for linux-f2fs-devel@lists.sourceforge.net; Mon, 02 Dec 2019 09:41:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1575279681; x=1606815681; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2VNhsxkjqEEBYvgF3YnGbSR8+67N76vhkmM/0vv9I/U=; b=pltdDlbxGYBKd3/RahHvB2EeLmG+U3fiWEtgsGYcxQkJym2V7GApbF8k 3TIaWaBPH/KGqr1VDLKOpaao46JCbH+tt9WwiNh5t064uD65uVu8kbdcN OX59lCRYkGSrcwUW4oCkafUVSi7oRjUt67mLp/qhIO3k591gbvhkI8raH eFwy9zK0WOJNBb9d+Hiys13kis/MKm8nIt/XUpagCMwoAEFLOVZnwXAA9 5P7fqkz6kf0u2ViDfgri+mN8yFKSQaHGyXXtzYKBxn2Z2MT+MT4AmzwDP MM+zatqGMhH/kkdgz9oCUBXJOaZckDgEctuFAHx1/Tl6KGaPjNkZyZwmW g==; IronPort-SDR: v/+3BE0+mZi3CbLcAYbelU/OnR6zf5Wi0gRks11fcbk2vJmk0ng5kYH/x7OKtAVkXat9SLSsit 8tmoZVh2csJmek3IQ6OEglb3jw0APTiyesITjij1N4VP3yC8sFfQJ05WNXfMcvoRKqq1SPL90t QxG7FiuRXk2+XHBcubROxJXF33tHtEwcctzTQzLqlf0fMBc7nCzRg/nbnL4vQsY+p3RppghvLC FexjSXjWuCfj6U22e6gT8gB1GoFnbAcmEDMMH9HiMH5uZsbRZyVUjARWDcc/h/CBjh17rvu69B Oh4= X-IronPort-AV: E=Sophos;i="5.69,268,1571673600"; d="scan'208";a="225835237" Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 02 Dec 2019 17:41:04 +0800 IronPort-SDR: UfcOBe0o0/LlmLfC7D0s+aLkqPX+3NPkG4yGtLcZuB8RjYX1n4BGVw0q37pFbgV/eR62MKvlnm 6X8az2/+YghYYehC4471ZW2FoV9V1P3Fswqs0w3uEZ1RRUcb1Zobs67VKKTtdtaD49bifJtK1D AroUY++f4LkI5RlWGOYkyLXYDvb+AHcSfSpaLdU+LvuXc+xSi+dgG6FSZfYQGhtIzhcX1Nq1Rs dguKLEvEb1SkUEmmhinZYSVSOaj6FYCgUgF/xiteh71QSf+bL+oEF/XED8iLIoIIEjD4K2KjmJ JdxA10XDPq9rD14RmYmcO3iO Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Dec 2019 01:35:25 -0800 IronPort-SDR: jDquNJKq37JlACbsjSfAt0LY61rKrYCYxGrSGD4lS7jCFcMFYWI/NI9cf5FFgWP5upIgcoSeby WSxwAcesBlfjjzOYFV73ZN9yBeiUNiZMEGDptrznxe1ZQMgHSs5CDRe5gqVwvcYoLtx4rpYvLD TRJiaTZI90Zk4FFTBkRKJlipDapBL4447iLk+iU/9LZyK2+PYSqRhhIKrFJlwEW9nNPHqe/yep r3LNli1phzVygTqsIL0LusyFFx6xd/7HKeDXwRkH2H4mTCrr+SyY7FrbaNwmTulXgnXEwsDItm S1U= WDCIronportException: Internal Received: from shindev.dhcp.fujisawa.hgst.com (HELO shindev.fujisawa.hgst.com) ([10.149.53.87]) by uls-op-cesaip01.wdc.com with ESMTP; 02 Dec 2019 01:40:55 -0800 From: Shin'ichiro Kawasaki To: Jaegeuk Kim , Chao Yu , linux-f2fs-devel@lists.sourceforge.net Date: Mon, 2 Dec 2019 18:40:43 +0900 Message-Id: <20191202094043.892258-3-shinichiro.kawasaki@wdc.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191202094043.892258-1-shinichiro.kawasaki@wdc.com> References: <20191202094043.892258-1-shinichiro.kawasaki@wdc.com> MIME-Version: 1.0 X-Headers-End: 1ibiCZ-002exm-Au Subject: [f2fs-dev] [PATCH v4 2/2] f2fs: Check write pointer consistency of non-open zones X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Damien Le Moal Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net To catch f2fs bugs in write pointer handling code for zoned block devices, check write pointers of non-open zones that current segments do not point to. Do this check at mount time, after the fsync data recovery and current segments' write pointer consistency fix. Or when fsync data recovery is disabled by mount option, do the check when there is no fsync data. Check two items comparing write pointers with valid block maps in SIT. The first item is check for zones with no valid blocks. When there is no valid blocks in a zone, the write pointer should be at the start of the zone. If not, next write operation to the zone will cause unaligned write error. If write pointer is not at the zone start, reset the write pointer to place at the zone start. The second item is check between the write pointer position and the last valid block in the zone. It is unexpected that the last valid block position is beyond the write pointer. In such a case, report as a bug. Fix is not required for such zone, because the zone is not selected for next write operation until the zone get discarded. Signed-off-by: Shin'ichiro Kawasaki --- fs/f2fs/f2fs.h | 1 + fs/f2fs/segment.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++ fs/f2fs/super.c | 11 ++++ 3 files changed, 138 insertions(+) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 002c417b0a53..23a84d7f17b8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3156,6 +3156,7 @@ int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type, unsigned int val, int alloc); void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc); int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi); +int f2fs_check_write_pointer(struct f2fs_sb_info *sbi); int f2fs_build_segment_manager(struct f2fs_sb_info *sbi); void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi); int __init f2fs_create_segment_manager_caches(void); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 9b6c7ab67b93..48903b7a9d25 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4370,6 +4370,90 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi) #ifdef CONFIG_BLK_DEV_ZONED +static int check_zone_write_pointer(struct f2fs_sb_info *sbi, + struct f2fs_dev_info *fdev, + struct blk_zone *zone) +{ + unsigned int wp_segno, wp_blkoff, zone_secno, zone_segno, segno; + block_t zone_block, wp_block, last_valid_block; + unsigned int log_sectors_per_block = sbi->log_blocksize - SECTOR_SHIFT; + int i, s, b, ret; + struct seg_entry *se; + + if (zone->type != BLK_ZONE_TYPE_SEQWRITE_REQ) + return 0; + + wp_block = fdev->start_blk + (zone->wp >> log_sectors_per_block); + wp_segno = GET_SEGNO(sbi, wp_block); + wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno); + zone_block = fdev->start_blk + (zone->start >> log_sectors_per_block); + zone_segno = GET_SEGNO(sbi, zone_block); + zone_secno = GET_SEC_FROM_SEG(sbi, zone_segno); + + if (zone_segno >= MAIN_SEGS(sbi)) + return 0; + + /* + * Skip check of zones cursegs point to, since + * fix_curseg_write_pointer() checks them. + */ + for (i = 0; i < NO_CHECK_TYPE; i++) + if (zone_secno == GET_SEC_FROM_SEG(sbi, + CURSEG_I(sbi, i)->segno)) + return 0; + + /* + * Get last valid block of the zone. + */ + last_valid_block = zone_block - 1; + for (s = sbi->segs_per_sec - 1; s >= 0; s--) { + segno = zone_segno + s; + se = get_seg_entry(sbi, segno); + for (b = sbi->blocks_per_seg - 1; b >= 0; b--) + if (f2fs_test_bit(b, se->cur_valid_map)) { + last_valid_block = START_BLOCK(sbi, segno) + b; + break; + } + if (last_valid_block >= zone_block) + break; + } + + /* + * If last valid block is beyond the write pointer, report the + * inconsistency. This inconsistency does not cause write error + * because the zone will not be selected for write operation until + * it get discarded. Just report it. + */ + if (last_valid_block >= wp_block) { + f2fs_notice(sbi, "Valid block beyond write pointer: " + "valid block[0x%x,0x%x] wp[0x%x,0x%x]", + GET_SEGNO(sbi, last_valid_block), + GET_BLKOFF_FROM_SEG0(sbi, last_valid_block), + wp_segno, wp_blkoff); + return 0; + } + + /* + * If there is no valid block in the zone and if write pointer is + * not at zone start, reset the write pointer. + */ + if (last_valid_block + 1 == zone_block && zone->wp != zone->start) { + f2fs_notice(sbi, + "Zone without valid block has non-zero write " + "pointer. Reset the write pointer: wp[0x%x,0x%x]", + wp_segno, wp_blkoff); + ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_RESET, + zone->start, zone->len, GFP_NOFS); + if (ret) { + f2fs_notice(sbi, "Reset zone failed: %s (errno=%d)", + fdev->path, ret); + return ret; + } + } + + return 0; +} + static struct f2fs_dev_info *get_target_zoned_dev(struct f2fs_sb_info *sbi, block_t zone_blkaddr) { @@ -4442,6 +4526,10 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type) "curseg[0x%x,0x%x]", type, cs->segno, cs->next_blkoff); allocate_segment_by_default(sbi, type, true); + /* check consistency of the zone curseg pointed to */ + if (check_zone_write_pointer(sbi, zbd, &zone)) + return -EIO; + /* check newly assigned zone */ cs_section = GET_SEC_FROM_SEG(sbi, cs->segno); cs_zone_block = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, cs_section)); @@ -4492,11 +4580,49 @@ int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi) return 0; } + +struct check_zone_write_pointer_args { + struct f2fs_sb_info *sbi; + struct f2fs_dev_info *fdev; +}; + +static int check_zone_write_pointer_cb(struct blk_zone *zone, unsigned int idx, + void *data) { + struct check_zone_write_pointer_args *args; + args = (struct check_zone_write_pointer_args *)data; + + return check_zone_write_pointer(args->sbi, args->fdev, zone); +} + +int f2fs_check_write_pointer(struct f2fs_sb_info *sbi) +{ + int i, ret; + struct check_zone_write_pointer_args args; + + for (i = 0; i < sbi->s_ndevs; i++) { + if (!bdev_is_zoned(FDEV(i).bdev)) + continue; + + args.sbi = sbi; + args.fdev = &FDEV(i); + ret = blkdev_report_zones(FDEV(i).bdev, 0, BLK_ALL_ZONES, + check_zone_write_pointer_cb, &args); + if (ret < 0) + return ret; + } + + return 0; +} #else int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi) { return 0; } + +int f2fs_check_write_pointer(struct f2fs_sb_info *sbi) +{ + return 0; +} #endif /* diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 5111e1ffe58a..755ad57c795b 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3544,6 +3544,17 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_meta; } } + + /* + * If the f2fs is not readonly and fsync data recovery succeeds, + * check zoned block devices' write pointer consistency. + */ + if (!err && !f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) { + err = f2fs_check_write_pointer(sbi); + if (err) + goto free_meta; + } + reset_checkpoint: /* f2fs_recover_fsync_data() cleared this already */ clear_sbi_flag(sbi, SBI_POR_DOING); -- 2.23.0 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel