18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * quota.h for OCFS2
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * On disk quota structures for local and global quota file, in-memory
68c2ecf20Sopenharmony_ci * structures.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef _OCFS2_QUOTA_H
118c2ecf20Sopenharmony_ci#define _OCFS2_QUOTA_H
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/types.h>
148c2ecf20Sopenharmony_ci#include <linux/slab.h>
158c2ecf20Sopenharmony_ci#include <linux/quota.h>
168c2ecf20Sopenharmony_ci#include <linux/list.h>
178c2ecf20Sopenharmony_ci#include <linux/dqblk_qtree.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#include "ocfs2.h"
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/* Number of quota types we support */
228c2ecf20Sopenharmony_ci#define OCFS2_MAXQUOTAS 2
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/*
258c2ecf20Sopenharmony_ci * In-memory structures
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_cistruct ocfs2_dquot {
288c2ecf20Sopenharmony_ci	struct dquot dq_dquot;	/* Generic VFS dquot */
298c2ecf20Sopenharmony_ci	loff_t dq_local_off;	/* Offset in the local quota file */
308c2ecf20Sopenharmony_ci	u64 dq_local_phys_blk;	/* Physical block carrying quota structure */
318c2ecf20Sopenharmony_ci	struct ocfs2_quota_chunk *dq_chunk;	/* Chunk dquot is in */
328c2ecf20Sopenharmony_ci	unsigned int dq_use_count;	/* Number of nodes having reference to this entry in global quota file */
338c2ecf20Sopenharmony_ci	s64 dq_origspace;	/* Last globally synced space usage */
348c2ecf20Sopenharmony_ci	s64 dq_originodes;	/* Last globally synced inode usage */
358c2ecf20Sopenharmony_ci	struct llist_node list;	/* Member of list of dquots to drop */
368c2ecf20Sopenharmony_ci};
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci/* Description of one chunk to recover in memory */
398c2ecf20Sopenharmony_cistruct ocfs2_recovery_chunk {
408c2ecf20Sopenharmony_ci	struct list_head rc_list;	/* List of chunks */
418c2ecf20Sopenharmony_ci	int rc_chunk;			/* Chunk number */
428c2ecf20Sopenharmony_ci	unsigned long *rc_bitmap;	/* Bitmap of entries to recover */
438c2ecf20Sopenharmony_ci};
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistruct ocfs2_quota_recovery {
468c2ecf20Sopenharmony_ci	struct list_head r_list[OCFS2_MAXQUOTAS];	/* List of chunks to recover */
478c2ecf20Sopenharmony_ci};
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/* In-memory structure with quota header information */
508c2ecf20Sopenharmony_cistruct ocfs2_mem_dqinfo {
518c2ecf20Sopenharmony_ci	unsigned int dqi_type;		/* Quota type this structure describes */
528c2ecf20Sopenharmony_ci	unsigned int dqi_flags;		/* Flags OLQF_* */
538c2ecf20Sopenharmony_ci	unsigned int dqi_chunks;	/* Number of chunks in local quota file */
548c2ecf20Sopenharmony_ci	unsigned int dqi_blocks;	/* Number of blocks allocated for local quota file */
558c2ecf20Sopenharmony_ci	unsigned int dqi_syncms;	/* How often should we sync with other nodes */
568c2ecf20Sopenharmony_ci	struct list_head dqi_chunk;	/* List of chunks */
578c2ecf20Sopenharmony_ci	struct inode *dqi_gqinode;	/* Global quota file inode */
588c2ecf20Sopenharmony_ci	struct ocfs2_lock_res dqi_gqlock;	/* Lock protecting quota information structure */
598c2ecf20Sopenharmony_ci	struct buffer_head *dqi_gqi_bh;	/* Buffer head with global quota file inode - set only if inode lock is obtained */
608c2ecf20Sopenharmony_ci	int dqi_gqi_count;		/* Number of holders of dqi_gqi_bh */
618c2ecf20Sopenharmony_ci	u64 dqi_giblk;			/* Number of block with global information header */
628c2ecf20Sopenharmony_ci	struct buffer_head *dqi_lqi_bh;	/* Buffer head with local quota file inode */
638c2ecf20Sopenharmony_ci	struct buffer_head *dqi_libh;	/* Buffer with local information header */
648c2ecf20Sopenharmony_ci	struct qtree_mem_dqinfo dqi_gi;	/* Info about global file */
658c2ecf20Sopenharmony_ci	struct delayed_work dqi_sync_work;	/* Work for syncing dquots */
668c2ecf20Sopenharmony_ci	struct ocfs2_quota_recovery *dqi_rec;	/* Pointer to recovery
678c2ecf20Sopenharmony_ci						 * information, in case we
688c2ecf20Sopenharmony_ci						 * enable quotas on file
698c2ecf20Sopenharmony_ci						 * needing it */
708c2ecf20Sopenharmony_ci};
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic inline struct ocfs2_dquot *OCFS2_DQUOT(struct dquot *dquot)
738c2ecf20Sopenharmony_ci{
748c2ecf20Sopenharmony_ci	return container_of(dquot, struct ocfs2_dquot, dq_dquot);
758c2ecf20Sopenharmony_ci}
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_cistruct ocfs2_quota_chunk {
788c2ecf20Sopenharmony_ci	struct list_head qc_chunk;	/* List of quotafile chunks */
798c2ecf20Sopenharmony_ci	int qc_num;			/* Number of quota chunk */
808c2ecf20Sopenharmony_ci	struct buffer_head *qc_headerbh;	/* Buffer head with chunk header */
818c2ecf20Sopenharmony_ci};
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ciextern struct kmem_cache *ocfs2_dquot_cachep;
848c2ecf20Sopenharmony_ciextern struct kmem_cache *ocfs2_qf_chunk_cachep;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ciextern const struct qtree_fmt_operations ocfs2_global_ops;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistruct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
898c2ecf20Sopenharmony_ci				struct ocfs2_super *osb, int slot_num);
908c2ecf20Sopenharmony_ciint ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
918c2ecf20Sopenharmony_ci				struct ocfs2_quota_recovery *rec,
928c2ecf20Sopenharmony_ci				int slot_num);
938c2ecf20Sopenharmony_civoid ocfs2_free_quota_recovery(struct ocfs2_quota_recovery *rec);
948c2ecf20Sopenharmony_cissize_t ocfs2_quota_read(struct super_block *sb, int type, char *data,
958c2ecf20Sopenharmony_ci			 size_t len, loff_t off);
968c2ecf20Sopenharmony_cissize_t ocfs2_quota_write(struct super_block *sb, int type,
978c2ecf20Sopenharmony_ci			  const char *data, size_t len, loff_t off);
988c2ecf20Sopenharmony_ciint ocfs2_global_read_info(struct super_block *sb, int type);
998c2ecf20Sopenharmony_ciint ocfs2_global_write_info(struct super_block *sb, int type);
1008c2ecf20Sopenharmony_ciint ocfs2_global_read_dquot(struct dquot *dquot);
1018c2ecf20Sopenharmony_ciint __ocfs2_sync_dquot(struct dquot *dquot, int freeing);
1028c2ecf20Sopenharmony_cistatic inline int ocfs2_sync_dquot(struct dquot *dquot)
1038c2ecf20Sopenharmony_ci{
1048c2ecf20Sopenharmony_ci	return __ocfs2_sync_dquot(dquot, 0);
1058c2ecf20Sopenharmony_ci}
1068c2ecf20Sopenharmony_cistatic inline int ocfs2_global_release_dquot(struct dquot *dquot)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci	return __ocfs2_sync_dquot(dquot, 1);
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ciint ocfs2_lock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex);
1128c2ecf20Sopenharmony_civoid ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex);
1138c2ecf20Sopenharmony_ciint ocfs2_validate_quota_block(struct super_block *sb, struct buffer_head *bh);
1148c2ecf20Sopenharmony_ciint ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block,
1158c2ecf20Sopenharmony_ci				struct buffer_head **bh);
1168c2ecf20Sopenharmony_ciint ocfs2_create_local_dquot(struct dquot *dquot);
1178c2ecf20Sopenharmony_ciint ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot);
1188c2ecf20Sopenharmony_ciint ocfs2_local_write_dquot(struct dquot *dquot);
1198c2ecf20Sopenharmony_civoid ocfs2_drop_dquot_refs(struct work_struct *work);
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ciextern const struct dquot_operations ocfs2_quota_operations;
1228c2ecf20Sopenharmony_ciextern struct quota_format_type ocfs2_quota_format;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci#endif /* _OCFS2_QUOTA_H */
125