From: Sergey Cheremencev Date: Fri, 26 Sep 2014 13:00:56 +0000 (+0400) Subject: LU-5729 osd: iput in case of error in osd_scrub_setup X-Git-Tag: 2.6.91~68 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=b474a0320e83daeffa44eccf724a19641d3f6566 LU-5729 osd: iput in case of error in osd_scrub_setup In case of ENOSPACE from osd_scrub_file_store iput is needed. Otherwise there is a message in dmesg: "VFS: Busy inodes after unmount of vdb. Self-destruct in 5 seconds. Have a nice day..." Also added osd_oi_fini for case of error from osd_initial_OI_scrub or osd_scrub_start. Change-Id: Ibc6f487c9bd5b07f09cb3f7e3b5fc2bf1e329fb0 Signed-off-by: Sergey Cheremencev Xyratex-bug-id: MRP-2109 Reviewed-on: http://review.whamcloud.com/12325 Tested-by: Jenkins Reviewed-by: Fan Yong Reviewed-by: Alex Zhuravlev Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index 603f4bb..547bb11 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -2173,7 +2173,7 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) sf->sf_internal_flags = SIF_NO_HANDLE_OLD_FID; dirty = 1; } else if (rc != 0) { - RETURN(rc); + GOTO(cleanup_inode, rc); } else { if (memcmp(sf->sf_uuid, es->s_uuid, 16) != 0) { osd_scrub_file_reset(scrub, es->s_uuid,SF_INCONSISTENT); @@ -2192,48 +2192,52 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) if (dirty != 0) { rc = osd_scrub_file_store(scrub); if (rc != 0) - RETURN(rc); + GOTO(cleanup_inode, rc); } /* Initialize OI files. */ rc = osd_oi_init(info, dev); if (rc < 0) - RETURN(rc); + GOTO(cleanup_inode, rc); rc = osd_initial_OI_scrub(info, dev); - if (rc == 0) { - if (sf->sf_flags & SF_UPGRADE || - !(sf->sf_internal_flags & SIF_NO_HANDLE_OLD_FID || - sf->sf_success_count > 0)) { - dev->od_igif_inoi = 0; - dev->od_check_ff = dev->od_is_ost; - } else { - dev->od_igif_inoi = 1; - dev->od_check_ff = 0; - } - - if (sf->sf_flags & SF_INCONSISTENT) - /* The 'od_igif_inoi' will be set under the - * following cases: - * 1) new created system, or - * 2) restored from file-level backup, or - * 3) the upgrading completed. - * - * The 'od_igif_inoi' may be cleared by OI scrub - * later if found that the system is upgrading. */ - dev->od_igif_inoi = 1; + if (rc != 0) + GOTO(cleanup_oi, rc); - if (!dev->od_noscrub && - ((sf->sf_status == SS_PAUSED) || - (sf->sf_status == SS_CRASHED && - sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | - SF_UPGRADE | SF_AUTO)) || - (sf->sf_status == SS_INIT && - sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | - SF_UPGRADE)))) - rc = osd_scrub_start(dev); + if (sf->sf_flags & SF_UPGRADE || + !(sf->sf_internal_flags & SIF_NO_HANDLE_OLD_FID || + sf->sf_success_count > 0)) { + dev->od_igif_inoi = 0; + dev->od_check_ff = dev->od_is_ost; + } else { + dev->od_igif_inoi = 1; + dev->od_check_ff = 0; } + if (sf->sf_flags & SF_INCONSISTENT) + /* The 'od_igif_inoi' will be set under the + * following cases: + * 1) new created system, or + * 2) restored from file-level backup, or + * 3) the upgrading completed. + * + * The 'od_igif_inoi' may be cleared by OI scrub + * later if found that the system is upgrading. */ + dev->od_igif_inoi = 1; + + if (!dev->od_noscrub && + ((sf->sf_status == SS_PAUSED) || + (sf->sf_status == SS_CRASHED && + sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | + SF_UPGRADE | SF_AUTO)) || + (sf->sf_status == SS_INIT && + sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | + SF_UPGRADE)))) + rc = osd_scrub_start(dev); + + if (rc != 0) + GOTO(cleanup_oi, rc); + /* it is possible that dcache entries may keep objects after they are * deleted by OSD. While it looks safe this can cause object data to * stay until umount causing failures in tests calculating free space, @@ -2241,7 +2245,14 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) * anymore let's just free them after use here */ shrink_dcache_sb(sb); - RETURN(rc); + RETURN(0); +cleanup_oi: + osd_oi_fini(info, dev); +cleanup_inode: + iput(scrub->os_inode); + scrub->os_inode = NULL; + + return rc; } void osd_scrub_cleanup(const struct lu_env *env, struct osd_device *dev) diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index c154d94..3aa7690 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -5166,6 +5166,58 @@ test_82b() { # LU-4665 } run_test 82b "specify OSTs for file with --pool and --ost-list options" +test_83() { + local dev + local ostmnt + local fstype + local mnt_opts + + if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then + skip "Only applicable to ldiskfs-based MDTs" + return + fi + + dev=$(ostdevname 1) + ostmnt=$(facet_mntpt ost1) + fstype=$(facet_fstype ost1) + + # Mount the OST as an ldiskfs filesystem. + log "mount the OST $dev as a $fstype filesystem" + add ost1 $(mkfs_opts ost1 $dev) $FSTYPE_OPT \ + --reformat $dev $dev > /dev/null || + error "format ost1 error" + + if ! test -b $dev; then + mnt_opts=$(csa_add "$OST_MOUNT_OPTS" -o loop) + fi + echo "mnt_opts $mnt_opts" + do_facet ost1 mount -t $fstype $dev \ + $ostmnt $mnt_opts + # Run llverfs on the mounted ldiskfs filesystem. + # It is needed to get ENOSPACE. + log "run llverfs in partial mode on the OST $fstype $ostmnt" + do_rpc_nodes $(facet_host ost1) run_llverfs $ostmnt -vpl \ + "no" || error "run_llverfs error on $fstype" + + # Unmount the OST. + log "unmount the OST $dev" + stop ost1 + + # Delete file IO_scrub. Later osd_scrub_setup will try to + # create "IO_scrub" but will get ENOSPACE. + writeconf_all + echo "start ost1 service on `facet_active_host ost1`" + start ost1 `ostdevname 1` $OST_MOUNT_OPTS + + local err + err=$(do_facet ost1 dmesg | grep "VFS: Busy inodes after unmount of") + echo "string err $err" + [ -z "$err" ] || error $err + reformat +} +run_test 83 "ENOSPACE on OST doesn't cause message VFS: \ +Busy inodes after unmount ..." + if ! combined_mgs_mds ; then stop mgs fi