int od_connects;
struct lu_site od_site;
- /* object IDs of the inode accounting indexes */
- uint64_t od_iusr_oid;
- uint64_t od_igrp_oid;
dnode_t *od_groupused_dn;
dnode_t *od_userused_dn;
int osd_statfs(const struct lu_env *, struct dt_device *, struct obd_statfs *);
extern const struct dt_index_operations osd_acct_index_ops;
-dnode_t *osd_quota_fid2dmu(const struct osd_device *, const struct lu_fid *fid);
extern struct lu_device_operations osd_lu_ops;
extern struct dt_index_operations osd_dir_ops;
int osd_declare_quota(const struct lu_env *env, struct osd_device *osd,
RETURN(rc);
}
+/**
+ * Helper function to retrieve DMU object id from fid for accounting object
+ */
+static dnode_t *osd_quota_fid2dmu(const struct osd_device *osd,
+ const struct lu_fid *fid)
+{
+ dnode_t *dn = NULL;
+
+ LASSERT(fid_is_acct(fid));
+
+ switch (fid_oid(fid)) {
+ case ACCT_USER_OID:
+ dn = osd->od_userused_dn;
+ break;
+ case ACCT_GROUP_OID:
+ dn = osd->od_groupused_dn;
+ break;
+ default:
+ break;
+ }
+
+ return dn;
+}
+
/*
* Concurrency: no concurrent access is possible that early in object
* life-cycle.
static int osd_object_init(const struct lu_env *env, struct lu_object *l,
const struct lu_object_conf *conf)
{
- struct osd_object *obj = osd_obj(l);
- struct osd_device *osd = osd_obj2dev(obj);
- uint64_t oid;
- int rc;
+ struct osd_object *obj = osd_obj(l);
+ struct osd_device *osd = osd_obj2dev(obj);
+ const struct lu_fid *fid = lu_object_fid(l);
+ uint64_t oid;
+ int rc = 0;
ENTRY;
LASSERT(osd_invariant(obj));
if (conf != NULL && conf->loc_flags & LOC_F_NEW)
GOTO(out, rc = 0);
- rc = osd_fid_lookup(env, osd, lu_object_fid(l), &oid);
+ if (unlikely(fid_is_acct(fid))) {
+ obj->oo_dn = osd_quota_fid2dmu(osd, fid);
+ if (obj->oo_dn) {
+ obj->oo_dt.do_index_ops = &osd_acct_index_ops;
+ l->lo_header->loh_attr |= LOHA_EXISTS;
+ }
+
+ GOTO(out, rc = 0);
+ }
+
+ rc = osd_fid_lookup(env, osd, fid, &oid);
if (rc == 0) {
LASSERT(obj->oo_dn == NULL);
rc = __osd_obj2dnode(osd->od_os, oid, &obj->oo_dn);
static void osd_object_delete(const struct lu_env *env, struct lu_object *l)
{
struct osd_object *obj = osd_obj(l);
-
- if (obj->oo_dn != NULL) {
- osd_object_sa_fini(obj);
- if (obj->oo_sa_xattr) {
- nvlist_free(obj->oo_sa_xattr);
- obj->oo_sa_xattr = NULL;
+ const struct lu_fid *fid = lu_object_fid(l);
+
+ if (obj->oo_dn) {
+ if (likely(!fid_is_acct(fid))) {
+ osd_object_sa_fini(obj);
+ if (obj->oo_sa_xattr) {
+ nvlist_free(obj->oo_sa_xattr);
+ obj->oo_sa_xattr = NULL;
+ }
+ osd_dnode_rele(obj->oo_dn);
+ list_del(&obj->oo_sa_linkage);
}
- osd_dnode_rele(obj->oo_dn);
- list_del(&obj->oo_sa_linkage);
obj->oo_dn = NULL;
}
}
if (unlikely(!dt_object_exists(dt) || obj->oo_destroyed))
GOTO(out, rc = -ENOENT);
+ if (unlikely(fid_is_acct(lu_object_fid(&dt->do_lu))))
+ GOTO(out, rc = 0);
+
LASSERT(osd_invariant(obj));
LASSERT(obj->oo_dn);
ENTRY;
+ LASSERT(!fid_is_acct(fid));
+
/* concurrent create declarations should not see
* the object inconsistent (db, attr, etc).
* in regular cases acquisition should be cheap */
/* XXX: oo_lma_flags */
obj->oo_dt.do_lu.lo_header->loh_attr |= obj->oo_attr.la_mode & S_IFMT;
- if (likely(!fid_is_acct(lu_object_fid(&obj->oo_dt.do_lu))))
- /* no body operations for accounting objects */
- obj->oo_dt.do_body_ops = &osd_body_ops;
+ obj->oo_dt.do_body_ops = &osd_body_ops;
rc = -nvlist_alloc(&obj->oo_sa_xattr, NV_UNIQUE_NAME, KM_SLEEP);
if (rc)
GOTO(out, rc);
/* initialize LMA */
- lustre_lma_init(lma, lu_object_fid(&obj->oo_dt.do_lu), 0, 0);
+ lustre_lma_init(lma, fid, 0, 0);
lustre_lma_swab(lma);
rc = -nvlist_add_byte_array(obj->oo_sa_xattr, XATTR_NAME_LMA,
(uchar_t *)lma, sizeof(*lma));
{ .oid = FLD_INDEX_OID, .name = "fld" },
{ .oid = MDD_LOV_OBJ_OID, .name = LOV_OBJID },
{ .oid = OFD_HEALTH_CHECK_OID, .name = HEALTH_CHECK },
- { .oid = ACCT_USER_OID, .name = "acct_usr_inode" },
- { .oid = ACCT_GROUP_OID, .name = "acct_grp_inode" },
- { .oid = ACCT_PROJECT_OID, .name = "acct_prj_inode" },
{ .oid = REPLY_DATA_OID, .name = REPLY_DATA },
{ .oid = 0 }
};
uint64_t zapid;
LASSERT(fid);
+ LASSERT(!fid_is_acct(fid));
+
if (zdn != NULL)
*zdn = NULL;
zapid = osd->od_root;
if (buf)
strncpy(buf, name, bufsize);
- if (fid_is_acct(fid))
- zapid = MASTER_NODE_OBJ;
} else {
zapid = osd_get_idx_for_fid(osd, fid, buf, NULL);
}
fid_oid(fid) == OSD_FS_ROOT_OID;
}
-static inline int osd_oid(struct osd_device *dev, __u32 local_oid,
- uint64_t *oid)
-{
- switch (local_oid) {
- case ACCT_USER_OID:
- *oid = dev->od_iusr_oid;
- return 0;
- case ACCT_GROUP_OID:
- *oid = dev->od_igrp_oid;
- return 0;
- case ACCT_PROJECT_OID:
- /* TODO: real oid */
- CERROR("%s: unsupported quota oid: %#x\n",
- osd_name(dev), local_oid);
- return -ENOTSUPP;
- }
-
- return -ENOTSUPP;
-}
-
int osd_fid_lookup(const struct lu_env *env, struct osd_device *dev,
const struct lu_fid *fid, uint64_t *oid)
{
if (OBD_FAIL_CHECK(OBD_FAIL_SRV_ENOENT))
RETURN(-ENOENT);
- if (unlikely(fid_is_acct(fid))) {
- rc = osd_oid(dev, fid_oid(fid), oid);
- if (rc)
- RETURN(rc);
- } else if (unlikely(fid_is_fs_root(fid))) {
+ LASSERT(!fid_is_acct(fid));
+
+ if (unlikely(fid_is_fs_root(fid))) {
*oid = dev->od_root;
} else {
zapid = osd_get_name_n_idx(env, dev, fid, buf,
static int
osd_oi_init_compat(const struct lu_env *env, struct osd_device *o)
{
- uint64_t odb, sdb;
- int rc;
+ uint64_t sdb;
+ int rc;
ENTRY;
rc = osd_oi_find_or_create(env, o, o->od_root, "O", &sdb);
- if (rc)
- RETURN(rc);
-
- o->od_O_id = sdb;
-
- /* Create on-disk indexes to maintain per-UID/GID inode usage.
- * Those new indexes are created in the top-level ZAP outside the
- * namespace in order not to confuse ZPL which might interpret those
- * indexes as directories and assume the values are object IDs */
- rc = osd_oi_find_or_create(env, o, MASTER_NODE_OBJ,
- oid2name(ACCT_USER_OID), &odb);
- if (rc)
- RETURN(rc);
- o->od_iusr_oid = odb;
-
- rc = osd_oi_find_or_create(env, o, MASTER_NODE_OBJ,
- oid2name(ACCT_GROUP_OID), &odb);
- if (rc)
- RETURN(rc);
- o->od_igrp_oid = odb;
+ if (!rc)
+ o->od_O_id = sdb;
RETURN(rc);
}
struct osd_idmap_cache *idc;
int rc;
+ LASSERT(!fid_is_acct(fid));
+
idc = osd_idc_find(env, osd, fid);
if (idc != NULL)
return idc;
#include "osd_internal.h"
/**
- * Helper function to retrieve DMU object id from fid for accounting object
- */
-dnode_t *osd_quota_fid2dmu(const struct osd_device *osd,
- const struct lu_fid *fid)
-{
- LASSERT(fid_is_acct(fid));
- if (fid_oid(fid) == ACCT_GROUP_OID)
- return osd->od_groupused_dn;
- return osd->od_userused_dn;
-}
-
-/**
- * Helper function to estimate the number of inodes in use for a give uid/gid
- * from the block usage
+ * Helper function to estimate the number of inodes in use for the given
+ * uid/gid from the block usage
*/
static uint64_t osd_objset_user_iused(struct osd_device *osd, uint64_t uidbytes)
{
struct dt_rec *dtrec,
const struct dt_key *dtkey)
{
- 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;
- dnode_t *dn;
+ struct osd_thread_info *info = osd_oti_get(env);
+ char *buf = 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);
+ dnode_t *dn = obj->oo_dn;
+ size_t buflen = sizeof(info->oti_buf);
+ int rc;
ENTRY;
rec->bspace = rec->ispace = 0;
/* convert the 64-bit uid/gid into a string */
snprintf(buf, buflen, "%llx", *((__u64 *)dtkey));
- /* fetch DMU object (DMU_USERUSED_OBJECT/DMU_GROUPUSED_OBJECT) to be
- * used */
- dn = osd_quota_fid2dmu(osd, lu_object_fid(&dtobj->do_lu));
+ if (unlikely(!dn)) {
+ CDEBUG(D_QUOTA, "%s: miss accounting obj for %s\n",
+ osd->od_svname, buf);
+
+ RETURN(-ENOENT);
+ }
/* disk usage (in bytes) is maintained by DMU.
* DMU_USERUSED_OBJECT/DMU_GROUPUSED_OBJECT are special objects which
/* user/group has not created anything yet */
CDEBUG(D_QUOTA, "%s: id %s not found in DMU accounting ZAP\n",
osd->od_svname, buf);
+ /* -ENOENT is normal case, convert it as 1. */
+ rc = 1;
} else if (rc) {
RETURN(rc);
}
CDEBUG(D_QUOTA,
"%s: id %s not found dnode accounting\n",
osd->od_svname, buf);
+ /* -ENOENT is normal case, convert it as 1. */
+ rc = 1;
} else if (rc == 0) {
rc = 1;
}
struct dt_object *dt,
__u32 attr)
{
- struct osd_thread_info *info = osd_oti_get(env);
- struct osd_it_quota *it;
- struct lu_object *lo = &dt->do_lu;
- struct osd_device *osd = osd_dev(lo->lo_dev);
- dnode_t *dn;
+ struct osd_thread_info *info = osd_oti_get(env);
+ struct osd_it_quota *it;
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct osd_device *osd = osd_obj2dev(obj);
+ dnode_t *dn = obj->oo_dn;
int rc;
ENTRY;
- LASSERT(lu_object_exists(lo));
+ if (unlikely(!dn)) {
+ CDEBUG(D_QUOTA, "%s: Not found in DMU accounting ZAP\n",
+ osd->od_svname);
+
+ RETURN(ERR_PTR(-ENOENT));
+ }
if (info == NULL)
RETURN(ERR_PTR(-ENOMEM));
RETURN(ERR_PTR(-ENOMEM));
memset(it, 0, sizeof(*it));
- dn = osd_quota_fid2dmu(osd, lu_object_fid(lo));
it->oiq_oid = dn->dn_object;
/* initialize zap cursor */
}
/* take object reference */
- lu_object_get(lo);
+ lu_object_get(&dt->do_lu);
it->oiq_obj = osd_dt_obj(dt);
it->oiq_reset = 1;