From 1673c7bdf58234db8963cd292b0a8e02d016ac9e Mon Sep 17 00:00:00 2001 From: Johann Lombardi Date: Tue, 11 Sep 2012 13:19:04 +0200 Subject: [PATCH] LU-1842 quota: helper routines to manage FID_SEQ_QUOTA_GLB The FID_SEQ_QUOTA_GLB sequence is used to produce FID for global quota indexes. The 32-bit object ID is thus divided into 3 fields containing: - 16-bit pool identifier (aka pool_id) - 8-bit quota type (aka LQUOTA_TYPE_{USR,GRP}) - 8-bit resource type (LQUOTA_RES_{MD,DT} for resp. inodes & blocks) This static FID scheme allows slaves to enqueue global quota lock directly on the right FID without requiring a first readdir or to change the resource ID on the fly when the lock is granted. This patch adds the helper routines to manipulate global index FIDs. Signed-off-by: Johann Lombardi Change-Id: I145c1468db7fe0d2a0f198ac323b00913a815c3c Reviewed-on: http://review.whamcloud.com/3937 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Niu Yawei Reviewed-by: Andreas Dilger --- lustre/include/lustre/lustre_idl.h | 18 ++++++++++++ lustre/ptlrpc/wiretest.c | 4 +++ lustre/quota/lquota_internal.h | 2 ++ lustre/quota/lquota_lib.c | 57 ++++++++++++++++++++++++++++++++++++++ lustre/utils/wirecheck.c | 6 ++++ lustre/utils/wiretest.c | 4 +++ 6 files changed, 91 insertions(+) diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 69ffac6..93c4040 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1855,6 +1855,24 @@ struct quota_adjust_qunit { }; extern void lustre_swab_quota_adjust_qunit(struct quota_adjust_qunit *q); +/* Quota types currently supported */ +enum { + LQUOTA_TYPE_USR = 0x00, /* maps to USRQUOTA */ + LQUOTA_TYPE_GRP = 0x01, /* maps to GRPQUOTA */ + LQUOTA_TYPE_MAX +}; + +/* There are 2 different resource types on which a quota limit can be enforced: + * - inodes on the MDTs + * - blocks on the OSTs */ +enum { + LQUOTA_RES_MD = 0x01, /* skip 0 to avoid null oid in FID */ + LQUOTA_RES_DT = 0x02, + LQUOTA_LAST_RES, + LQUOTA_FIRST_RES = LQUOTA_RES_MD +}; +#define LQUOTA_NR_RES (LQUOTA_LAST_RES - LQUOTA_FIRST_RES + 1) + /* * Space accounting support * Format of an accounting record, providing disk usage information for a given diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 665e986..5f6766f 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -336,6 +336,10 @@ void lustre_assert_wire_constants(void) CLASSERT(LUSTRE_RES_ID_SEQ_OFF == 0); CLASSERT(LUSTRE_RES_ID_VER_OID_OFF == 1); CLASSERT(LUSTRE_RES_ID_HSH_OFF == 3); + CLASSERT(LQUOTA_TYPE_USR == 0); + CLASSERT(LQUOTA_TYPE_GRP == 1); + CLASSERT(LQUOTA_RES_MD == 1); + CLASSERT(LQUOTA_RES_DT == 2); LASSERTF(OBD_PING == 400, "found %lld\n", (long long)OBD_PING); LASSERTF(OBD_LOG_CANCEL == 401, "found %lld\n", diff --git a/lustre/quota/lquota_internal.h b/lustre/quota/lquota_internal.h index 22fc7a2..4e916f5 100644 --- a/lustre/quota/lquota_internal.h +++ b/lustre/quota/lquota_internal.h @@ -81,6 +81,8 @@ struct lquota_thread_info *lquota_info(const struct lu_env *env) /* lquota_lib.c */ struct dt_object *acct_obj_lookup(const struct lu_env *, struct dt_device *, int); +void lquota_generate_fid(struct lu_fid *, int, int, int); +int lquota_extract_fid(struct lu_fid *, int *, int *, int *); /* lproc_quota.c */ extern struct file_operations lprocfs_quota_seq_fops; diff --git a/lustre/quota/lquota_lib.c b/lustre/quota/lquota_lib.c index 51a0c49..5278818 100644 --- a/lustre/quota/lquota_lib.c +++ b/lustre/quota/lquota_lib.c @@ -223,6 +223,63 @@ out: } EXPORT_SYMBOL(lquotactl_slv); +/** + * Helper routine returning the FID associated with the global index storing + * quota settings for the storage pool \pool_id, resource type \pool_type and + * the quota type \quota_type. + */ +void lquota_generate_fid(struct lu_fid *fid, int pool_id, int pool_type, + int quota_type) +{ + __u8 qtype; + + qtype = (quota_type == USRQUOTA) ? LQUOTA_TYPE_USR : LQUOTA_TYPE_GRP; + + fid->f_seq = FID_SEQ_QUOTA_GLB; + fid->f_oid = (qtype << 24) | (pool_type << 16) | (__u16)pool_id; + fid->f_ver = 0; +} + +/** + * Helper routine used to extract pool ID, pool type and quota type from a + * given FID. + */ +int lquota_extract_fid(struct lu_fid *fid, int *pool_id, int *pool_type, + int *quota_type) +{ + unsigned int tmp; + ENTRY; + + if (fid->f_seq != FID_SEQ_QUOTA_GLB) + RETURN(-EINVAL); + + if (pool_id != NULL) { + tmp = fid->f_oid & 0xffffU; + if (tmp != 0) + /* we only support pool ID 0 for the time being */ + RETURN(-ENOTSUPP); + *pool_id = tmp; + } + + if (pool_type != NULL) { + tmp = (fid->f_oid >> 16) & 0xffU; + if (tmp >= LQUOTA_LAST_RES) + RETURN(-ENOTSUPP); + + *pool_type = tmp; + } + + if (quota_type != NULL) { + tmp = fid->f_oid >> 24; + if (tmp >= LQUOTA_TYPE_MAX) + RETURN(-ENOTSUPP); + + *quota_type = (tmp == LQUOTA_TYPE_USR) ? USRQUOTA : GRPQUOTA; + } + + RETURN(0); +} + static int __init init_lquota(void) { int rc; diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 409a8ff..b8d2ef3 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -2033,6 +2033,12 @@ main(int argc, char **argv) /* CHECK_CVALUE(LUSTRE_RES_ID_WAS_VER_OFF); packed with OID */ CHECK_CVALUE(LUSTRE_RES_ID_HSH_OFF); + CHECK_CVALUE(LQUOTA_TYPE_USR); + CHECK_CVALUE(LQUOTA_TYPE_GRP); + + CHECK_CVALUE(LQUOTA_RES_MD); + CHECK_CVALUE(LQUOTA_RES_DT); + CHECK_VALUE(OBD_PING); CHECK_VALUE(OBD_LOG_CANCEL); CHECK_VALUE(OBD_QC_CALLBACK); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 4e6f36a..7de9139 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -344,6 +344,10 @@ void lustre_assert_wire_constants(void) CLASSERT(LUSTRE_RES_ID_SEQ_OFF == 0); CLASSERT(LUSTRE_RES_ID_VER_OID_OFF == 1); CLASSERT(LUSTRE_RES_ID_HSH_OFF == 3); + CLASSERT(LQUOTA_TYPE_USR == 0); + CLASSERT(LQUOTA_TYPE_GRP == 1); + CLASSERT(LQUOTA_RES_MD == 1); + CLASSERT(LQUOTA_RES_DT == 2); LASSERTF(OBD_PING == 400, "found %lld\n", (long long)OBD_PING); LASSERTF(OBD_LOG_CANCEL == 401, "found %lld\n", -- 1.8.3.1