X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosc%2Fosc_quota.c;h=a0aaae784515a0567dbb5fe36563667dfaa97074;hp=244658761a29f5b5e417dd16dfcf24fb38296751;hb=3cce65712d94cffe8f1626545845b95b88aef672;hpb=b117bc837c02e2d156bb114142a28a184aa9d633 diff --git a/lustre/osc/osc_quota.c b/lustre/osc/osc_quota.c index 2446587..a0aaae7 100644 --- a/lustre/osc/osc_quota.c +++ b/lustre/osc/osc_quota.c @@ -23,12 +23,14 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * - * Copyright (c) 2012, 2013, Intel Corporation. + * Copyright (c) 2012, 2017, Intel Corporation. * * Code originally extracted from quota directory */ #include +#include + #include "osc_internal.h" static inline struct osc_quota_info *osc_oqi_alloc(u32 id) @@ -47,7 +49,7 @@ int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]) int type; ENTRY; - for (type = 0; type < MAXQUOTAS; type++) { + for (type = 0; type < LL_MAXQUOTAS; type++) { struct osc_quota_info *oqi; oqi = cfs_hash_lookup(cli->cl_quota_hash[type], &qid[type]); @@ -66,30 +68,65 @@ int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]) RETURN(QUOTA_OK); } -#define MD_QUOTA_FLAG(type) ((type == USRQUOTA) ? OBD_MD_FLUSRQUOTA \ - : OBD_MD_FLGRPQUOTA) -#define FL_QUOTA_FLAG(type) ((type == USRQUOTA) ? OBD_FL_NO_USRQUOTA \ - : OBD_FL_NO_GRPQUOTA) +static inline u32 md_quota_flag(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return OBD_MD_FLUSRQUOTA; + case GRPQUOTA: + return OBD_MD_FLGRPQUOTA; + case PRJQUOTA: + return OBD_MD_FLPRJQUOTA; + default: + return 0; + } +} + +static inline u32 fl_quota_flag(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return OBD_FL_NO_USRQUOTA; + case GRPQUOTA: + return OBD_FL_NO_GRPQUOTA; + case PRJQUOTA: + return OBD_FL_NO_PRJQUOTA; + default: + return 0; + } +} -int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], +int osc_quota_setdq(struct client_obd *cli, __u64 xid, const unsigned int qid[], u64 valid, u32 flags) { int type; int rc = 0; + ENTRY; - if ((valid & (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA)) == 0) + if ((valid & (OBD_MD_FLALLQUOTA)) == 0) RETURN(0); - for (type = 0; type < MAXQUOTAS; type++) { + mutex_lock(&cli->cl_quota_mutex); + /* still mark the quots is running out for the old request, because it + * could be processed after the new request at OST, the side effect is + * the following request will be processed synchronously, but it will + * not break the quota enforcement. */ + if (cli->cl_quota_last_xid > xid && !(flags & OBD_FL_NO_QUOTA_ALL)) + GOTO(out_unlock, rc); + + if (cli->cl_quota_last_xid < xid) + cli->cl_quota_last_xid = xid; + + for (type = 0; type < LL_MAXQUOTAS; type++) { struct osc_quota_info *oqi; - if ((valid & MD_QUOTA_FLAG(type)) == 0) + if ((valid & md_quota_flag(type)) == 0) continue; /* lookup the ID in the per-type hash table */ oqi = cfs_hash_lookup(cli->cl_quota_hash[type], &qid[type]); - if ((flags & FL_QUOTA_FLAG(type)) != 0) { + if ((flags & fl_quota_flag(type)) != 0) { /* This ID is getting close to its quota limit, let's * switch to sync I/O */ if (oqi != NULL) @@ -110,9 +147,7 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], } CDEBUG(D_QUOTA, "%s: setdq to insert for %s %d (%d)\n", - cli_name(cli), - type == USRQUOTA ? "user" : "group", - qid[type], rc); + cli_name(cli), qtype_name(type), qid[type], rc); } else { /* This ID is now off the hook, let's remove it from * the hash table */ @@ -125,12 +160,12 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], OBD_SLAB_FREE_PTR(oqi, osc_quota_kmem); CDEBUG(D_QUOTA, "%s: setdq to remove for %s %d (%p)\n", - cli_name(cli), - type == USRQUOTA ? "user" : "group", - qid[type], oqi); + cli_name(cli), qtype_name(type), qid[type], oqi); } } +out_unlock: + mutex_unlock(&cli->cl_quota_mutex); RETURN(rc); } @@ -210,7 +245,9 @@ int osc_quota_setup(struct obd_device *obd) int i, type; ENTRY; - for (type = 0; type < MAXQUOTAS; type++) { + mutex_init(&cli->cl_quota_mutex); + + for (type = 0; type < LL_MAXQUOTAS; type++) { cli->cl_quota_hash[type] = cfs_hash_create("QUOTA_HASH", HASH_QUOTA_CUR_BITS, HASH_QUOTA_MAX_BITS, @@ -224,7 +261,7 @@ int osc_quota_setup(struct obd_device *obd) break; } - if (type == MAXQUOTAS) + if (type == LL_MAXQUOTAS) RETURN(0); for (i = 0; i < type; i++) @@ -239,7 +276,7 @@ int osc_quota_cleanup(struct obd_device *obd) int type; ENTRY; - for (type = 0; type < MAXQUOTAS; type++) + for (type = 0; type < LL_MAXQUOTAS; type++) cfs_hash_putref(cli->cl_quota_hash[type]); RETURN(0);