Whamcloud - gitweb
LU-15283 quota: deadlock between reint & lquota_wb
[fs/lustre-release.git] / lustre / include / lustre_quota.h
index 131b7d9..4b674d8 100644 (file)
@@ -21,7 +21,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2011, 2012, Intel, Inc.
+ * Copyright (c) 2012, 2017, Intel Corporation.
  * Use is subject to license terms.
  */
 
  *
  */
 
-#if defined(__linux__)
-#include <linux/lustre_quota.h>
-#elif defined(__APPLE__)
-#include <darwin/lustre_quota.h>
-#elif defined(__WINNT__)
-#include <winnt/lustre_quota.h>
-#error Unsupported operating system.
-#endif
-
+#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>
 
+#ifndef MAX_IQ_TIME
+#define MAX_IQ_TIME  604800     /* (7*24*60*60) 1 week */
+#endif
+
+#ifndef MAX_DQ_TIME
+#define MAX_DQ_TIME  604800     /* (7*24*60*60) 1 week */
+#endif
+
 struct lquota_id_info;
 struct lquota_trans;
 
@@ -57,6 +60,13 @@ union lquota_rec {
        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 */
@@ -161,22 +171,38 @@ struct qsd_instance;
  *                 operation is declared, qsd_op_end() should be called only
  *                 once for the whole transaction.
  *
- * - qsd_adjust_quota(): triggers pre-acquire/release if necessary.
+ * - qsd_op_adjust(): triggers pre-acquire/release if necessary.
  *
  * 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 *,
-                             cfs_proc_dir_entry_t *);
+                             struct proc_dir_entry *, bool is_md, bool excl);
 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_adjust_quota(const struct lu_env *, struct qsd_instance *,
-                     union lquota_id *, int);
+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
@@ -203,13 +229,13 @@ struct lquota_id_info {
        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 {
@@ -217,11 +243,6 @@ 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)
@@ -230,5 +251,29 @@ struct lquota_trans {
  * 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 */