* GPL HEADER END
*/
/*
- * Copyright (c) 2012 Whamcloud, Inc.
+ * Copyright (c) 2012, 2014, Intel Corporation.
* Use is subject to license terms.
*/
#include <obd.h>
-#include <lquota.h>
+#include <lustre_quota.h>
#ifndef _LQUOTA_INTERNAL_H
#define _LQUOTA_INTERNAL_H
#define QTYPE_NAME(qtype) ((qtype) == USRQUOTA ? "usr" : "grp")
+#define RES_NAME(res) ((res) == LQUOTA_RES_MD ? "md" : "dt")
#define QIF_IFLAGS (QIF_INODES | QIF_ITIME | QIF_ILIMITS)
#define QIF_BFLAGS (QIF_SPACE | QIF_BTIME | QIF_BLIMITS)
/* r/w semaphore used to protect concurrent access to the quota
* parameters which are stored on disk */
- cfs_rw_semaphore_t lme_sem;
+ struct rw_semaphore lme_sem;
/* quota space that may be released after glimpse */
__u64 lme_may_rel;
unsigned int lse_pending_req;
/* rw spinlock protecting in-memory counters (i.e. lse_pending*) */
- cfs_rwlock_t lse_lock;
+ rwlock_t lse_lock;
/* waiter for pending request done */
- cfs_waitq_t lse_waiters;
+ wait_queue_head_t lse_waiters;
/* hint on current on-disk usage, in inodes or kbytes */
__u64 lse_usage;
/* time to trigger quota adjust */
__u64 lse_adjust_time;
+
+ /* return code of latest acquire RPC */
+ int lse_acq_rc;
+
+ /* when latest acquire RPC completed */
+ __u64 lse_acq_time;
+
+ /* when latest edquot set */
+ __u64 lse_edquot_time;
};
/* In-memory entry for each enforced quota id
* A lquota_entry structure belong to a single lquota_site */
struct lquota_entry {
/* link to site hash table */
- cfs_hlist_node_t lqe_hash;
+ struct hlist_node lqe_hash;
/* quota identifier associated with this entry */
union lquota_id lqe_id;
struct lquota_site *lqe_site;
/* reference counter */
- cfs_atomic_t lqe_ref;
+ atomic_t lqe_ref;
/* linked to list of lqes which:
* - need quota space adjustment on slave
* - need glimpse to be sent on master */
- cfs_list_t lqe_link;
+ struct list_head lqe_link;
/* current quota settings/usage of this ID */
__u64 lqe_granted; /* granted limit, inodes or kbytes */
* present. */
struct lquota_site {
/* Hash table storing lquota_entry structures */
- cfs_hash_t *lqs_hash;
+ struct cfs_hash *lqs_hash;
/* Quota type, either user or group. */
int lqs_qtype;
#define lqe_usage u.se.lse_usage
#define lqe_adjust_time u.se.lse_adjust_time
#define lqe_lockh u.se.lse_lockh
+#define lqe_acq_rc u.se.lse_acq_rc
+#define lqe_acq_time u.se.lse_acq_time
+#define lqe_edquot_time u.se.lse_edquot_time
#define LQUOTA_BUMP_VER 0x1
#define LQUOTA_SET_VER 0x2
+extern struct kmem_cache *lqe_kmem;
+
/* helper routine to get/put reference on lquota_entry */
static inline void lqe_getref(struct lquota_entry *lqe)
{
- cfs_atomic_inc(&lqe->lqe_ref);
+ LASSERT(lqe != NULL);
+ atomic_inc(&lqe->lqe_ref);
}
static inline void lqe_putref(struct lquota_entry *lqe)
{
+ LASSERT(lqe != NULL);
LASSERT(atomic_read(&lqe->lqe_ref) > 0);
if (atomic_dec_and_test(&lqe->lqe_ref))
- OBD_FREE_PTR(lqe);
+ OBD_SLAB_FREE_PTR(lqe, lqe_kmem);
}
static inline int lqe_is_master(struct lquota_entry *lqe)
static inline void lqe_write_lock(struct lquota_entry *lqe)
{
if (lqe_is_master(lqe))
- cfs_down_write(&lqe->lqe_sem);
+ down_write(&lqe->lqe_sem);
else
- cfs_write_lock(&lqe->lqe_lock);
+ write_lock(&lqe->lqe_lock);
}
static inline void lqe_write_unlock(struct lquota_entry *lqe)
{
if (lqe_is_master(lqe))
- cfs_up_write(&lqe->lqe_sem);
+ up_write(&lqe->lqe_sem);
else
- cfs_write_unlock(&lqe->lqe_lock);
+ write_unlock(&lqe->lqe_lock);
}
static inline void lqe_read_lock(struct lquota_entry *lqe)
{
if (lqe_is_master(lqe))
- cfs_down_read(&lqe->lqe_sem);
+ down_read(&lqe->lqe_sem);
else
- cfs_read_lock(&lqe->lqe_lock);
+ read_lock(&lqe->lqe_lock);
}
static inline void lqe_read_unlock(struct lquota_entry *lqe)
{
if (lqe_is_master(lqe))
- cfs_up_read(&lqe->lqe_sem);
+ up_read(&lqe->lqe_sem);
else
- cfs_read_unlock(&lqe->lqe_lock);
+ read_unlock(&lqe->lqe_lock);
}
+/*
+ * Helper functions & prototypes
+ */
+
+/* minimum qunit size, 1K inode for metadata pool and 1MB for data pool */
+#define LQUOTA_LEAST_QUNIT(type) \
+ (type == LQUOTA_RES_MD ? (1 << 10) : toqb(OFD_MAX_BRW_SIZE))
+
+#define LQUOTA_OVER_FL(type) \
+ (type == USRQUOTA ? QUOTA_FL_OVER_USRQUOTA : QUOTA_FL_OVER_GRPQUOTA)
+
/* Common data shared by quota-level handlers. This is allocated per-thread to
* reduce stack consumption */
struct lquota_thread_info {
return info;
}
+#define req_is_acq(flags) ((flags & QUOTA_DQACQ_FL_ACQ) != 0)
+#define req_is_preacq(flags) ((flags & QUOTA_DQACQ_FL_PREACQ) != 0)
+#define req_is_rel(flags) ((flags & QUOTA_DQACQ_FL_REL) != 0)
+#define req_has_rep(flags) ((flags & QUOTA_DQACQ_FL_REPORT) != 0)
+
/* debugging macros */
#ifdef LIBCFS_DEBUG
#define lquota_lqe_debug(msgdata, mask, cdls, lqe, fmt, a...) do { \
__attribute__ ((format (printf, 3, 4)));
#define LQUOTA_DEBUG_LIMIT(mask, lqe, fmt, a...) do { \
- static cfs_debug_limit_state_t _lquota_cdls; \
+ static struct cfs_debug_limit_state _lquota_cdls; \
LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, &_lquota_cdls); \
lquota_lqe_debug(&msgdata, mask, &_lquota_cdls, lqe, "$$$ "fmt" ", \
##a); \
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 *);
+int lquota_extract_fid(const struct lu_fid *, int *, int *, int *);
const struct dt_index_features *glb_idx_feature(struct lu_fid *);
/* lquota_entry.c */
struct lu_fid *, lquota_disk_slv_cb_t, void *);
struct dt_object *lquota_disk_slv_find(const struct lu_env *,
struct dt_device *, struct dt_object *,
- struct lu_fid *, struct obd_uuid *);
+ const struct lu_fid *,
+ struct obd_uuid *);
int lquota_disk_read(const struct lu_env *, struct dt_object *,
union lquota_id *, struct dt_rec *);
int lquota_disk_declare_write(const struct lu_env *, struct thandle *,
__u32, __u64 *);
int lquota_disk_update_ver(const struct lu_env *, struct dt_device *,
struct dt_object *, __u64);
+int lquota_disk_write_glb(const struct lu_env *, struct dt_object *, __u64,
+ struct lquota_glb_rec *);
+
+/* qmt_dev.c */
+int qmt_glb_init(void);
+void qmt_glb_fini(void);
/* lproc_quota.c */
extern struct file_operations lprocfs_quota_seq_fops;