Whamcloud - gitweb
LU-1842 quota: helper routines to manage FID_SEQ_QUOTA_GLB
authorJohann Lombardi <johann@whamcloud.com>
Tue, 11 Sep 2012 11:19:04 +0000 (13:19 +0200)
committerOleg Drokin <green@whamcloud.com>
Wed, 19 Sep 2012 12:58:41 +0000 (08:58 -0400)
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 <johann@whamcloud.com>
Change-Id: I145c1468db7fe0d2a0f198ac323b00913a815c3c
Reviewed-on: http://review.whamcloud.com/3937
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Niu Yawei <niu@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/include/lustre/lustre_idl.h
lustre/ptlrpc/wiretest.c
lustre/quota/lquota_internal.h
lustre/quota/lquota_lib.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 69ffac6..93c4040 100644 (file)
@@ -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
index 665e986..5f6766f 100644 (file)
@@ -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",
index 22fc7a2..4e916f5 100644 (file)
@@ -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;
index 51a0c49..5278818 100644 (file)
@@ -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;
index 409a8ff..b8d2ef3 100644 (file)
@@ -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);
index 4e6f36a..7de9139 100644 (file)
@@ -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",