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