/* index features supported by the accounting objects */
extern const struct dt_index_features dt_acct_features;
+/* index features supported by the quota global indexes */
+extern const struct dt_index_features dt_quota_glb_features;
+
+/* index features supported by the quota slave indexes */
+extern const struct dt_index_features dt_quota_slv_features;
+
/**
* This is a general purpose dt allocation hint.
* It now contains the parent object.
#ifndef _LUSTRE_LQUOTA_H
#define _LUSTRE_LQUOTA_H
-/*
- * Space accounting support
- * Format of an accounting record, providing disk usage information for a given
- * user or group
- */
-struct acct_rec { /* 16 bytes */
- __u64 bspace; /* current space in use */
- __u64 ispace; /* current # inodes in use */
+/* Gather all quota record type in an union that can be used to read any records
+ * from disk. All fields of these records must be 64-bit aligned, otherwise the
+ * OSD layer may swab them incorrectly. */
+union lquota_rec {
+ struct lquota_glb_rec lqr_glb_rec;
+ struct lquota_slv_rec lqr_slv_rec;
+ struct lquota_acct_rec lqr_acct_rec;
};
/* Name used in the configuration logs to identify the default metadata pool
};
extern void lustre_swab_quota_adjust_qunit(struct quota_adjust_qunit *q);
+/*
+ * Space accounting support
+ * Format of an accounting record, providing disk usage information for a given
+ * user or group
+ */
+struct lquota_acct_rec { /* 16 bytes */
+ __u64 bspace; /* current space in use */
+ __u64 ispace; /* current # inodes in use */
+};
+
+/*
+ * Global quota index support
+ * Format of a global record, providing global quota settings for a given quota
+ * identifier
+ */
+struct lquota_glb_rec { /* 32 bytes */
+ __u64 qbr_hardlimit; /* quota hard limit, in #inodes or kbytes */
+ __u64 qbr_softlimit; /* quota soft limit, in #inodes or kbytes */
+ __u64 qbr_time; /* grace time, in seconds */
+ __u64 qbr_granted; /* how much is granted to slaves, in #inodes or
+ * kbytes */
+};
+
+/*
+ * Slave index support
+ * Format of a slave record, recording how much space is granted to a given
+ * slave
+ */
+struct lquota_slv_rec { /* 8 bytes */
+ __u64 qsr_granted; /* space granted to the slave for the key=ID,
+ * in #inodes or kbytes */
+};
+
/* flags is shared among quota structures */
#define LQUOTA_FLAGS_GRP 1UL /* 0 is user, 1 is group */
#define LQUOTA_FLAGS_BLK 2UL /* 0 is inode, 1 is block */
.dif_flags = DT_IND_UPDATE,
.dif_keysize_min = sizeof(__u64), /* 64-bit uid/gid */
.dif_keysize_max = sizeof(__u64), /* 64-bit uid/gid */
- .dif_recsize_min = sizeof(struct acct_rec), /* 32 bytes */
- .dif_recsize_max = sizeof(struct acct_rec), /* 32 bytes */
+ .dif_recsize_min = sizeof(struct lquota_acct_rec), /* 16 bytes */
+ .dif_recsize_max = sizeof(struct lquota_acct_rec), /* 16 bytes */
.dif_ptrsize = 4
};
EXPORT_SYMBOL(dt_acct_features);
+
+/* global quota files */
+const struct dt_index_features dt_quota_glb_features = {
+ .dif_flags = DT_IND_UPDATE,
+ /* a different key would have to be used for per-directory quota */
+ .dif_keysize_min = sizeof(__u64), /* 64-bit uid/gid */
+ .dif_keysize_max = sizeof(__u64), /* 64-bit uid/gid */
+ .dif_recsize_min = sizeof(struct lquota_glb_rec), /* 32 bytes */
+ .dif_recsize_max = sizeof(struct lquota_glb_rec), /* 32 bytes */
+ .dif_ptrsize = 4
+};
+EXPORT_SYMBOL(dt_quota_glb_features);
+
+/* slave quota files */
+const struct dt_index_features dt_quota_slv_features = {
+ .dif_flags = DT_IND_UPDATE,
+ /* a different key would have to be used for per-directory quota */
+ .dif_keysize_min = sizeof(__u64), /* 64-bit uid/gid */
+ .dif_keysize_max = sizeof(__u64), /* 64-bit uid/gid */
+ .dif_recsize_min = sizeof(struct lquota_slv_rec), /* 8 bytes */
+ .dif_recsize_max = sizeof(struct lquota_slv_rec), /* 8 bytes */
+ .dif_ptrsize = 4
+};
+EXPORT_SYMBOL(dt_quota_slv_features);
struct osd_thread_info *info = osd_oti_get(env);
struct if_dqblk *dqblk = &info->oti_dqblk;
struct super_block *sb = osd_sb(osd_obj2dev(osd_dt_obj(dtobj)));
- struct acct_rec *rec = (struct acct_rec *)dtrec;
+ struct lquota_acct_rec *rec = (struct lquota_acct_rec *)dtrec;
__u64 id = *((__u64 *)dtkey);
int rc;
{
struct osd_thread_info *info = osd_oti_get(env);
char *buf = info->oti_buf;
- struct acct_rec *rec = (struct acct_rec *)dtrec;
+ 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;
struct osd_thread_info *info = osd_oti_get(env);
char *buf = info->oti_buf;
struct osd_it_quota *it = (struct osd_it_quota *)di;
- struct acct_rec *rec = (struct acct_rec *)dtrec;
+ struct lquota_acct_rec *rec = (struct lquota_acct_rec *)dtrec;
struct osd_object *obj = it->oiq_obj;
struct osd_device *osd = osd_obj2dev(obj);
int bytes_read;
LASSERTF(Q_FINVALIDATE == 0x800104, "found 0x%.8x\n",
Q_FINVALIDATE);
+ /* Checks for struct lquota_acct_rec */
+ LASSERTF((int)sizeof(struct lquota_acct_rec) == 16, "found %lld\n",
+ (long long)(int)sizeof(struct lquota_acct_rec));
+ LASSERTF((int)offsetof(struct lquota_acct_rec, bspace) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_acct_rec, bspace));
+ LASSERTF((int)sizeof(((struct lquota_acct_rec *)0)->bspace) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_acct_rec *)0)->bspace));
+ LASSERTF((int)offsetof(struct lquota_acct_rec, ispace) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_acct_rec, ispace));
+ LASSERTF((int)sizeof(((struct lquota_acct_rec *)0)->ispace) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_acct_rec *)0)->ispace));
+
+ /* Checks for struct lquota_glb_rec */
+ LASSERTF((int)sizeof(struct lquota_glb_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct lquota_glb_rec));
+ LASSERTF((int)offsetof(struct lquota_glb_rec, qbr_hardlimit) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_glb_rec, qbr_hardlimit));
+ LASSERTF((int)sizeof(((struct lquota_glb_rec *)0)->qbr_hardlimit) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_glb_rec *)0)->qbr_hardlimit));
+ LASSERTF((int)offsetof(struct lquota_glb_rec, qbr_softlimit) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_glb_rec, qbr_softlimit));
+ LASSERTF((int)sizeof(((struct lquota_glb_rec *)0)->qbr_softlimit) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_glb_rec *)0)->qbr_softlimit));
+ LASSERTF((int)offsetof(struct lquota_glb_rec, qbr_time) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_glb_rec, qbr_time));
+ LASSERTF((int)sizeof(((struct lquota_glb_rec *)0)->qbr_time) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_glb_rec *)0)->qbr_time));
+ LASSERTF((int)offsetof(struct lquota_glb_rec, qbr_granted) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_glb_rec, qbr_granted));
+ LASSERTF((int)sizeof(((struct lquota_glb_rec *)0)->qbr_granted) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_glb_rec *)0)->qbr_granted));
+
+ /* Checks for struct lquota_slv_rec */
+ LASSERTF((int)sizeof(struct lquota_slv_rec) == 8, "found %lld\n",
+ (long long)(int)sizeof(struct lquota_slv_rec));
+ LASSERTF((int)offsetof(struct lquota_slv_rec, qsr_granted) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_slv_rec, qsr_granted));
+ LASSERTF((int)sizeof(((struct lquota_slv_rec *)0)->qsr_granted) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_slv_rec *)0)->qsr_granted));
+
/* Checks for struct niobuf_remote */
LASSERTF((int)sizeof(struct niobuf_remote) == 16, "found %lld\n",
(long long)(int)sizeof(struct niobuf_remote));
*/
static int lprocfs_quota_seq_show(struct seq_file *p, void *v)
{
- struct lquota_procfs *lqp = p->private;
- const struct dt_it_ops *iops;
- struct dt_it *it;
- struct dt_key *key;
- struct acct_rec rec;
- int rc;
+ struct lquota_procfs *lqp = p->private;
+ const struct dt_it_ops *iops;
+ struct dt_it *it;
+ struct dt_key *key;
+ struct lquota_acct_rec rec;
+ int rc;
LASSERT(lqp);
if (lqp->lqp_obj == NULL) {
#define QTYPE_NAME(qtype) ((qtype) == USRQUOTA ? "usr" : "grp")
+#define QIF_IFLAGS (QIF_INODES | QIF_ITIME | QIF_ILIMITS)
+#define QIF_BFLAGS (QIF_SPACE | QIF_BTIME | QIF_BLIMITS)
+
+/* The biggest filename are the one used for slave index which are in the form
+ * of 0x%x-%s,glb_fid.f_oid,slv_uuid, that's to say:
+ * 2(0x) + 8(f_oid) + 1(-) + 40(UUID_MAX) which means 51 chars + '\0' */
+#define LQUOTA_NAME_MAX 52
+
+/* reserved OID in FID_SEQ_QUOTA for local objects */
+enum lquota_local_oid {
+ LQUOTA_USR_OID = 1UL, /* slave index copy for user quota */
+ LQUOTA_GRP_OID = 2UL, /* slave index copy for group quota */
+ /* all OIDs after this are allocated dynamically by the QMT */
+ LQUOTA_GENERATED_OID = 4096UL,
+};
+
+/* Common data shared by quota-level handlers. This is allocated per-thread to
+ * reduce stack consumption */
+struct lquota_thread_info {
+ union lquota_rec qti_rec;
+ struct lu_buf qti_lb;
+ struct lu_attr qti_attr;
+ struct dt_object_format qti_dof;
+ struct lustre_mdt_attrs qti_lma;
+ struct lu_fid qti_fid;
+ char qti_buf[LQUOTA_NAME_MAX];
+};
+
+#define qti_glb_rec qti_rec.lqr_glb_rec
+#define qti_acct_rec qti_rec.lqr_acct_rec
+#define qti_slv_rec qti_rec.lqr_slv_rec
+
+extern struct lu_context_key lquota_thread_key;
+
+/* extract lquota_threa_info context from environment */
+static inline
+struct lquota_thread_info *lquota_info(const struct lu_env *env)
+{
+ struct lquota_thread_info *info;
+
+ info = lu_context_key_get(&env->le_ctx, &lquota_thread_key);
+ LASSERT(info);
+ return info;
+}
+
/* lquota_lib.c */
struct dt_object *acct_obj_lookup(const struct lu_env *, struct dt_device *,
- __u32);
+ int);
/* lproc_quota.c */
extern struct file_operations lprocfs_quota_seq_fops;
+/* quota_interface.c
+ * old quota module initialization routines, to be removed */
+int init_lustre_quota(void);
+void exit_lustre_quota(void);
+
#endif /* _LQUOTA_INTERNAL_H */
* GPL HEADER END
*/
/*
- * Copyright (c) 2011, 2012, Whamcloud, Inc.
+ * Copyright (c) 2011, 2012, Intel, Inc.
* Use is subject to license terms.
*
- * Author: Johann Lombardi <johann@whamcloud.com>
- * Author: Niu Yawei <niu@whamcloud.com>
+ * Author: Johann Lombardi <johann.lombardi@intel.com>
+ * Author: Niu Yawei <yawei.niu@intel.com>
*/
#ifndef EXPORT_SYMTAB
#define DEBUG_SUBSYSTEM S_LQUOTA
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
#include "lquota_internal.h"
-static struct dt_object_format dt_acct_format = {
- .dof_type = DFT_INDEX,
- .u.dof_idx.di_feat = &dt_acct_features
-};
+/* register lquota key */
+LU_KEY_INIT_FINI(lquota, struct lquota_thread_info);
+LU_CONTEXT_KEY_DEFINE(lquota, LCT_MD_THREAD | LCT_DT_THREAD | LCT_LOCAL);
+LU_KEY_INIT_GENERIC(lquota);
/**
* Look-up accounting object to collect space usage information for user
* or group.
*
- * \param env - is the environment passed by the caller
- * \param dev - is the dt_device storing the accounting object
- * \param oid - is the object id of the accounting object to initialize, must be
- * either ACCT_USER_OID or ACCT_GROUP_OID.
+ * \param env - is the environment passed by the caller
+ * \param dev - is the dt_device storing the accounting object
+ * \param type - is the quota type, either USRQUOTA or GRPQUOTA
*/
struct dt_object *acct_obj_lookup(const struct lu_env *env,
- struct dt_device *dev, __u32 oid)
+ struct dt_device *dev, int type)
{
- struct dt_object *obj = NULL;
- struct lu_fid fid;
- struct lu_attr attr;
- int rc;
+ struct lquota_thread_info *qti = lquota_info(env);
+ struct dt_object *obj = NULL;
ENTRY;
- memset(&attr, 0, sizeof(attr));
- attr.la_valid = LA_MODE;
- attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR;
- lu_local_obj_fid(&fid, oid);
+ lu_local_obj_fid(&qti->qti_fid,
+ type == USRQUOTA ? ACCT_USER_OID : ACCT_GROUP_OID);
- /* lookup/create the accounting object */
- obj = dt_find_or_create(env, dev, &fid, &dt_acct_format, &attr);
+ /* lookup the accounting object */
+ obj = dt_locate(env, dev, &qti->qti_fid);
if (IS_ERR(obj))
RETURN(obj);
+ if (!dt_object_exists(obj)) {
+ lu_object_put(env, &obj->do_lu);
+ RETURN(ERR_PTR(-ENOENT));
+ }
+
if (obj->do_index_ops == NULL) {
+ int rc;
+
/* set up indexing operations */
rc = obj->do_ops->do_index_try(env, obj, &dt_acct_features);
if (rc) {
+ CERROR("%s: failed to set up indexing operations for %s"
+ " acct object rc:%d\n",
+ dev->dd_lu_dev.ld_obd->obd_name,
+ QTYPE_NAME(type), rc);
+ lu_object_put(env, &obj->do_lu);
+ RETURN(ERR_PTR(rc));
+ }
+ }
+ RETURN(obj);
+}
+
+/**
+ * Initialize slave index object to collect local quota limit for user or group.
+ *
+ * \param env - is the environment passed by the caller
+ * \param dev - is the dt_device storing the slave index object
+ * \param type - is the quota type, either USRQUOTA or GRPQUOTA
+ */
+static struct dt_object *quota_obj_lookup(const struct lu_env *env,
+ struct dt_device *dev, int type)
+{
+ struct lquota_thread_info *qti = lquota_info(env);
+ struct dt_object *obj = NULL;
+ ENTRY;
+
+ qti->qti_fid.f_seq = FID_SEQ_QUOTA;
+ qti->qti_fid.f_oid = type == USRQUOTA ? LQUOTA_USR_OID : LQUOTA_GRP_OID;
+ qti->qti_fid.f_ver = 0;
+
+ /* lookup the quota object */
+ obj = dt_locate(env, dev, &qti->qti_fid);
+ if (IS_ERR(obj))
+ RETURN(obj);
+
+ if (!dt_object_exists(obj)) {
+ lu_object_put(env, &obj->do_lu);
+ RETURN(ERR_PTR(-ENOENT));
+ }
+
+ if (obj->do_index_ops == NULL) {
+ int rc;
+
+ /* set up indexing operations */
+ rc = obj->do_ops->do_index_try(env, obj,
+ &dt_quota_slv_features);
+ if (rc) {
+ CERROR("%s: failed to set up indexing operations for %s"
+ " slave index object rc:%d\n",
+ dev->dd_lu_dev.ld_obd->obd_name,
+ QTYPE_NAME(type), rc);
lu_object_put(env, &obj->do_lu);
RETURN(ERR_PTR(rc));
}
int lquotactl_slv(const struct lu_env *env, struct dt_device *dev,
struct obd_quotactl *oqctl)
{
- struct acct_rec rec;
- __u64 key;
- struct dt_object *obj;
- int rc = 0;
+ struct lquota_thread_info *qti = lquota_info(env);
+ __u64 key;
+ struct dt_object *obj;
+ struct obd_dqblk *dqblk = &oqctl->qc_dqblk;
+ int rc;
ENTRY;
if (oqctl->qc_cmd != Q_GETOQUOTA) {
/* as in many other places, dev->dd_lu_dev.ld_obd->obd_name
- * point to a valid obd_name, to be fixed in LU-1574 */
+ * point to an invalid obd_name, to be fixed in LU-1574 */
CERROR("%s: Unsupported quotactl command: %x\n",
dev->dd_lu_dev.ld_obd->obd_name, oqctl->qc_cmd);
RETURN(-EOPNOTSUPP);
}
- if (oqctl->qc_type == USRQUOTA)
- obj = acct_obj_lookup(env, dev, ACCT_USER_OID);
- else if (oqctl->qc_type == GRPQUOTA)
- obj = acct_obj_lookup(env, dev, ACCT_GROUP_OID);
- else
+ if (oqctl->qc_type != USRQUOTA && oqctl->qc_type != GRPQUOTA)
/* no support for directory quota yet */
RETURN(-EOPNOTSUPP);
+ /* qc_id is a 32-bit field while a key has 64 bits */
+ key = oqctl->qc_id;
+
+ /* Step 1: collect accounting information */
+
+ obj = acct_obj_lookup(env, dev, oqctl->qc_type);
if (IS_ERR(obj))
RETURN(-EOPNOTSUPP);
if (obj->do_index_ops == NULL)
GOTO(out, rc = -EINVAL);
- /* qc_id is a 32-bit field while a key has 64 bits */
- key = oqctl->qc_id;
-
/* lookup record storing space accounting information for this ID */
- rc = dt_lookup(env, obj, (struct dt_rec *)&rec, (struct dt_key *)&key,
- BYPASS_CAPA);
+ rc = dt_lookup(env, obj, (struct dt_rec *)&qti->qti_acct_rec,
+ (struct dt_key *)&key, BYPASS_CAPA);
if (rc < 0)
GOTO(out, rc);
memset(&oqctl->qc_dqblk, 0, sizeof(struct obd_dqblk));
- oqctl->qc_dqblk.dqb_curspace = rec.bspace;
- oqctl->qc_dqblk.dqb_curinodes = rec.ispace;
- oqctl->qc_dqblk.dqb_valid = QIF_USAGE;
- /* TODO: must set {hard,soft}limit and grace time */
+ dqblk->dqb_curspace = qti->qti_acct_rec.bspace;
+ dqblk->dqb_curinodes = qti->qti_acct_rec.ispace;
+ dqblk->dqb_valid = QIF_USAGE;
+
+ lu_object_put(env, &obj->do_lu);
+
+ /* Step 2: collect enforcement information */
- EXIT;
+ obj = quota_obj_lookup(env, dev, oqctl->qc_type);
+ if (IS_ERR(obj))
+ RETURN(0);
+ if (obj->do_index_ops == NULL)
+ GOTO(out, rc = 0);
+
+ memset(&qti->qti_slv_rec, 0, sizeof(qti->qti_slv_rec));
+ /* lookup record storing enforcement information for this ID */
+ rc = dt_lookup(env, obj, (struct dt_rec *)&qti->qti_slv_rec,
+ (struct dt_key *)&key, BYPASS_CAPA);
+ if (rc < 0 && rc != -ENOENT)
+ GOTO(out, rc = 0);
+
+ if (lu_device_is_md(dev->dd_lu_dev.ld_site->ls_top_dev)) {
+ dqblk->dqb_ihardlimit = qti->qti_slv_rec.qsr_granted;
+ dqblk->dqb_bhardlimit = 0;
+ } else {
+ dqblk->dqb_ihardlimit = 0;
+ dqblk->dqb_bhardlimit = qti->qti_slv_rec.qsr_granted;
+ }
+ dqblk->dqb_valid |= QIF_LIMITS;
+
+ GOTO(out, rc = 0);
out:
lu_object_put(env, &obj->do_lu);
return rc;
}
EXPORT_SYMBOL(lquotactl_slv);
+
+static int __init init_lquota(void)
+{
+ int rc;
+
+ /* call old quota module init function */
+ rc = init_lustre_quota();
+ if (rc)
+ return rc;
+
+ /* new quota initialization */
+ lquota_key_init_generic(&lquota_thread_key, NULL);
+ lu_context_key_register(&lquota_thread_key);
+
+ return 0;
+}
+
+static void exit_lquota(void)
+{
+ /* call old quota module exit function */
+ exit_lustre_quota();
+
+ lu_context_key_degister(&lquota_thread_key);
+}
+
+MODULE_AUTHOR("Intel, Inc. <http://www.intel.com/>");
+MODULE_DESCRIPTION("Lustre Quota");
+MODULE_LICENSE("GPL");
+
+cfs_module(lquota, "2.4.0", init_lquota, exit_lquota);
cfs_proc_dir_entry_t *lquota_type_proc_dir = NULL;
-static int __init init_lustre_quota(void)
+int init_lustre_quota(void)
{
int rc = 0;
return 0;
}
-static void /*__exit*/ exit_lustre_quota(void)
+void exit_lustre_quota(void)
{
PORTAL_SYMBOL_UNREGISTER(filter_quota_interface);
PORTAL_SYMBOL_UNREGISTER(mds_quota_interface);
lprocfs_remove(&lquota_type_proc_dir);
}
-MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
-MODULE_DESCRIPTION("Lustre Quota");
-MODULE_LICENSE("GPL");
-
-cfs_module(lquota, "1.0.0", init_lustre_quota, exit_lustre_quota);
-
EXPORT_SYMBOL(mds_quota_interface);
EXPORT_SYMBOL(filter_quota_interface);
#endif /* __KERNEL */
CHECK_DEFINE_X(Q_GETOINFO);
CHECK_DEFINE_X(Q_GETOQUOTA);
CHECK_DEFINE_X(Q_FINVALIDATE);
+
+ BLANK_LINE();
+ CHECK_STRUCT(lquota_acct_rec);
+ CHECK_MEMBER(lquota_acct_rec, bspace);
+ CHECK_MEMBER(lquota_acct_rec, ispace);
+
+ BLANK_LINE();
+ CHECK_STRUCT(lquota_glb_rec);
+ CHECK_MEMBER(lquota_glb_rec, qbr_hardlimit);
+ CHECK_MEMBER(lquota_glb_rec, qbr_softlimit);
+ CHECK_MEMBER(lquota_glb_rec, qbr_time);
+ CHECK_MEMBER(lquota_glb_rec, qbr_granted);
+
+ BLANK_LINE();
+ CHECK_STRUCT(lquota_slv_rec);
+ CHECK_MEMBER(lquota_slv_rec, qsr_granted);
+
}
static void
LASSERTF(Q_FINVALIDATE == 0x800104, "found 0x%.8x\n",
Q_FINVALIDATE);
+ /* Checks for struct lquota_acct_rec */
+ LASSERTF((int)sizeof(struct lquota_acct_rec) == 16, "found %lld\n",
+ (long long)(int)sizeof(struct lquota_acct_rec));
+ LASSERTF((int)offsetof(struct lquota_acct_rec, bspace) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_acct_rec, bspace));
+ LASSERTF((int)sizeof(((struct lquota_acct_rec *)0)->bspace) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_acct_rec *)0)->bspace));
+ LASSERTF((int)offsetof(struct lquota_acct_rec, ispace) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_acct_rec, ispace));
+ LASSERTF((int)sizeof(((struct lquota_acct_rec *)0)->ispace) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_acct_rec *)0)->ispace));
+
+ /* Checks for struct lquota_glb_rec */
+ LASSERTF((int)sizeof(struct lquota_glb_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct lquota_glb_rec));
+ LASSERTF((int)offsetof(struct lquota_glb_rec, qbr_hardlimit) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_glb_rec, qbr_hardlimit));
+ LASSERTF((int)sizeof(((struct lquota_glb_rec *)0)->qbr_hardlimit) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_glb_rec *)0)->qbr_hardlimit));
+ LASSERTF((int)offsetof(struct lquota_glb_rec, qbr_softlimit) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_glb_rec, qbr_softlimit));
+ LASSERTF((int)sizeof(((struct lquota_glb_rec *)0)->qbr_softlimit) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_glb_rec *)0)->qbr_softlimit));
+ LASSERTF((int)offsetof(struct lquota_glb_rec, qbr_time) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_glb_rec, qbr_time));
+ LASSERTF((int)sizeof(((struct lquota_glb_rec *)0)->qbr_time) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_glb_rec *)0)->qbr_time));
+ LASSERTF((int)offsetof(struct lquota_glb_rec, qbr_granted) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_glb_rec, qbr_granted));
+ LASSERTF((int)sizeof(((struct lquota_glb_rec *)0)->qbr_granted) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_glb_rec *)0)->qbr_granted));
+
+ /* Checks for struct lquota_slv_rec */
+ LASSERTF((int)sizeof(struct lquota_slv_rec) == 8, "found %lld\n",
+ (long long)(int)sizeof(struct lquota_slv_rec));
+ LASSERTF((int)offsetof(struct lquota_slv_rec, qsr_granted) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct lquota_slv_rec, qsr_granted));
+ LASSERTF((int)sizeof(((struct lquota_slv_rec *)0)->qsr_granted) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lquota_slv_rec *)0)->qsr_granted));
+
/* Checks for struct niobuf_remote */
LASSERTF((int)sizeof(struct niobuf_remote) == 16, "found %lld\n",
(long long)(int)sizeof(struct niobuf_remote));