Whamcloud - gitweb
LU-5729 osd: iput in case of error in osd_scrub_setup 25/12325/4
authorSergey Cheremencev <sergey.cheremencev@seagate.com>
Fri, 26 Sep 2014 13:00:56 +0000 (17:00 +0400)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 19 Nov 2014 19:17:36 +0000 (19:17 +0000)
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 <sergey.cheremencev@seagate.com>
Xyratex-bug-id: MRP-2109
Reviewed-on: http://review.whamcloud.com/12325
Tested-by: Jenkins
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/osd-ldiskfs/osd_scrub.c
lustre/tests/conf-sanity.sh

index 603f4bb..547bb11 100644 (file)
@@ -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) {
                        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);
        } 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)
        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)
        }
 
        /* 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);
 
        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,
        /* 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);
 
         * 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)
 }
 
 void osd_scrub_cleanup(const struct lu_env *env, struct osd_device *dev)
index c154d94..3aa7690 100644 (file)
@@ -5166,6 +5166,58 @@ test_82b() { # LU-4665
 }
 run_test 82b "specify OSTs for file with --pool and --ost-list options"
 
 }
 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
 if ! combined_mgs_mds ; then
        stop mgs
 fi