From 106abc184d8b57de560dc1874683ce5487dcf30a Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Wed, 3 May 2017 15:45:13 +0300 Subject: [PATCH] LU-8856 osd: mark specific transactions netfree 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: Ia5ca247843b296319376c4ac69efad68b557df9f Signed-off-by: Alex Zhuravlev Reviewed-on: https://review.whamcloud.com/31444 Reviewed-by: Andreas Dilger Tested-by: Jenkins Reviewed-by: Mike Pershin Tested-by: Maloo Reviewed-by: Fan Yong --- config/lustre-build-zfs.m4 | 13 +++++++++++ lustre/osd-zfs/osd_handler.c | 1 + lustre/osd-zfs/osd_internal.h | 4 ++++ lustre/osd-zfs/osd_io.c | 1 + lustre/osd-zfs/osd_object.c | 2 ++ lustre/tests/sanity-lfsck.sh | 4 ++-- lustre/tests/sanity.sh | 46 +++++++++++++++++++++++++++++++++++++++ lustre/utils/libmount_utils_zfs.c | 3 +++ 8 files changed, 72 insertions(+), 2 deletions(-) diff --git a/config/lustre-build-zfs.m4 b/config/lustre-build-zfs.m4 index 07f00dc..6debc60 100644 --- a/config/lustre-build-zfs.m4 +++ b/config/lustre-build-zfs.m4 @@ -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 + ],[ + 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], [ diff --git a/lustre/osd-zfs/osd_handler.c b/lustre/osd-zfs/osd_handler.c index d2bb0c7..dfa285c 100644 --- a/lustre/osd-zfs/osd_handler.c +++ b/lustre/osd-zfs/osd_handler.c @@ -983,6 +983,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); diff --git a/lustre/osd-zfs/osd_internal.h b/lustre/osd-zfs/osd_internal.h index 4877600..edb881c 100644 --- a/lustre/osd-zfs/osd_internal.h +++ b/lustre/osd-zfs/osd_internal.h @@ -1090,4 +1090,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 */ diff --git a/lustre/osd-zfs/osd_io.c b/lustre/osd-zfs/osd_io.c index ac7a9aa..fef00d7 100644 --- a/lustre/osd-zfs/osd_io.c +++ b/lustre/osd-zfs/osd_io.c @@ -1028,6 +1028,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); diff --git a/lustre/osd-zfs/osd_object.c b/lustre/osd-zfs/osd_object.c index 0734da2..06f1407 100644 --- a/lustre/osd-zfs/osd_object.c +++ b/lustre/osd-zfs/osd_object.c @@ -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); diff --git a/lustre/tests/sanity-lfsck.sh b/lustre/tests/sanity-lfsck.sh index 8c1ed01..eb50b54 100644 --- a/lustre/tests/sanity-lfsck.sh +++ b/lustre/tests/sanity-lfsck.sh @@ -8,8 +8,8 @@ set -e ONLY=${ONLY:-"$*"} -#Bug number for excepting test LU-10406 -ALWAYS_EXCEPT="$SANITY_LFSCK_EXCEPT 31c" +#Bug number for excepting test LU-10732 LU-10406 +ALWAYS_EXCEPT="$SANITY_LFSCK_EXCEPT 9a 31c" [ "$SLOW" = "no" ] && EXCEPT_SLOW="" # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT! diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 93f71ef..e99e0ed 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -18265,6 +18265,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 # diff --git a/lustre/utils/libmount_utils_zfs.c b/lustre/utils/libmount_utils_zfs.c index 04b1d61..148260c 100644 --- a/lustre/utils/libmount_utils_zfs.c +++ b/lustre/utils/libmount_utils_zfs.c @@ -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; } -- 1.8.3.1