-/* set inode quota limitation on a quota uid/gid */
-#define QI_SET (1 << 30)
-/* set block quota limitation on a quota uid/gid */
-#define QB_SET (1 << 31)
-
-#define QFILE_CHK 1
-#define QFILE_RD_INFO 2
-#define QFILE_WR_INFO 3
-#define QFILE_INIT_INFO 4
-#define QFILE_RD_DQUOT 5
-#define QFILE_WR_DQUOT 6
-#define QFILE_CONVERT 7
-
-/* admin quotafile operations */
-int lustre_check_quota_file(struct lustre_quota_info *lqi, int type);
-int lustre_read_quota_info(struct lustre_quota_info *lqi, int type);
-int lustre_write_quota_info(struct lustre_quota_info *lqi, int type);
-int lustre_read_dquot(struct lustre_dquot *dquot);
-int lustre_commit_dquot(struct lustre_dquot *dquot);
-int lustre_init_quota_info(struct lustre_quota_info *lqi, int type);
-int lustre_get_qids(struct file *file, struct inode *inode, int type,
- cfs_list_t *list);
-int lustre_quota_convert(struct lustre_quota_info *lqi, int type);
-
-typedef int (*dqacq_handler_t) (struct obd_device * obd, struct qunit_data * qd,
- int opc);
-
-/* user quota is turned on on filter */
-#define LQC_USRQUOTA_FLAG (1 << 0)
-/* group quota is turned on on filter */
-#define LQC_GRPQUOTA_FLAG (1 << 1)
-
-#define UGQUOTA2LQC(id) ((Q_TYPEMATCH(id, USRQUOTA) ? LQC_USRQUOTA_FLAG : 0) | \
- (Q_TYPEMATCH(id, GRPQUOTA) ? LQC_GRPQUOTA_FLAG : 0))
-
-struct lustre_quota_ctxt {
- /** superblock this applies to */
- struct super_block *lqc_sb;
- /** obd_device_target for obt_rwsem */
- struct obd_device_target *lqc_obt;
- /** import used to send dqacq/dqrel RPC */
- struct obd_import *lqc_import;
- /** dqacq/dqrel RPC handler, only for quota master */
- dqacq_handler_t lqc_handler;
- /** quota flags */
- unsigned long lqc_flags;
- /** @{ */
- unsigned long lqc_recovery:1, /** Doing recovery */
- lqc_switch_qs:1, /**
- * the function of change qunit size
- * 0:Off, 1:On
- */
- lqc_valid:1, /** this qctxt is valid or not */
- lqc_setup:1; /**
- * tell whether of not quota_type has
- * been processed, so that the master
- * knows when it can start processing
- * incoming acq/rel quota requests
- */
- /** }@ */
- /**
- * original unit size of file quota and
- * upper limitation for adjust file qunit
- */
- unsigned long lqc_iunit_sz;
- /**
- * Trigger dqacq when available file
- * quota less than this value, trigger
- * dqrel when available file quota
- * more than this value + 1 iunit
- */
- unsigned long lqc_itune_sz;
- /**
- * original unit size of block quota and
- * upper limitation for adjust block qunit
- */
- unsigned long lqc_bunit_sz;
- /** See comment of lqc_itune_sz */
- unsigned long lqc_btune_sz;
- /** all lustre_qunit_size structures */
- cfs_hash_t *lqc_lqs_hash;
-
- /** @{ */
- /**
- * the values below are relative to how master change its qunit sizes
- */
- /**
- * this affects the boundary of
- * shrinking and enlarging qunit size. default=4
- */
- unsigned long lqc_cqs_boundary_factor;
- /** the least value of block qunit */
- unsigned long lqc_cqs_least_bunit;
- /** the least value of inode qunit */
- unsigned long lqc_cqs_least_iunit;
- /**
- * when enlarging, qunit size will
- * mutilple it; when shrinking,
- * qunit size will divide it
- */
- unsigned long lqc_cqs_qs_factor;
- /**
- * avoid ping-pong effect of
- * adjusting qunit size. How many
- * seconds must be waited between
- * enlarging and shinking qunit
- */
- /** }@ */
- int lqc_switch_seconds;
- /**
- * when blk qunit reaches this value,
- * later write reqs from client should be sync b=16642
- */
- int lqc_sync_blk;
- /** guard lqc_imp_valid now */
- cfs_spinlock_t lqc_lock;
- /**
- * when mds isn't connected, threads
- * on osts who send the quota reqs
- * with wait==1 will be put here b=14840
- */
- cfs_waitq_t lqc_wait_for_qmaster;
- struct proc_dir_entry *lqc_proc_dir;
- /** lquota statistics */
- struct lprocfs_stats *lqc_stats;
- /** the number of used hashed lqs */
- cfs_atomic_t lqc_lqs;
- /** no lqs are in use */
- cfs_waitq_t lqc_lqs_waitq;
-};
-
-#define QUOTA_MASTER_READY(qctxt) (qctxt)->lqc_setup = 1
-#define QUOTA_MASTER_UNREADY(qctxt) (qctxt)->lqc_setup = 0
-
-struct lustre_qunit_size {
- cfs_hlist_node_t lqs_hash; /** the hash entry */
- unsigned int lqs_id; /** id of user/group */
- unsigned long lqs_flags; /** 31st bit is QB_SET, 30th bit is QI_SET
- * other bits are same as LQUOTA_FLAGS_*
- */
- unsigned long lqs_iunit_sz; /** Unit size of file quota currently */
- /**
- * Trigger dqacq when available file quota
- * less than this value, trigger dqrel
- * when more than this value + 1 iunit
- */
- unsigned long lqs_itune_sz;
- unsigned long lqs_bunit_sz; /** Unit size of block quota currently */
- unsigned long lqs_btune_sz; /** See comment of lqs itune sz */
- /** the blocks reached ost and don't finish */
- unsigned long lqs_bwrite_pending;
- /** the inodes reached mds and don't finish */
- unsigned long lqs_iwrite_pending;
- /** when inodes are allocated/released, this value will record it */
- long long lqs_ino_rec;
- /** when blocks are allocated/released, this value will record it */
- long long lqs_blk_rec;
- cfs_atomic_t lqs_refcount;
- cfs_time_t lqs_last_bshrink; /** time of last block shrink */
- cfs_time_t lqs_last_ishrink; /** time of last inode shrink */
- cfs_spinlock_t lqs_lock;
- unsigned long long lqs_key; /** hash key */
- struct lustre_quota_ctxt *lqs_ctxt; /** quota ctxt */
-};
-
-#define LQS_IS_GRP(lqs) ((lqs)->lqs_flags & LQUOTA_FLAGS_GRP)
-#define LQS_IS_ADJBLK(lqs) ((lqs)->lqs_flags & LQUOTA_FLAGS_ADJBLK)
-#define LQS_IS_ADJINO(lqs) ((lqs)->lqs_flags & LQUOTA_FLAGS_ADJINO)
-#define LQS_IS_RECOVERY(lqs) ((lqs)->lqs_flags & LQUOTA_FLAGS_RECOVERY)
-#define LQS_IS_SETQUOTA(lqs) ((lqs)->lqs_flags & LQUOTA_FLAGS_SETQUOTA)
-
-#define LQS_SET_GRP(lqs) ((lqs)->lqs_flags |= LQUOTA_FLAGS_GRP)
-#define LQS_SET_ADJBLK(lqs) ((lqs)->lqs_flags |= LQUOTA_FLAGS_ADJBLK)
-#define LQS_SET_ADJINO(lqs) ((lqs)->lqs_flags |= LQUOTA_FLAGS_ADJINO)
-#define LQS_SET_RECOVERY(lqs) ((lqs)->lqs_flags |= LQUOTA_FLAGS_RECOVERY)
-#define LQS_SET_SETQUOTA(lqs) ((lqs)->lqs_flags |= LQUOTA_FLAGS_SETQUOTA)
-
-#define LQS_CLEAR_RECOVERY(lqs) ((lqs)->lqs_flags &= ~LQUOTA_FLAGS_RECOVERY)
-#define LQS_CLEAR_SETQUOTA(lqs) ((lqs)->lqs_flags &= ~LQUOTA_FLAGS_SETQUOTA)
-
-/* In the hash for lustre_qunit_size, the key is decided by
- * grp_or_usr and uid/gid, in here, I combine these two values,
- * which will make comparing easier and more efficient */
-#define LQS_KEY(is_grp, id) ((is_grp ? 1ULL << 32: 0) + id)
-#define LQS_KEY_ID(key) (key & 0xffffffff)
-#define LQS_KEY_GRP(key) (key >> 32)
-
-static inline void lqs_getref(struct lustre_qunit_size *lqs)
-{
- int count = cfs_atomic_inc_return(&lqs->lqs_refcount);