* Below are the function prototypes to be used by OSD layer to manage quota
* enforcement. Arguments are documented where each function is defined. */
+/* flags for quota local enforcement */
+enum osd_quota_local_flags {
+ QUOTA_FL_OVER_USRQUOTA = 1 << 0,
+ QUOTA_FL_OVER_GRPQUOTA = 1 << 1,
+ QUOTA_FL_SYNC = 1 << 2,
+ QUOTA_FL_OVER_PRJQUOTA = 1 << 3,
+};
+
struct qsd_instance *qsd_init(const struct lu_env *, char *, struct dt_device *,
struct proc_dir_entry *, bool is_md);
int qsd_prepare(const struct lu_env *, struct qsd_instance *);
int qsd_start(const struct lu_env *, struct qsd_instance *);
void qsd_fini(const struct lu_env *, struct qsd_instance *);
int qsd_op_begin(const struct lu_env *, struct qsd_instance *,
- struct lquota_trans *, struct lquota_id_info *, int *);
+ struct lquota_trans *, struct lquota_id_info *,
+ enum osd_quota_local_flags *);
void qsd_op_end(const struct lu_env *, struct qsd_instance *,
struct lquota_trans *);
void qsd_op_adjust(const struct lu_env *, struct qsd_instance *,
struct lquota_id_info lqt_ids[QUOTA_MAX_TRANSIDS];
};
-/* flags for quota local enforcement */
-#define QUOTA_FL_OVER_USRQUOTA 0x01
-#define QUOTA_FL_OVER_GRPQUOTA 0x02
-#define QUOTA_FL_SYNC 0x04
-#define QUOTA_FL_OVER_PRJQUOTA 0x08
-
#define IS_LQUOTA_RES(res) \
(res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA || \
res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA_GLB)
/* osd_quota.c */
int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh,
struct lquota_id_info *qi, struct osd_object *obj,
- bool enforce, int *flags);
+ bool enforce, enum osd_quota_local_flags *local_flags);
int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid,
__u32 projid, long long space, struct osd_thandle *oh,
- struct osd_object *obj, int *flags,
+ struct osd_object *obj,
+ enum osd_quota_local_flags *local_flags,
enum osd_qid_declare_flags);
const struct dt_rec *osd_quota_pack(struct osd_object *obj,
const struct dt_rec *rec,
int i;
int newblocks;
int rc = 0;
- int flags = 0;
int credits = 0;
long long quota_space = 0;
struct osd_fextent extent = { 0 };
+ enum osd_quota_local_flags local_flags = 0;
enum osd_qid_declare_flags declare_flags = OSD_QID_BLK;
ENTRY;
rc = osd_declare_inode_qid(env, i_uid_read(inode), i_gid_read(inode),
i_projid_read(inode), quota_space, oh,
- osd_dt_obj(dt), &flags, declare_flags);
+ osd_dt_obj(dt), &local_flags, declare_flags);
/* we need only to store the overquota flags in the first lnb for
* now, once we support multiple objects BRW, this code needs be
* revised. */
- if (flags & QUOTA_FL_OVER_USRQUOTA)
+ if (local_flags & QUOTA_FL_OVER_USRQUOTA)
lnb[0].lnb_flags |= OBD_BRW_OVER_USRQUOTA;
- if (flags & QUOTA_FL_OVER_GRPQUOTA)
+ if (local_flags & QUOTA_FL_OVER_GRPQUOTA)
lnb[0].lnb_flags |= OBD_BRW_OVER_GRPQUOTA;
- if (flags & QUOTA_FL_OVER_PRJQUOTA)
+ if (local_flags & QUOTA_FL_OVER_PRJQUOTA)
lnb[0].lnb_flags |= OBD_BRW_OVER_PRJQUOTA;
if (rc == 0)
*/
int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh,
struct lquota_id_info *qi, struct osd_object *obj,
- bool enforce, int *flags)
+ bool enforce, enum osd_quota_local_flags *local_flags)
{
struct osd_device *dev;
struct qsd_instance *qsd;
/* check quota */
if (enforce)
- rc = qsd_op_begin(env, qsd, oh->ot_quota_trans, qi, flags);
+ rc = qsd_op_begin(env, qsd, oh->ot_quota_trans, qi,
+ local_flags);
RETURN(rc);
}
*/
int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid,
__u32 projid, long long space, struct osd_thandle *oh,
- struct osd_object *obj, int *flags,
+ struct osd_object *obj,
+ enum osd_quota_local_flags *local_flags,
enum osd_qid_declare_flags osd_qid_declare_flags)
{
struct osd_thread_info *info = osd_oti_get(env);
qi->lqi_type = USRQUOTA;
qi->lqi_space = space;
qi->lqi_is_blk = !!(osd_qid_declare_flags & OSD_QID_BLK);
- rcu = osd_declare_qid(env, oh, qi, obj, true, flags);
+ rcu = osd_declare_qid(env, oh, qi, obj, true, local_flags);
if (force && (rcu == -EDQUOT || rcu == -EINPROGRESS))
/* ignore EDQUOT & EINPROGRESS when changes are done by root */
* in. See osd_declare_write_commit().
* When force is set to true, we also want to proceed with the gid
*/
- if (rcu && (rcu != -EDQUOT || flags == NULL))
+ if (rcu && (rcu != -EDQUOT || local_flags == NULL))
RETURN(rcu);
/* and now group quota */
qi->lqi_id.qid_gid = gid;
qi->lqi_type = GRPQUOTA;
- rcg = osd_declare_qid(env, oh, qi, obj, true, flags);
+ rcg = osd_declare_qid(env, oh, qi, obj, true, local_flags);
if (force && (rcg == -EDQUOT || rcg == -EINPROGRESS))
/* as before, ignore EDQUOT & EINPROGRESS for root */
rcg = 0;
#ifdef HAVE_PROJECT_QUOTA
- if (rcg && (rcg != -EDQUOT || flags == NULL))
+ if (rcg && (rcg != -EDQUOT || local_flags == NULL))
RETURN(rcg);
/* and now project quota */
qi->lqi_id.qid_projid = projid;
qi->lqi_type = PRJQUOTA;
- rcp = osd_declare_qid(env, oh, qi, obj, true, flags);
+ rcp = osd_declare_qid(env, oh, qi, obj, true, local_flags);
if (force && (rcp == -EDQUOT || rcp == -EINPROGRESS)) {
- CDEBUG(D_ERROR, "force to ignore quota flags =%d\n", *flags);
+ CDEBUG(D_QUOTA, "forced to ignore quota flags = %#x\n",
+ local_flags ? *local_flags : -1);
/* as before, ignore EDQUOT & EINPROGRESS for root */
rcp = 0;
}
extern struct dt_index_operations osd_dir_ops;
int osd_declare_quota(const struct lu_env *env, struct osd_device *osd,
qid_t uid, qid_t gid, qid_t projid, long long space,
- struct osd_thandle *oh, int *flags,
+ struct osd_thandle *oh,
+ enum osd_quota_local_flags *local_flags,
enum osd_qid_declare_flags osd_qid_declare_flags);
uint64_t osd_objs_count_estimate(uint64_t refdbytes, uint64_t usedobjs,
uint64_t nrblocks, uint64_t est_maxblockshift);
uint64_t offset = 0;
uint32_t size = 0;
uint32_t blksz = obj->oo_dn->dn_datablksz;
- int i, rc, flags = 0;
+ int i, rc;
bool synced = false;
long long space = 0;
struct page *last_page = NULL;
unsigned long discont_pages = 0;
+ enum osd_quota_local_flags local_flags = 0;
enum osd_qid_declare_flags declare_flags = OSD_QID_BLK;
ENTRY;
/* acquire quota space if needed */
rc = osd_declare_quota(env, osd, obj->oo_attr.la_uid,
obj->oo_attr.la_gid, obj->oo_attr.la_projid,
- space, oh, &flags, declare_flags);
+ space, oh, &local_flags, declare_flags);
- if (!synced && rc == -EDQUOT && (flags & QUOTA_FL_SYNC) != 0) {
+ if (!synced && rc == -EDQUOT &&
+ (local_flags & QUOTA_FL_SYNC) != 0) {
dt_sync(env, th->th_dev);
synced = true;
CDEBUG(D_QUOTA, "retry after sync\n");
- flags = 0;
+ local_flags = 0;
goto retry;
}
/* we need only to store the overquota flags in the first lnb for
* now, once we support multiple objects BRW, this code needs be
* revised. */
- if (flags & QUOTA_FL_OVER_USRQUOTA)
+ if (local_flags & QUOTA_FL_OVER_USRQUOTA)
lnb[0].lnb_flags |= OBD_BRW_OVER_USRQUOTA;
- if (flags & QUOTA_FL_OVER_GRPQUOTA)
+ if (local_flags & QUOTA_FL_OVER_GRPQUOTA)
lnb[0].lnb_flags |= OBD_BRW_OVER_GRPQUOTA;
#ifdef ZFS_PROJINHERIT
- if (flags & QUOTA_FL_OVER_PRJQUOTA)
+ if (local_flags & QUOTA_FL_OVER_PRJQUOTA)
lnb[0].lnb_flags |= OBD_BRW_OVER_PRJQUOTA;
#endif
*/
int osd_declare_quota(const struct lu_env *env, struct osd_device *osd,
qid_t uid, qid_t gid, qid_t projid, long long space,
- struct osd_thandle *oh, int *flags,
+ struct osd_thandle *oh,
+ enum osd_quota_local_flags *local_flags,
enum osd_qid_declare_flags osd_qid_declare_flags)
{
struct osd_thread_info *info = osd_oti_get(env);
qi->lqi_type = USRQUOTA;
qi->lqi_space = space;
qi->lqi_is_blk = !!(osd_qid_declare_flags & OSD_QID_BLK);
- rcu = qsd_op_begin(env, qsd, &oh->ot_quota_trans, qi, flags);
+ rcu = qsd_op_begin(env, qsd, &oh->ot_quota_trans, qi, local_flags);
if (force && (rcu == -EDQUOT || rcu == -EINPROGRESS))
/* ignore EDQUOT & EINPROGRESS when changes are done by root */
rcu = 0;
* for group id. This is only for commit write, which has @flags passed
* in. See osd_declare_write_commit().
* When force is set to true, we also want to proceed with the gid */
- if (rcu && (rcu != -EDQUOT || flags == NULL))
+ if (rcu && (rcu != -EDQUOT || local_flags == NULL))
RETURN(rcu);
/* and now group quota */
qi->lqi_id.qid_gid = gid;
qi->lqi_type = GRPQUOTA;
- rcg = qsd_op_begin(env, qsd, &oh->ot_quota_trans, qi, flags);
+ rcg = qsd_op_begin(env, qsd, &oh->ot_quota_trans, qi, local_flags);
if (force && (rcg == -EDQUOT || rcg == -EINPROGRESS))
/* as before, ignore EDQUOT & EINPROGRESS for root */
rcg = 0;
#ifdef ZFS_PROJINHERIT
- if (rcg && (rcg != -EDQUOT || flags == NULL))
+ if (rcg && (rcg != -EDQUOT || local_flags == NULL))
RETURN(rcg);
/* for project quota */
if (osd->od_projectused_dn) {
qi->lqi_id.qid_projid = projid;
qi->lqi_type = PRJQUOTA;
- rcp = qsd_op_begin(env, qsd, &oh->ot_quota_trans, qi, flags);
+ rcp = qsd_op_begin(env, qsd, &oh->ot_quota_trans, qi,
+ local_flags);
if (force && (rcp == -EDQUOT || rcp == -EINPROGRESS))
rcp = 0;
}
#define LQUOTA_LEAST_QUNIT(type) \
(type == LQUOTA_RES_MD ? (1 << 10) : toqb(OFD_MAX_BRW_SIZE))
-static inline int lquota_over_fl(int qtype)
+static inline enum osd_quota_local_flags lquota_over_fl(int qtype)
{
switch (qtype) {
case USRQUOTA:
*/
static int qsd_op_begin0(const struct lu_env *env, struct qsd_qtype_info *qqi,
struct lquota_id_info *qid, long long space,
- int *flags)
+ enum osd_quota_local_flags *local_flags)
{
struct lquota_entry *lqe;
struct l_wait_info lwi;
- int qtype_flag = 0;
+ enum osd_quota_local_flags qtype_flag = 0;
int rc, ret = -EINPROGRESS;
ENTRY;
* quota space. That said, we still want to perform space
* adjustments in qsd_op_end, so we return here, but with
* a reference on the lqe */
- if (flags != NULL) {
+ if (local_flags != NULL) {
rc = qsd_refresh_usage(env, lqe);
GOTO(out_flags, rc);
}
lqe_write_lock(lqe);
lqe->lqe_waiting_write -= space;
- if (flags && lqe->lqe_pending_write != 0)
+ if (local_flags && lqe->lqe_pending_write != 0)
/* Inform OSD layer that there are pending writes.
* It might want to retry after a sync if appropriate */
- *flags |= QUOTA_FL_SYNC;
+ *local_flags |= QUOTA_FL_SYNC;
lqe_write_unlock(lqe);
/* convert recoverable error into -EINPROGRESS, client will
}
}
- if (flags != NULL) {
+ if (local_flags != NULL) {
out_flags:
LASSERT(qid->lqi_is_blk);
if (rc != 0) {
- *flags |= lquota_over_fl(qqi->qqi_qtype);
+ *local_flags |= lquota_over_fl(qqi->qqi_qtype);
} else {
__u64 usage;
qtype_flag = lquota_over_fl(qqi->qqi_qtype);
/* if we should notify client to start sync write */
if (usage >= lqe->lqe_granted - lqe->lqe_pending_rel)
- *flags |= qtype_flag;
+ *local_flags |= qtype_flag;
else
- *flags &= ~qtype_flag;
+ *local_flags &= ~qtype_flag;
lqe_read_unlock(lqe);
}
}
*/
int qsd_op_begin(const struct lu_env *env, struct qsd_instance *qsd,
struct lquota_trans *trans, struct lquota_id_info *qi,
- int *flags)
+ enum osd_quota_local_flags *local_flags)
{
int i, rc;
bool found = false;
/* manage quota enforcement for this ID */
rc = qsd_op_begin0(env, qsd->qsd_type_array[qi->lqi_type],
- &trans->lqt_ids[i], qi->lqi_space, flags);
+ &trans->lqt_ids[i], qi->lqi_space, local_flags);
RETURN(rc);
}
EXPORT_SYMBOL(qsd_op_begin);