Whamcloud - gitweb
LU-8856 osd: mark specific transactions netfree 30/26930/20
authorAlex Zhuravlev <alexey.zhuravlev@intel.com>
Wed, 3 May 2017 12:45:13 +0000 (15:45 +0300)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 27 Feb 2018 03:41:47 +0000 (03:41 +0000)
osd-zfs should mark some transactions netfree. this means those transactions
are expected to release space (rather than consume) and for this kind of
transaction half of reserved space is available.

Change-Id: I71605bc224882aafac26b3dfb0f3d7e82af8fde8
Signed-off-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-on: https://review.whamcloud.com/26930
Tested-by: Jenkins
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Reviewed-by: Olaf Faaland-LLNL <faaland1@llnl.gov>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
config/lustre-build-zfs.m4
lustre/osd-zfs/osd_handler.c
lustre/osd-zfs/osd_internal.h
lustre/osd-zfs/osd_io.c
lustre/osd-zfs/osd_object.c
lustre/tests/sanity.sh
lustre/utils/libmount_utils_zfs.c

index 07f00dc..6debc60 100644 (file)
@@ -655,6 +655,19 @@ your distribution.
                        AC_DEFINE(HAVE_DMU_OBJSET_DISOWN_3ARG, 1,
                                [Have dmu_objset_disown() with 3 args])
                ])
+               dnl #
+               dnl # ZFS 0.7.2 adds new method dmu_tx_mark_netfree
+               dnl #
+               LB_CHECK_COMPILE([if ZFS has 'dmu_tx_mark_netfree'],
+               dmu_tx_mark_netfree, [
+                       #include <sys/dmu.h>
+               ],[
+                       dmu_tx_t *tx = NULL;
+                       dmu_tx_mark_netfree(tx);
+               ],[
+                       AC_DEFINE(HAVE_DMU_TX_MARK_NETFREE, 1,
+                               [Have dmu_tx_mark_netfree])
+               ])
        ])
 
        AS_IF([test "x$enable_zfs" = xyes], [
index e2e9d31..23d684c 100644 (file)
@@ -977,6 +977,7 @@ int osd_unlinked_object_free(const struct lu_env *env, struct osd_device *osd,
        }
 
        tx = dmu_tx_create(osd->od_os);
+       dmu_tx_mark_netfree(tx);
        dmu_tx_hold_free(tx, oid, 0, DMU_OBJECT_END);
        osd_tx_hold_zap(tx, osd->od_unlinked->dn_object, osd->od_unlinked,
                        FALSE, NULL);
index 5d423cc..30beef8 100644 (file)
@@ -1086,4 +1086,8 @@ osd_index_backup(const struct lu_env *env, struct osd_device *osd, bool backup)
                            &osd->od_index_backup_stop, backup);
 }
 
+#ifndef HAVE_DMU_TX_MARK_NETFREE
+#define dmu_tx_mark_netfree(tx)
+#endif
+
 #endif /* _OSD_INTERNAL_H */
index eda81fa..94c36de 100644 (file)
@@ -1009,6 +1009,7 @@ static int osd_declare_punch(const struct lu_env *env, struct dt_object *dt,
        /* declare we'll free some blocks ... */
        if (start < obj->oo_attr.la_size) {
                read_unlock(&obj->oo_attr_lock);
+               dmu_tx_mark_netfree(oh->ot_tx);
                dmu_tx_hold_free(oh->ot_tx, obj->oo_dn->dn_object, start, len);
        } else {
                read_unlock(&obj->oo_attr_lock);
index c835e92..62f7a83 100644 (file)
@@ -762,6 +762,8 @@ static int osd_declare_destroy(const struct lu_env *env, struct dt_object *dt,
        oh = container_of0(th, struct osd_thandle, ot_super);
        LASSERT(oh->ot_tx != NULL);
 
+       dmu_tx_mark_netfree(oh->ot_tx);
+
        /* declare that we'll remove object from fid-dnode mapping */
        zapid = osd_get_name_n_idx(env, osd, fid, NULL, 0, &dn);
        osd_tx_hold_zap(oh->ot_tx, zapid, dn, FALSE, NULL);
index 683c60e..d49a4cd 100755 (executable)
@@ -18264,6 +18264,52 @@ test_804() {
 }
 run_test 804 "verify agent entry for remote entry"
 
+cleanup_805() {
+       do_facet $SINGLEMDS zfs set quota=$old $fsset
+       unlinkmany $DIR/$tdir/f- 1000000
+       trap 0
+}
+
+test_805() {
+       local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
+       [ "$(facet_fstype mds1)" != "zfs" ] &&
+               skip "ZFS specific test" && return
+       [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
+               skip "netfree not implemented before 0.7" && return
+       [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.10.57) ]] ||
+               { skip "Need MDS version at least 2.10.57" && return 0; }
+
+       local fsset
+       local freekb
+       local usedkb
+       local old
+       local quota
+       local pref="osd-zfs.lustre-MDT0000."
+
+       # limit available space on MDS dataset to meet nospace issue
+       # quickly. then ZFS 0.7.2 can use reserved space if asked
+       # properly (using netfree flag in osd_declare_destroy()
+       fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
+       old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
+               gawk '{print $3}')
+       freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
+       usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
+       let "usedkb=usedkb-freekb"
+       let "freekb=freekb/2"
+       if let "freekb > 5000"; then
+               let "freekb=5000"
+       fi
+       do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
+       trap cleanup_805 EXIT
+       mkdir $DIR/$tdir
+       $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
+       createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
+       rm -rf $DIR/$tdir || error "not able to remove"
+       do_facet $SINGLEMDS zfs set quota=$old $fsset
+       trap 0
+}
+run_test 805 "ZFS can remove from full fs"
+
 #
 # tests that do cleanup/setup should be run at the end
 #
index 04b1d61..148260c 100644 (file)
@@ -543,6 +543,9 @@ static char *zfs_mkfs_opts(struct mkfs_opts *mop, char *str, int len)
 
        if (strlen(mop->mo_mkfsopts) != 0)
                snprintf(str, len, " -o %s", mop->mo_mkfsopts);
+       if (mop->mo_device_kb)
+               snprintf(str, len, " -o quota=%llu",
+                        mop->mo_device_kb * 1024);
 
        return str;
 }