* GPL HEADER END
*/
/*
- * Copyright (c) 2012, 2014, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
* Use is subject to license terms.
*/
#include <linux/fs.h>
#include <linux/quota.h>
#include <linux/quotaops.h>
+#include <linux/sort.h>
#include <dt_object.h>
#include <lustre_fid.h>
#include <lustre_dlm.h>
struct lquota_acct_rec lqr_acct_rec;
};
+/* flags for inode/block quota accounting */
+enum osd_qid_declare_flags {
+ OSD_QID_INODE = BIT(0),
+ OSD_QID_BLK = BIT(1),
+ OSD_QID_FORCE = BIT(2),
+};
+
/* Index features supported by the global index objects
* Only used for migration purpose and should be removed once on-disk migration
* is no longer needed */
* 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 = BIT(0),
+ QUOTA_FL_OVER_GRPQUOTA = BIT(1),
+ QUOTA_FL_SYNC = BIT(2),
+ QUOTA_FL_OVER_PRJQUOTA = BIT(3),
+};
+
struct qsd_instance *qsd_init(const struct lu_env *, char *, struct dt_device *,
- struct proc_dir_entry *);
+ 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 *,
union lquota_id *, int);
+int qsd_transfer(const struct lu_env *env, struct qsd_instance *qsd,
+ struct lquota_trans *trans, unsigned int qtype,
+ u64 orig_id, u64 new_id, u64 bspace,
+ struct lquota_id_info *qi);
+int qsd_reserve_or_free_quota(const struct lu_env *env,
+ struct qsd_instance *qsd,
+ struct lquota_id_info *qi);
/*
* Quota information attached to a transaction
bool lqi_is_blk;
};
-/* Since we enforce only inode quota in meta pool (MDTs), and block quota in
- * data pool (OSTs), there are at most 4 quota ids being enforced in a single
- * transaction, which is chown transaction:
+/* With the DoM, both inode quota in meta pool and block quota in data pool
+ * will be enforced at MDT, there are at most 4 quota ids being enforced in
+ * a single transaction for inode and block quota, which is chown transaction:
* original uid and gid, new uid and gid.
*
* This value might need to be revised when directory quota is added. */
-#define QUOTA_MAX_TRANSIDS 4
+#define QUOTA_MAX_TRANSIDS 8
/* all qids involved in a single transaction */
struct lquota_trans {
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 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)
* on slave */
int lquotactl_slv(const struct lu_env *, struct dt_device *,
struct obd_quotactl *);
+
+static inline int quota_reserve_or_free(const struct lu_env *env,
+ struct qsd_instance *qsd,
+ struct lquota_id_info *qi,
+ enum quota_type type, __u64 uid,
+ __u64 gid, __s64 count, bool is_md)
+{
+ qi->lqi_type = type;
+ if (count > 0)
+ qi->lqi_space = toqb(count);
+ else
+ qi->lqi_space = -toqb(-count);
+
+ if (is_md)
+ qi->lqi_is_blk = false;
+ else
+ qi->lqi_is_blk = true;
+
+ qi->lqi_id.qid_uid = uid;
+ qi->lqi_id.qid_gid = gid;
+
+ return qsd_reserve_or_free_quota(env, qsd, qi);
+}
+
/** @} quota */
#endif /* _LUSTRE_QUOTA_H */