From e431666d6636ce5ff3637592188fc96bcf695a31 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Thu, 3 Aug 2017 18:42:39 -0700 Subject: [PATCH] LU-8999 quota: fix quota iteration interface Since zfs 0.7.0, object accounting is maintained by DMU, so that quota iteration interface should retrieve the information over there. Signed-off-by: Jinshan Xiong Change-Id: I3d0744dfb52b1a9088b828bc72d648872ec4d00b Reviewed-on: https://review.whamcloud.com/28345 Reviewed-by: Niu Yawei Reviewed-by: Fan Yong Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- lustre/osd-zfs/osd_internal.h | 6 ++++-- lustre/osd-zfs/osd_quota.c | 49 +++++++++++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/lustre/osd-zfs/osd_internal.h b/lustre/osd-zfs/osd_internal.h index bda22e9..d7e6e99 100644 --- a/lustre/osd-zfs/osd_internal.h +++ b/lustre/osd-zfs/osd_internal.h @@ -770,7 +770,8 @@ static inline void osd_dnode_rele(dnode_t *dn) #ifdef HAVE_DMU_USEROBJ_ACCOUNTING -#define OSD_DMU_USEROBJ_PREFIX DMU_OBJACCT_PREFIX +#define OSD_DMU_USEROBJ_PREFIX DMU_OBJACCT_PREFIX +#define OSD_DMU_USEROBJ_PREFIX_LEN DMU_OBJACCT_PREFIX_LEN static inline bool osd_dmu_userobj_accounting_available(struct osd_device *osd) { @@ -781,7 +782,8 @@ static inline bool osd_dmu_userobj_accounting_available(struct osd_device *osd) } #else -#define OSD_DMU_USEROBJ_PREFIX "obj-" +#define OSD_DMU_USEROBJ_PREFIX "obj-" +#define OSD_DMU_USEROBJ_PREFIX_LEN 4 static inline bool osd_dmu_userobj_accounting_available(struct osd_device *osd) { diff --git a/lustre/osd-zfs/osd_quota.c b/lustre/osd-zfs/osd_quota.c index b3d45af..20da34e 100644 --- a/lustre/osd-zfs/osd_quota.c +++ b/lustre/osd-zfs/osd_quota.c @@ -207,6 +207,29 @@ static void osd_it_acct_fini(const struct lu_env *env, struct dt_it *di) } /** + * Locate the first entry that is for space accounting. + */ +static int osd_zap_locate(struct osd_it_quota *it, zap_attribute_t *za) +{ + int rc; + ENTRY; + + while (1) { + rc = -zap_cursor_retrieve(it->oiq_zc, za); + if (rc) + break; + + if (strncmp(za->za_name, OSD_DMU_USEROBJ_PREFIX, + OSD_DMU_USEROBJ_PREFIX_LEN)) + break; + + zap_cursor_advance(it->oiq_zc); + } + + RETURN(rc); +} + +/** * Move on to the next valid entry. * * \param di - osd iterator @@ -225,10 +248,9 @@ static int osd_it_acct_next(const struct lu_env *env, struct dt_it *di) if (it->oiq_reset == 0) zap_cursor_advance(it->oiq_zc); it->oiq_reset = 0; - rc = -zap_cursor_retrieve(it->oiq_zc, za); - if (rc == -ENOENT) /* reached the end */ - rc = 1; - RETURN(rc); + + rc = osd_zap_locate(it, za); + RETURN(rc == -ENOENT ? 1 : rc); } /** @@ -245,10 +267,13 @@ static struct dt_key *osd_it_acct_key(const struct lu_env *env, ENTRY; it->oiq_reset = 0; - rc = -zap_cursor_retrieve(it->oiq_zc, za); + rc = osd_zap_locate(it, za); if (rc) RETURN(ERR_PTR(rc)); + rc = kstrtoull(za->za_name, 16, &it->oiq_id); + if (rc) + CERROR("couldn't parse name %s\n", za->za_name); RETURN((struct dt_key *) &it->oiq_id); } @@ -347,15 +372,18 @@ static int osd_it_acct_rec(const struct lu_env *env, if (unlikely(rc != 0)) RETURN(rc); - /* inode accounting is not maintained by DMU, so we use our own ZAP to - * track inode usage */ + /* inode accounting is maintained by DMU since 0.7.0 */ + strncpy(info->oti_buf, OSD_DMU_USEROBJ_PREFIX, + OSD_DMU_USEROBJ_PREFIX_LEN); + strlcpy(info->oti_buf + OSD_DMU_USEROBJ_PREFIX_LEN, za->za_name, + sizeof(info->oti_buf) - OSD_DMU_USEROBJ_PREFIX_LEN); rc = osd_zap_lookup(osd, it->oiq_obj->oo_dn->dn_object, - it->oiq_obj->oo_dn, za->za_name, sizeof(uint64_t), + it->oiq_obj->oo_dn, info->oti_buf, sizeof(uint64_t), 1, &rec->ispace); if (rc == -ENOENT) /* user/group has not created any file yet */ CDEBUG(D_QUOTA, "%s: id %s not found in accounting ZAP\n", - osd->od_svname, za->za_name); + osd->od_svname, info->oti_buf); else if (rc) RETURN(rc); @@ -405,12 +433,11 @@ static int osd_it_acct_load(const struct lu_env *env, it->oiq_zc = zc; it->oiq_reset = 0; - rc = -zap_cursor_retrieve(it->oiq_zc, za); + rc = osd_zap_locate(it, za); if (rc == 0) rc = 1; else if (rc == -ENOENT) rc = 0; - RETURN(rc); } -- 1.8.3.1