• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** quotaio.h
2  *
3  * Interface to the quota library.
4  *
5  * The quota library provides interface for creating and updating the quota
6  * files and the ext4 superblock fields. It supports the new VFS_V1 quota
7  * format. The quota library also provides support for keeping track of quotas
8  * in memory.
9  *
10  * Aditya Kali <adityakali@google.com>
11  * Header of IO operations for quota utilities
12  *
13  * Jan Kara <jack@suse.cz>
14  *
15  * Hyojun Kim <hyojun@google.com> - Ported to f2fs-tools
16  */
17 
18 #ifndef GUARD_QUOTAIO_H
19 #define GUARD_QUOTAIO_H
20 
21 #include <limits.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 
25 #include "dict.h"
26 #include "f2fs_fs.h"
27 #include "f2fs.h"
28 #include "node.h"
29 #include "fsck.h"
30 
31 #include "dqblk_v2.h"
32 
33 typedef int64_t qsize_t;	/* Type in which we store size limitations */
34 typedef int32_t f2fs_ino_t;
35 typedef int errcode_t;
36 
37 enum quota_type {
38 	USRQUOTA = 0,
39 	GRPQUOTA = 1,
40 	PRJQUOTA = 2,
41 	MAXQUOTAS = 3,
42 };
43 
44 #if MAXQUOTAS > 32
45 #error "cannot have more than 32 quota types to fit in qtype_bits"
46 #endif
47 
48 enum qf_szchk_type_t {
49 	QF_SZCHK_NONE,
50 	QF_SZCHK_ERR,
51 	QF_SZCHK_INLINE,
52 	QF_SZCHK_REGFILE,
53 };
54 
55 extern int cur_qtype;
56 extern u32 qf_last_blkofs[];
57 extern enum qf_szchk_type_t qf_szchk_type[];
58 extern u64 qf_maxsize[];
59 
60 #define QUOTA_USR_BIT (1 << USRQUOTA)
61 #define QUOTA_GRP_BIT (1 << GRPQUOTA)
62 #define QUOTA_PRJ_BIT (1 << PRJQUOTA)
63 #define QUOTA_ALL_BIT (QUOTA_USR_BIT | QUOTA_GRP_BIT | QUOTA_PRJ_BIT)
64 
65 typedef struct quota_ctx *quota_ctx_t;
66 
67 struct quota_ctx {
68 	struct f2fs_sb_info *sbi;
69 	struct dict_t *quota_dict[MAXQUOTAS];
70 	struct quota_handle *quota_file[MAXQUOTAS];
71 	struct dict_t linked_inode_dict;
72 };
73 
74 /*
75  * Definitions of magics and versions of current quota files
76  */
77 #define INITQMAGICS {\
78 	0xd9c01f11,	/* USRQUOTA */\
79 	0xd9c01927,	/* GRPQUOTA */\
80 	0xd9c03f14	/* PRJQUOTA */\
81 }
82 
83 /* Size of blocks in which are counted size limits in generic utility parts */
84 #define QUOTABLOCK_BITS 10
85 #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
86 #define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
87 
88 /* Quota format type IDs */
89 #define	QFMT_VFS_OLD 1
90 #define	QFMT_VFS_V0 2
91 #define	QFMT_VFS_V1 4
92 
93 /*
94  * The following constants define the default amount of time given a user
95  * before the soft limits are treated as hard limits (usually resulting
96  * in an allocation failure). The timer is started when the user crosses
97  * their soft limit, it is reset when they go below their soft limit.
98  */
99 #define MAX_IQ_TIME  604800	/* (7*24*60*60) 1 week */
100 #define MAX_DQ_TIME  604800	/* (7*24*60*60) 1 week */
101 
102 #define IOFL_INFODIRTY	0x01	/* Did info change? */
103 
104 struct quotafile_ops;
105 
106 /* Generic information about quotafile */
107 struct util_dqinfo {
108 	time_t dqi_bgrace;	/* Block grace time for given quotafile */
109 	time_t dqi_igrace;	/* Inode grace time for given quotafile */
110 	union {
111 		struct v2_mem_dqinfo v2_mdqi;
112 	} u;			/* Format specific info about quotafile */
113 };
114 
115 struct quota_file {
116 	struct f2fs_sb_info *sbi;
117 	f2fs_ino_t ino;
118 	int64_t filesize;
119 };
120 
121 /* Structure for one opened quota file */
122 struct quota_handle {
123 	enum quota_type qh_type;	/* Type of quotafile */
124 	int qh_fmt;		/* Quotafile format */
125 	int qh_file_flags;
126 	int qh_io_flags;	/* IO flags for file */
127 	struct quota_file qh_qf;
128 	unsigned int (*read)(struct quota_file *qf, long offset,
129 			 void *buf, unsigned int size);
130 	unsigned int (*write)(struct quota_file *qf, long offset,
131 			  void *buf, unsigned int size);
132 	struct quotafile_ops *qh_ops;	/* Operations on quotafile */
133 	struct util_dqinfo qh_info;	/* Generic quotafile info */
134 };
135 
136 /* Utility quota block */
137 struct util_dqblk {
138 	qsize_t dqb_ihardlimit;
139 	qsize_t dqb_isoftlimit;
140 	qsize_t dqb_curinodes;
141 	qsize_t dqb_bhardlimit;
142 	qsize_t dqb_bsoftlimit;
143 	qsize_t dqb_curspace;
144 	time_t dqb_btime;
145 	time_t dqb_itime;
146 	union {
147 		struct v2_mem_dqblk v2_mdqb;
148 	} u;			/* Format specific dquot information */
149 };
150 
151 /* Structure for one loaded quota */
152 struct dquot {
153 	struct dquot *dq_next;	/* Pointer to next dquot in the list */
154 	qid_t dq_id;		/* ID dquot belongs to */
155 	int dq_flags;		/* Some flags for utils */
156 	struct quota_handle *dq_h;	/* Handle of quotafile for this dquot */
157 	struct util_dqblk dq_dqb;	/* Parsed data of dquot */
158 };
159 
160 #define DQF_SEEN	0x0001
161 
162 /* Structure of quotafile operations */
163 struct quotafile_ops {
164 	/* Check whether quotafile is in our format */
165 	int (*check_file) (struct quota_handle *h, int type);
166 	/* Open quotafile */
167 	int (*init_io) (struct quota_handle *h, enum quota_type qtype);
168 	/* Create new quotafile */
169 	int (*new_io) (struct quota_handle *h);
170 	/* Write all changes and close quotafile */
171 	int (*end_io) (struct quota_handle *h);
172 	/* Write info about quotafile */
173 	int (*write_info) (struct quota_handle *h);
174 	/* Read dquot into memory */
175 	struct dquot *(*read_dquot) (struct quota_handle *h, qid_t id);
176 	/* Write given dquot to disk */
177 	int (*commit_dquot) (struct dquot *dquot);
178 	/* Scan quotafile and call callback on every structure */
179 	int (*scan_dquots) (struct quota_handle *h,
180 			    int (*process_dquot) (struct dquot *dquot,
181 						  void *data),
182 			    void *data);
183 	/* Function to print format specific file information */
184 	int (*report) (struct quota_handle *h, int verbose);
185 };
186 
187 #ifdef __CHECKER__
188 # ifndef __bitwise
189 #  define __bitwise             __attribute__((bitwise))
190 # endif
191 #define __force                 __attribute__((force))
192 #else
193 # ifndef __bitwise
194 #  define __bitwise
195 # endif
196 #define __force
197 #endif
198 
199 /* Open existing quotafile of given type (and verify its format) on given
200  * filesystem. */
201 errcode_t quota_file_open(struct f2fs_sb_info *sbi, struct quota_handle *h,
202 			  enum quota_type qtype, int flags);
203 
204 /* Create new quotafile of specified format on given filesystem */
205 errcode_t quota_file_create(struct f2fs_sb_info *sbi, struct quota_handle *h,
206 		enum quota_type qtype);
207 
208 /* Close quotafile */
209 errcode_t quota_file_close(struct f2fs_sb_info *sbi, struct quota_handle *h,
210 		int update_filesize);
211 
212 /* Get empty quota structure */
213 struct dquot *get_empty_dquot(void);
214 const char *quota_type2name(enum quota_type qtype);
215 void update_grace_times(struct dquot *q);
216 
217 /* In mkquota.c */
218 errcode_t quota_init_context(struct f2fs_sb_info *sbi);
219 void quota_data_inodes(quota_ctx_t qctx, struct f2fs_inode *inode, int adjust);
220 void quota_data_add(quota_ctx_t qctx, struct f2fs_inode *inode, qsize_t space);
221 void quota_data_sub(quota_ctx_t qctx, struct f2fs_inode *inode, qsize_t space);
222 errcode_t quota_write_inode(struct f2fs_sb_info *sbi, enum quota_type qtype);
223 void quota_add_inode_usage(quota_ctx_t qctx, f2fs_ino_t ino,
224 		struct f2fs_inode* inode);
225 void quota_release_context(quota_ctx_t *qctx);
226 errcode_t quota_compare_and_update(struct f2fs_sb_info *sbi,
227 		enum quota_type qtype, int *usage_inconsistent,
228 		int preserve_limits);
229 
quota_get_mem(unsigned long size,void * ptr)230 static inline errcode_t quota_get_mem(unsigned long size, void *ptr)
231 {
232         void *pp;
233 
234         pp = malloc(size);
235         if (!pp)
236                 return -1;
237         memcpy(ptr, &pp, sizeof (pp));
238         return 0;
239 }
240 
quota_get_memzero(unsigned long size,void * ptr)241 static inline errcode_t quota_get_memzero(unsigned long size, void *ptr)
242 {
243         void *pp;
244 
245         pp = malloc(size);
246         if (!pp)
247                 return -1;
248         memset(pp, 0, size);
249         memcpy(ptr, &pp, sizeof(pp));
250         return 0;
251 }
252 
quota_free_mem(void * ptr)253 static inline errcode_t quota_free_mem(void *ptr)
254 {
255         void *p;
256 
257         memcpy(&p, ptr, sizeof(p));
258         free(p);
259         p = 0;
260         memcpy(ptr, &p, sizeof(p));
261         return 0;
262 }
263 
264 #endif /* GUARD_QUOTAIO_H */
265