* GPL HEADER END
*/
/*
- * Copyright (c) 2012 Intel, Inc.
+ * Copyright (c) 2012, 2017, Intel Corporation.
* Use is subject to license terms.
*
* Author: Johann Lombardi <johann.lombardi@intel.com>
* required and create the index file on disk if
* it does not exist.
* - lquota_disk_for_each_slv: iterate over all existing slave index files
- * - lquota_disk_read: read quota settings from a index file
+ * - lquota_disk_read: read quota settings from an index file
* - lquota_disk_declare_write: reserve credits to update a record in an index
* file
* - lquota_disk_write: update a record in an index file
* - lquota_disk_update_ver: update version of an index file
*/
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
-
#define DEBUG_SUBSYSTEM S_LQUOTA
#include "lquota_internal.h"
const struct dt_index_features *idx_feat,
char *name)
{
- struct lquota_thread_info *qti = lquota_info(env);
- struct dt_object *obj;
- struct local_oid_storage *los;
- int rc;
+ struct lquota_thread_info *qti = lquota_info(env);
+ struct dt_object *obj;
+ struct local_oid_storage *los;
+ int rc;
ENTRY;
/* Set up local storage */
/* local_oid_storage_fini() will finalize the local storage device,
* we have to open the object in another device stack */
qti->qti_fid = obj->do_lu.lo_header->loh_fid;
- lu_object_put_nocache(env, &obj->do_lu);
+ dt_object_put_nocache(env, obj);
obj = dt_locate(env, dev, &qti->qti_fid);
if (IS_ERR(obj))
GOTO(out, obj);
GOTO(out, rc);
parent = dt_locate_at(env, dev, &qti->qti_fid,
- dev->dd_lu_dev.ld_site->ls_top_dev);
+ dev->dd_lu_dev.ld_site->ls_top_dev, NULL);
if (IS_ERR(parent))
GOTO(out, rc = PTR_ERR(parent));
} else {
/* local_oid_storage_fini() will finalize the local storage device,
* we have to open the object in another device stack */
qti->qti_fid = qt_dir->do_lu.lo_header->loh_fid;
- lu_object_put_nocache(env, &qt_dir->do_lu);
+ dt_object_put_nocache(env, qt_dir);
qt_dir = dt_locate(env, dev, &qti->qti_fid);
if (IS_ERR(qt_dir))
GOTO(out, rc = PTR_ERR(qt_dir));
EXIT;
out:
if (parent != NULL && !IS_ERR(parent))
- lu_object_put(env, &parent->do_lu);
+ dt_object_put(env, parent);
if (los != NULL)
local_oid_storage_fini(env, los);
if (rc) {
if (qt_dir != NULL && !IS_ERR(qt_dir))
- lu_object_put(env, &qt_dir->do_lu);
+ dt_object_put(env, qt_dir);
qt_dir = ERR_PTR(rc);
}
return qt_dir;
CDEBUG(D_QUOTA, "look-up/create %sglobal idx file ("DFID")\n",
local ? "local " : "", PFID(fid));
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0)
- /* we use different index feature for each quota type and target type
- * for the time being. This is done for on-disk conversion from the old
- * quota format. Once this is no longer required, we should just be
- * using dt_quota_glb_features for all global index file */
- idx_feat = glb_idx_feature(fid);
-#else
-#warning "remove old quota compatibility code"
idx_feat = &dt_quota_glb_features;
-#endif
/* the filename is composed of the most signicant bits of the FID,
* that's to say the oid which encodes the pool id, pool type and quota
CERROR("%s: failed to setup index operations for "DFID
" rc:%d\n", dev->dd_lu_dev.ld_obd->obd_name,
PFID(lu_object_fid(&glb_idx->do_lu)), rc);
- lu_object_put(env, &glb_idx->do_lu);
+ dt_object_put(env, glb_idx);
glb_idx = ERR_PTR(rc);
}
}
CERROR("%s: failed to setup slave index operations for "
"%s, rc:%d\n", dev->dd_lu_dev.ld_obd->obd_name,
obd_uuid2str(uuid), rc);
- lu_object_put(env, &slv_idx->do_lu);
+ dt_object_put(env, slv_idx);
slv_idx = ERR_PTR(rc);
}
}
RETURN(ERR_PTR(rc));
/* use predefined fid in the reserved oid list */
- qti->qti_fid.f_oid = (type == USRQUOTA) ? LQUOTA_USR_OID
- : LQUOTA_GRP_OID;
+ qti->qti_fid.f_oid = qtype2slv_oid(type);
slv_idx = local_index_find_or_create_with_fid(env, dev,
&qti->qti_fid,
CERROR("%s: failed to setup index operations for "DFID
" rc:%d\n", dev->dd_lu_dev.ld_obd->obd_name,
PFID(lu_object_fid(&slv_idx->do_lu)), rc);
- lu_object_put(env, &slv_idx->do_lu);
+ dt_object_put(env, slv_idx);
slv_idx = ERR_PTR(rc);
}
}
int rc;
ENTRY;
- OBD_ALLOC(name, sizeof("0x00000000-"));
+ OBD_ALLOC(name, LQUOTA_NAME_MAX);
if (name == NULL)
RETURN(-ENOMEM);
sprintf(name, "0x%x-", glb_fid->f_oid);
iops = &parent->do_index_ops->dio_it;
- it = iops->init(env, parent, 0, BYPASS_CAPA);
+ it = iops->init(env, parent, 0);
if (IS_ERR(it)) {
- OBD_FREE(name, sizeof("0x00000000-"));
+ OBD_FREE(name, LQUOTA_NAME_MAX);
RETURN(PTR_ERR(it));
}
iops->put(env, it);
iops->fini(env, it);
- OBD_FREE(name, sizeof("0x00000000-"));
+ OBD_FREE(name, LQUOTA_NAME_MAX);
if (rc > 0)
rc = 0;
RETURN(rc);
/* lookup on-disk record from index file */
dt_read_lock(env, obj, 0);
- rc = dt_lookup(env, obj, rec, (struct dt_key *)&id->qid_uid,
- BYPASS_CAPA);
+ rc = dt_lookup(env, obj, rec, (struct dt_key *)&id->qid_uid);
dt_read_unlock(env, obj);
RETURN(rc);
dt_write_lock(env, obj, 0);
/* check whether there is already an existing record for this ID */
- rc = dt_lookup(env, obj, (struct dt_rec *)&qti->qti_rec, key,
- BYPASS_CAPA);
+ rc = dt_lookup(env, obj, (struct dt_rec *)&qti->qti_rec, key);
if (rc == 0) {
/* delete existing record in order to replace it */
- rc = dt_delete(env, obj, key, th, BYPASS_CAPA);
+ rc = dt_delete(env, obj, key, th);
if (rc)
GOTO(out, rc);
} else if (rc == -ENOENT) {
if (rec != NULL) {
/* insert record with updated quota settings */
- rc = dt_insert(env, obj, rec, key, th, BYPASS_CAPA, 1);
+ rc = dt_insert(env, obj, rec, key, th);
if (rc) {
/* try to insert the old one */
rc = dt_insert(env, obj, (struct dt_rec *)&qti->qti_rec,
- key, th, BYPASS_CAPA, 1);
+ key, th);
LASSERTF(rc == 0, "failed to insert record in quota "
- "index "DFID,
+ "index "DFID"\n",
PFID(lu_object_fid(&obj->do_lu)));
GOTO(out, rc);
}
dt_trans_stop(env, dev, th);
return rc;
}
+
+/*
+ * Write a global record
+ *
+ * \param env - is the environment passed by the caller
+ * \param obj - is the on-disk global index to be updated
+ * \param id - index to be updated
+ * \param rec - record to be written
+ */
+int lquota_disk_write_glb(const struct lu_env *env, struct dt_object *obj,
+ __u64 id, struct lquota_glb_rec *rec)
+{
+ struct dt_device *dev = lu2dt_dev(obj->do_lu.lo_dev);
+ struct thandle *th;
+ struct dt_key *key = (struct dt_key *)&id;
+ int rc;
+ ENTRY;
+
+ th = dt_trans_create(env, dev);
+ if (IS_ERR(th))
+ RETURN(PTR_ERR(th));
+
+ /* the entry with 0 key can always be found in IAM file. */
+ if (id == 0) {
+ rc = dt_declare_delete(env, obj, key, th);
+ if (rc)
+ GOTO(out, rc);
+ }
+
+ rc = dt_declare_insert(env, obj, (struct dt_rec *)rec, key, th);
+ if (rc)
+ GOTO(out, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc)
+ GOTO(out, rc);
+
+ dt_write_lock(env, obj, 0);
+
+ if (id == 0) {
+ struct lquota_glb_rec *tmp;
+
+ OBD_ALLOC_PTR(tmp);
+ if (tmp == NULL)
+ GOTO(out_lock, rc = -ENOMEM);
+
+ rc = dt_lookup(env, obj, (struct dt_rec *)tmp, key);
+
+ OBD_FREE_PTR(tmp);
+ if (rc == 0) {
+ rc = dt_delete(env, obj, key, th);
+ if (rc)
+ GOTO(out_lock, rc);
+ }
+ rc = 0;
+ }
+
+ rc = dt_insert(env, obj, (struct dt_rec *)rec, key, th);
+out_lock:
+ dt_write_unlock(env, obj);
+out:
+ dt_trans_stop(env, dev, th);
+ RETURN(rc);
+}