X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fosd-zfs%2Fosd_quota.c;h=14ba2cdf7fd516637e3b623427e26d283c83cb0c;hb=1ea468480e6bee5782d96955a60d5bab1491b080;hp=2e9152c6da02704a0702affbe3a499724e03e2cc;hpb=5963af745b3aa14410d5ceb66f8a7b7d6aaf576a;p=fs%2Flustre-release.git diff --git a/lustre/osd-zfs/osd_quota.c b/lustre/osd-zfs/osd_quota.c index 2e9152c..14ba2cd 100644 --- a/lustre/osd-zfs/osd_quota.c +++ b/lustre/osd-zfs/osd_quota.c @@ -34,12 +34,23 @@ /** * Helper function to retrieve DMU object id from fid for accounting object */ -uint64_t osd_quota_fid2dmu(const struct lu_fid *fid) +inline int osd_quota_fid2dmu(const struct lu_fid *fid, uint64_t *oid) { + int rc = 0; + LASSERT(fid_is_acct(fid)); - if (fid_oid(fid) == ACCT_GROUP_OID) - return DMU_GROUPUSED_OBJECT; - return DMU_USERUSED_OBJECT; + switch (fid_oid(fid)) { + case ACCT_GROUP_OID: + *oid = DMU_GROUPUSED_OBJECT; + break; + case ACCT_USER_OID: + *oid = DMU_USERUSED_OBJECT; + break; + default: + rc = -EINVAL; + break; + } + return rc; } /** @@ -92,54 +103,57 @@ static int osd_acct_index_lookup(const struct lu_env *env, { struct osd_thread_info *info = osd_oti_get(env); char *buf = info->oti_buf; + size_t buflen = sizeof(info->oti_buf); struct lquota_acct_rec *rec = (struct lquota_acct_rec *)dtrec; struct osd_object *obj = osd_dt_obj(dtobj); struct osd_device *osd = osd_obj2dev(obj); int rc; - uint64_t oid; + uint64_t oid = 0; ENTRY; rec->bspace = rec->ispace = 0; /* convert the 64-bit uid/gid into a string */ - sprintf(buf, "%llx", *((__u64 *)dtkey)); + snprintf(buf, buflen, "%llx", *((__u64 *)dtkey)); /* fetch DMU object ID (DMU_USERUSED_OBJECT/DMU_GROUPUSED_OBJECT) to be * used */ - oid = osd_quota_fid2dmu(lu_object_fid(&dtobj->do_lu)); + rc = osd_quota_fid2dmu(lu_object_fid(&dtobj->do_lu), &oid); + if (rc) + RETURN(rc); /* disk usage (in bytes) is maintained by DMU. * DMU_USERUSED_OBJECT/DMU_GROUPUSED_OBJECT are special objects which - * not associated with any dmu_but_t (see dnode_special_open()). - * As a consequence, we cannot use udmu_zap_lookup() here since it - * requires a valid oo_dn. */ - rc = -zap_lookup(osd->od_os, oid, buf, sizeof(uint64_t), 1, + * not associated with any dmu_but_t (see dnode_special_open()). */ + rc = zap_lookup(osd->od_os, oid, buf, sizeof(uint64_t), 1, &rec->bspace); - if (rc == -ENOENT) + if (rc == -ENOENT) { /* user/group has not created anything yet */ CDEBUG(D_QUOTA, "%s: id %s not found in DMU accounting ZAP\n", osd->od_svname, buf); - else if (rc) + } else if (rc) { RETURN(rc); + } - if (osd->od_quota_iused_est) { + if (!osd_dmu_userobj_accounting_available(osd)) { if (rec->bspace != 0) /* estimate #inodes in use */ rec->ispace = osd_objset_user_iused(osd, rec->bspace); - RETURN(+1); + rc = 1; + } else { + snprintf(buf, buflen, OSD_DMU_USEROBJ_PREFIX "%llx", + *((__u64 *)dtkey)); + rc = zap_lookup(osd->od_os, oid, buf, sizeof(uint64_t), 1, + &rec->ispace); + if (rc == -ENOENT) { + CDEBUG(D_QUOTA, + "%s: id %s not found dnode accounting\n", + osd->od_svname, buf); + } else if (rc == 0) { + rc = 1; + } } - /* as for inode accounting, it is not maintained by DMU, so we just - * use our own ZAP to track inode usage */ - rc = -zap_lookup(osd->od_os, obj->oo_dn->dn_object, - 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, buf); - else if (rc) - RETURN(rc); - - RETURN(+1); + RETURN(rc); } /** @@ -169,7 +183,9 @@ static struct dt_it *osd_it_acct_init(const struct lu_env *env, RETURN(ERR_PTR(-ENOMEM)); memset(it, 0, sizeof(*it)); - it->oiq_oid = osd_quota_fid2dmu(lu_object_fid(lo)); + rc = osd_quota_fid2dmu(lu_object_fid(lo), &it->oiq_oid); + if (rc) + RETURN(ERR_PTR(rc)); /* initialize zap cursor */ rc = osd_zap_cursor_init(&it->oiq_zc, osd->od_os, it->oiq_oid, 0); @@ -329,7 +345,7 @@ static int osd_it_acct_rec(const struct lu_env *env, if (rc) RETURN(rc); - if (osd->od_quota_iused_est) { + if (!osd_dmu_userobj_accounting_available(osd)) { if (rec->bspace != 0) /* estimate #inodes in use */ rec->ispace = osd_objset_user_iused(osd, rec->bspace);