1*59bfda1fSAndroid Build Coastguard Worker /*
2*59bfda1fSAndroid Build Coastguard Worker * Implementation of new quotafile format
3*59bfda1fSAndroid Build Coastguard Worker *
4*59bfda1fSAndroid Build Coastguard Worker * Jan Kara <[email protected]> - sponsored by SuSE CR
5*59bfda1fSAndroid Build Coastguard Worker * Hyojun Kim <[email protected]> - Ported to f2fs-tools
6*59bfda1fSAndroid Build Coastguard Worker */
7*59bfda1fSAndroid Build Coastguard Worker
8*59bfda1fSAndroid Build Coastguard Worker #include <sys/types.h>
9*59bfda1fSAndroid Build Coastguard Worker #include <errno.h>
10*59bfda1fSAndroid Build Coastguard Worker #include <stdio.h>
11*59bfda1fSAndroid Build Coastguard Worker #include <stdlib.h>
12*59bfda1fSAndroid Build Coastguard Worker #include <string.h>
13*59bfda1fSAndroid Build Coastguard Worker #include <unistd.h>
14*59bfda1fSAndroid Build Coastguard Worker
15*59bfda1fSAndroid Build Coastguard Worker #include "common.h"
16*59bfda1fSAndroid Build Coastguard Worker
17*59bfda1fSAndroid Build Coastguard Worker #include "quotaio_v2.h"
18*59bfda1fSAndroid Build Coastguard Worker #include "dqblk_v2.h"
19*59bfda1fSAndroid Build Coastguard Worker #include "quotaio_tree.h"
20*59bfda1fSAndroid Build Coastguard Worker
21*59bfda1fSAndroid Build Coastguard Worker static int v2_check_file(struct quota_handle *h, int type);
22*59bfda1fSAndroid Build Coastguard Worker static int v2_init_io(struct quota_handle *h, enum quota_type qtype);
23*59bfda1fSAndroid Build Coastguard Worker static int v2_new_io(struct quota_handle *h);
24*59bfda1fSAndroid Build Coastguard Worker static int v2_write_info(struct quota_handle *h);
25*59bfda1fSAndroid Build Coastguard Worker static struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id);
26*59bfda1fSAndroid Build Coastguard Worker static int v2_commit_dquot(struct dquot *dquot);
27*59bfda1fSAndroid Build Coastguard Worker static int v2_scan_dquots(struct quota_handle *h,
28*59bfda1fSAndroid Build Coastguard Worker int (*process_dquot) (struct dquot *dquot,
29*59bfda1fSAndroid Build Coastguard Worker void *data),
30*59bfda1fSAndroid Build Coastguard Worker void *data);
31*59bfda1fSAndroid Build Coastguard Worker static int v2_report(struct quota_handle *h, int verbose);
32*59bfda1fSAndroid Build Coastguard Worker
33*59bfda1fSAndroid Build Coastguard Worker struct quotafile_ops quotafile_ops_2 = {
34*59bfda1fSAndroid Build Coastguard Worker .check_file = v2_check_file,
35*59bfda1fSAndroid Build Coastguard Worker .init_io = v2_init_io,
36*59bfda1fSAndroid Build Coastguard Worker .new_io = v2_new_io,
37*59bfda1fSAndroid Build Coastguard Worker .write_info = v2_write_info,
38*59bfda1fSAndroid Build Coastguard Worker .read_dquot = v2_read_dquot,
39*59bfda1fSAndroid Build Coastguard Worker .commit_dquot = v2_commit_dquot,
40*59bfda1fSAndroid Build Coastguard Worker .scan_dquots = v2_scan_dquots,
41*59bfda1fSAndroid Build Coastguard Worker .report = v2_report,
42*59bfda1fSAndroid Build Coastguard Worker };
43*59bfda1fSAndroid Build Coastguard Worker
44*59bfda1fSAndroid Build Coastguard Worker /*
45*59bfda1fSAndroid Build Coastguard Worker * Copy dquot from disk to memory
46*59bfda1fSAndroid Build Coastguard Worker */
v2r1_disk2memdqblk(struct dquot * dquot,void * dp)47*59bfda1fSAndroid Build Coastguard Worker static void v2r1_disk2memdqblk(struct dquot *dquot, void *dp)
48*59bfda1fSAndroid Build Coastguard Worker {
49*59bfda1fSAndroid Build Coastguard Worker struct util_dqblk *m = &dquot->dq_dqb;
50*59bfda1fSAndroid Build Coastguard Worker struct v2r1_disk_dqblk *d = dp, empty;
51*59bfda1fSAndroid Build Coastguard Worker
52*59bfda1fSAndroid Build Coastguard Worker dquot->dq_id = le32_to_cpu(d->dqb_id);
53*59bfda1fSAndroid Build Coastguard Worker m->dqb_ihardlimit = le64_to_cpu(d->dqb_ihardlimit);
54*59bfda1fSAndroid Build Coastguard Worker m->dqb_isoftlimit = le64_to_cpu(d->dqb_isoftlimit);
55*59bfda1fSAndroid Build Coastguard Worker m->dqb_bhardlimit = le64_to_cpu(d->dqb_bhardlimit);
56*59bfda1fSAndroid Build Coastguard Worker m->dqb_bsoftlimit = le64_to_cpu(d->dqb_bsoftlimit);
57*59bfda1fSAndroid Build Coastguard Worker m->dqb_curinodes = le64_to_cpu(d->dqb_curinodes);
58*59bfda1fSAndroid Build Coastguard Worker m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
59*59bfda1fSAndroid Build Coastguard Worker m->dqb_itime = le64_to_cpu(d->dqb_itime);
60*59bfda1fSAndroid Build Coastguard Worker m->dqb_btime = le64_to_cpu(d->dqb_btime);
61*59bfda1fSAndroid Build Coastguard Worker
62*59bfda1fSAndroid Build Coastguard Worker memset(&empty, 0, sizeof(struct v2r1_disk_dqblk));
63*59bfda1fSAndroid Build Coastguard Worker empty.dqb_itime = cpu_to_le64(1);
64*59bfda1fSAndroid Build Coastguard Worker if (!memcmp(&empty, dp, sizeof(struct v2r1_disk_dqblk)))
65*59bfda1fSAndroid Build Coastguard Worker m->dqb_itime = 0;
66*59bfda1fSAndroid Build Coastguard Worker }
67*59bfda1fSAndroid Build Coastguard Worker
68*59bfda1fSAndroid Build Coastguard Worker /*
69*59bfda1fSAndroid Build Coastguard Worker * Copy dquot from memory to disk
70*59bfda1fSAndroid Build Coastguard Worker */
v2r1_mem2diskdqblk(void * dp,struct dquot * dquot)71*59bfda1fSAndroid Build Coastguard Worker static void v2r1_mem2diskdqblk(void *dp, struct dquot *dquot)
72*59bfda1fSAndroid Build Coastguard Worker {
73*59bfda1fSAndroid Build Coastguard Worker struct util_dqblk *m = &dquot->dq_dqb;
74*59bfda1fSAndroid Build Coastguard Worker struct v2r1_disk_dqblk *d = dp;
75*59bfda1fSAndroid Build Coastguard Worker
76*59bfda1fSAndroid Build Coastguard Worker d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
77*59bfda1fSAndroid Build Coastguard Worker d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
78*59bfda1fSAndroid Build Coastguard Worker d->dqb_bhardlimit = cpu_to_le64(m->dqb_bhardlimit);
79*59bfda1fSAndroid Build Coastguard Worker d->dqb_bsoftlimit = cpu_to_le64(m->dqb_bsoftlimit);
80*59bfda1fSAndroid Build Coastguard Worker d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
81*59bfda1fSAndroid Build Coastguard Worker d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
82*59bfda1fSAndroid Build Coastguard Worker d->dqb_itime = cpu_to_le64(m->dqb_itime);
83*59bfda1fSAndroid Build Coastguard Worker d->dqb_btime = cpu_to_le64(m->dqb_btime);
84*59bfda1fSAndroid Build Coastguard Worker d->dqb_id = cpu_to_le32(dquot->dq_id);
85*59bfda1fSAndroid Build Coastguard Worker if (qtree_entry_unused(&dquot->dq_h->qh_info.u.v2_mdqi.dqi_qtree, dp))
86*59bfda1fSAndroid Build Coastguard Worker d->dqb_itime = cpu_to_le64(1);
87*59bfda1fSAndroid Build Coastguard Worker }
88*59bfda1fSAndroid Build Coastguard Worker
v2r1_is_id(void * dp,struct dquot * dquot)89*59bfda1fSAndroid Build Coastguard Worker static int v2r1_is_id(void *dp, struct dquot *dquot)
90*59bfda1fSAndroid Build Coastguard Worker {
91*59bfda1fSAndroid Build Coastguard Worker struct v2r1_disk_dqblk *d = dp;
92*59bfda1fSAndroid Build Coastguard Worker struct qtree_mem_dqinfo *info =
93*59bfda1fSAndroid Build Coastguard Worker &dquot->dq_h->qh_info.u.v2_mdqi.dqi_qtree;
94*59bfda1fSAndroid Build Coastguard Worker
95*59bfda1fSAndroid Build Coastguard Worker if (qtree_entry_unused(info, dp))
96*59bfda1fSAndroid Build Coastguard Worker return 0;
97*59bfda1fSAndroid Build Coastguard Worker return le32_to_cpu(d->dqb_id) == dquot->dq_id;
98*59bfda1fSAndroid Build Coastguard Worker }
99*59bfda1fSAndroid Build Coastguard Worker
100*59bfda1fSAndroid Build Coastguard Worker static struct qtree_fmt_operations v2r1_fmt_ops = {
101*59bfda1fSAndroid Build Coastguard Worker .mem2disk_dqblk = v2r1_mem2diskdqblk,
102*59bfda1fSAndroid Build Coastguard Worker .disk2mem_dqblk = v2r1_disk2memdqblk,
103*59bfda1fSAndroid Build Coastguard Worker .is_id = v2r1_is_id,
104*59bfda1fSAndroid Build Coastguard Worker };
105*59bfda1fSAndroid Build Coastguard Worker
106*59bfda1fSAndroid Build Coastguard Worker /*
107*59bfda1fSAndroid Build Coastguard Worker * Copy dqinfo from disk to memory
108*59bfda1fSAndroid Build Coastguard Worker */
v2_disk2memdqinfo(struct util_dqinfo * m,struct v2_disk_dqinfo * d)109*59bfda1fSAndroid Build Coastguard Worker static inline void v2_disk2memdqinfo(struct util_dqinfo *m,
110*59bfda1fSAndroid Build Coastguard Worker struct v2_disk_dqinfo *d)
111*59bfda1fSAndroid Build Coastguard Worker {
112*59bfda1fSAndroid Build Coastguard Worker m->dqi_bgrace = le32_to_cpu(d->dqi_bgrace);
113*59bfda1fSAndroid Build Coastguard Worker m->dqi_igrace = le32_to_cpu(d->dqi_igrace);
114*59bfda1fSAndroid Build Coastguard Worker m->u.v2_mdqi.dqi_flags = le32_to_cpu(d->dqi_flags) & V2_DQF_MASK;
115*59bfda1fSAndroid Build Coastguard Worker m->u.v2_mdqi.dqi_qtree.dqi_blocks = le32_to_cpu(d->dqi_blocks);
116*59bfda1fSAndroid Build Coastguard Worker m->u.v2_mdqi.dqi_qtree.dqi_free_blk =
117*59bfda1fSAndroid Build Coastguard Worker le32_to_cpu(d->dqi_free_blk);
118*59bfda1fSAndroid Build Coastguard Worker m->u.v2_mdqi.dqi_qtree.dqi_free_entry =
119*59bfda1fSAndroid Build Coastguard Worker le32_to_cpu(d->dqi_free_entry);
120*59bfda1fSAndroid Build Coastguard Worker }
121*59bfda1fSAndroid Build Coastguard Worker
122*59bfda1fSAndroid Build Coastguard Worker /*
123*59bfda1fSAndroid Build Coastguard Worker * Copy dqinfo from memory to disk
124*59bfda1fSAndroid Build Coastguard Worker */
v2_mem2diskdqinfo(struct v2_disk_dqinfo * d,struct util_dqinfo * m)125*59bfda1fSAndroid Build Coastguard Worker static inline void v2_mem2diskdqinfo(struct v2_disk_dqinfo *d,
126*59bfda1fSAndroid Build Coastguard Worker struct util_dqinfo *m)
127*59bfda1fSAndroid Build Coastguard Worker {
128*59bfda1fSAndroid Build Coastguard Worker d->dqi_bgrace = cpu_to_le32(m->dqi_bgrace);
129*59bfda1fSAndroid Build Coastguard Worker d->dqi_igrace = cpu_to_le32(m->dqi_igrace);
130*59bfda1fSAndroid Build Coastguard Worker d->dqi_flags = cpu_to_le32(m->u.v2_mdqi.dqi_flags & V2_DQF_MASK);
131*59bfda1fSAndroid Build Coastguard Worker d->dqi_blocks = cpu_to_le32(m->u.v2_mdqi.dqi_qtree.dqi_blocks);
132*59bfda1fSAndroid Build Coastguard Worker d->dqi_free_blk =
133*59bfda1fSAndroid Build Coastguard Worker cpu_to_le32(m->u.v2_mdqi.dqi_qtree.dqi_free_blk);
134*59bfda1fSAndroid Build Coastguard Worker d->dqi_free_entry =
135*59bfda1fSAndroid Build Coastguard Worker cpu_to_le32(m->u.v2_mdqi.dqi_qtree.dqi_free_entry);
136*59bfda1fSAndroid Build Coastguard Worker }
137*59bfda1fSAndroid Build Coastguard Worker
v2_read_header(struct quota_handle * h,struct v2_disk_dqheader * dqh)138*59bfda1fSAndroid Build Coastguard Worker static int v2_read_header(struct quota_handle *h, struct v2_disk_dqheader *dqh)
139*59bfda1fSAndroid Build Coastguard Worker {
140*59bfda1fSAndroid Build Coastguard Worker if (h->read(&h->qh_qf, 0, dqh, sizeof(struct v2_disk_dqheader)) !=
141*59bfda1fSAndroid Build Coastguard Worker sizeof(struct v2_disk_dqheader))
142*59bfda1fSAndroid Build Coastguard Worker return 0;
143*59bfda1fSAndroid Build Coastguard Worker
144*59bfda1fSAndroid Build Coastguard Worker return 1;
145*59bfda1fSAndroid Build Coastguard Worker }
146*59bfda1fSAndroid Build Coastguard Worker
147*59bfda1fSAndroid Build Coastguard Worker /*
148*59bfda1fSAndroid Build Coastguard Worker * Check whether given quota file is in our format
149*59bfda1fSAndroid Build Coastguard Worker */
v2_check_file(struct quota_handle * h,int type)150*59bfda1fSAndroid Build Coastguard Worker static int v2_check_file(struct quota_handle *h, int type)
151*59bfda1fSAndroid Build Coastguard Worker {
152*59bfda1fSAndroid Build Coastguard Worker struct v2_disk_dqheader dqh;
153*59bfda1fSAndroid Build Coastguard Worker int file_magics[] = INITQMAGICS;
154*59bfda1fSAndroid Build Coastguard Worker int be_magic;
155*59bfda1fSAndroid Build Coastguard Worker
156*59bfda1fSAndroid Build Coastguard Worker if (!v2_read_header(h, &dqh))
157*59bfda1fSAndroid Build Coastguard Worker return 0;
158*59bfda1fSAndroid Build Coastguard Worker
159*59bfda1fSAndroid Build Coastguard Worker be_magic = be32_to_cpu((__force __be32)dqh.dqh_magic);
160*59bfda1fSAndroid Build Coastguard Worker if (be_magic == file_magics[type]) {
161*59bfda1fSAndroid Build Coastguard Worker log_err("Your quota file is stored in wrong endianity");
162*59bfda1fSAndroid Build Coastguard Worker return 0;
163*59bfda1fSAndroid Build Coastguard Worker }
164*59bfda1fSAndroid Build Coastguard Worker if (V2_VERSION != le32_to_cpu(dqh.dqh_version))
165*59bfda1fSAndroid Build Coastguard Worker return 0;
166*59bfda1fSAndroid Build Coastguard Worker return 1;
167*59bfda1fSAndroid Build Coastguard Worker }
168*59bfda1fSAndroid Build Coastguard Worker
169*59bfda1fSAndroid Build Coastguard Worker /*
170*59bfda1fSAndroid Build Coastguard Worker * Open quotafile
171*59bfda1fSAndroid Build Coastguard Worker */
v2_init_io(struct quota_handle * h,enum quota_type qtype)172*59bfda1fSAndroid Build Coastguard Worker static int v2_init_io(struct quota_handle *h, enum quota_type qtype)
173*59bfda1fSAndroid Build Coastguard Worker {
174*59bfda1fSAndroid Build Coastguard Worker struct v2_disk_dqinfo ddqinfo;
175*59bfda1fSAndroid Build Coastguard Worker struct v2_mem_dqinfo *info;
176*59bfda1fSAndroid Build Coastguard Worker u64 filesize;
177*59bfda1fSAndroid Build Coastguard Worker struct quota_file *qf = &h->qh_qf;
178*59bfda1fSAndroid Build Coastguard Worker u32 last_blkofs = qf_last_blkofs[qtype];
179*59bfda1fSAndroid Build Coastguard Worker
180*59bfda1fSAndroid Build Coastguard Worker h->qh_info.u.v2_mdqi.dqi_qtree.dqi_entry_size =
181*59bfda1fSAndroid Build Coastguard Worker sizeof(struct v2r1_disk_dqblk);
182*59bfda1fSAndroid Build Coastguard Worker h->qh_info.u.v2_mdqi.dqi_qtree.dqi_ops = &v2r1_fmt_ops;
183*59bfda1fSAndroid Build Coastguard Worker
184*59bfda1fSAndroid Build Coastguard Worker /* Read information about quotafile */
185*59bfda1fSAndroid Build Coastguard Worker if (h->read(qf, V2_DQINFOOFF, &ddqinfo,
186*59bfda1fSAndroid Build Coastguard Worker sizeof(ddqinfo)) != sizeof(ddqinfo))
187*59bfda1fSAndroid Build Coastguard Worker return -1;
188*59bfda1fSAndroid Build Coastguard Worker v2_disk2memdqinfo(&h->qh_info, &ddqinfo);
189*59bfda1fSAndroid Build Coastguard Worker
190*59bfda1fSAndroid Build Coastguard Worker /* Check to make sure quota file info is sane */
191*59bfda1fSAndroid Build Coastguard Worker info = &h->qh_info.u.v2_mdqi;
192*59bfda1fSAndroid Build Coastguard Worker filesize = qf->filesize = f2fs_quota_size(qf);
193*59bfda1fSAndroid Build Coastguard Worker if (qf_szchk_type[qtype] == QF_SZCHK_REGFILE &&
194*59bfda1fSAndroid Build Coastguard Worker ((filesize + F2FS_BLKSIZE - 1) >> F2FS_BLKSIZE_BITS <
195*59bfda1fSAndroid Build Coastguard Worker last_blkofs + 1 || filesize > qf_maxsize[qtype])) {
196*59bfda1fSAndroid Build Coastguard Worker /*
197*59bfda1fSAndroid Build Coastguard Worker * reqular: qf_szchk is now the last block index,
198*59bfda1fSAndroid Build Coastguard Worker * including the hole's index
199*59bfda1fSAndroid Build Coastguard Worker */
200*59bfda1fSAndroid Build Coastguard Worker log_err("Quota inode %u corrupted: file size %" PRIu64
201*59bfda1fSAndroid Build Coastguard Worker " does not match page offset %" PRIu32,
202*59bfda1fSAndroid Build Coastguard Worker h->qh_qf.ino,
203*59bfda1fSAndroid Build Coastguard Worker filesize,
204*59bfda1fSAndroid Build Coastguard Worker last_blkofs);
205*59bfda1fSAndroid Build Coastguard Worker filesize = (last_blkofs + 1) << F2FS_BLKSIZE_BITS;
206*59bfda1fSAndroid Build Coastguard Worker f2fs_filesize_update(qf->sbi, qf->ino, filesize);
207*59bfda1fSAndroid Build Coastguard Worker }
208*59bfda1fSAndroid Build Coastguard Worker
209*59bfda1fSAndroid Build Coastguard Worker if ((info->dqi_qtree.dqi_blocks >
210*59bfda1fSAndroid Build Coastguard Worker (filesize + QT_BLKSIZE - 1) >> QT_BLKSIZE_BITS)) {
211*59bfda1fSAndroid Build Coastguard Worker log_err("Quota inode %u corrupted: file size %" PRId64 "; "
212*59bfda1fSAndroid Build Coastguard Worker "dqi_blocks %u", h->qh_qf.ino,
213*59bfda1fSAndroid Build Coastguard Worker filesize, info->dqi_qtree.dqi_blocks);
214*59bfda1fSAndroid Build Coastguard Worker return -1;
215*59bfda1fSAndroid Build Coastguard Worker }
216*59bfda1fSAndroid Build Coastguard Worker if (info->dqi_qtree.dqi_free_blk >= info->dqi_qtree.dqi_blocks) {
217*59bfda1fSAndroid Build Coastguard Worker log_err("Quota inode %u corrupted: free_blk %u;"
218*59bfda1fSAndroid Build Coastguard Worker " dqi_blocks %u",
219*59bfda1fSAndroid Build Coastguard Worker h->qh_qf.ino, info->dqi_qtree.dqi_free_blk,
220*59bfda1fSAndroid Build Coastguard Worker info->dqi_qtree.dqi_blocks);
221*59bfda1fSAndroid Build Coastguard Worker return -1;
222*59bfda1fSAndroid Build Coastguard Worker }
223*59bfda1fSAndroid Build Coastguard Worker if (info->dqi_qtree.dqi_free_entry >= info->dqi_qtree.dqi_blocks) {
224*59bfda1fSAndroid Build Coastguard Worker log_err("Quota inode %u corrupted: free_entry %u; "
225*59bfda1fSAndroid Build Coastguard Worker "dqi_blocks %u", h->qh_qf.ino,
226*59bfda1fSAndroid Build Coastguard Worker info->dqi_qtree.dqi_free_entry,
227*59bfda1fSAndroid Build Coastguard Worker info->dqi_qtree.dqi_blocks);
228*59bfda1fSAndroid Build Coastguard Worker return -1;
229*59bfda1fSAndroid Build Coastguard Worker }
230*59bfda1fSAndroid Build Coastguard Worker return 0;
231*59bfda1fSAndroid Build Coastguard Worker }
232*59bfda1fSAndroid Build Coastguard Worker
233*59bfda1fSAndroid Build Coastguard Worker /*
234*59bfda1fSAndroid Build Coastguard Worker * Initialize new quotafile
235*59bfda1fSAndroid Build Coastguard Worker */
v2_new_io(struct quota_handle * h)236*59bfda1fSAndroid Build Coastguard Worker static int v2_new_io(struct quota_handle *h)
237*59bfda1fSAndroid Build Coastguard Worker {
238*59bfda1fSAndroid Build Coastguard Worker int file_magics[] = INITQMAGICS;
239*59bfda1fSAndroid Build Coastguard Worker struct v2_disk_dqheader ddqheader;
240*59bfda1fSAndroid Build Coastguard Worker struct v2_disk_dqinfo ddqinfo;
241*59bfda1fSAndroid Build Coastguard Worker
242*59bfda1fSAndroid Build Coastguard Worker if (h->qh_fmt != QFMT_VFS_V1)
243*59bfda1fSAndroid Build Coastguard Worker return -1;
244*59bfda1fSAndroid Build Coastguard Worker
245*59bfda1fSAndroid Build Coastguard Worker /* Write basic quota header */
246*59bfda1fSAndroid Build Coastguard Worker ddqheader.dqh_magic = cpu_to_le32(file_magics[h->qh_type]);
247*59bfda1fSAndroid Build Coastguard Worker ddqheader.dqh_version = cpu_to_le32(V2_VERSION);
248*59bfda1fSAndroid Build Coastguard Worker if (h->write(&h->qh_qf, 0, &ddqheader, sizeof(ddqheader)) !=
249*59bfda1fSAndroid Build Coastguard Worker sizeof(ddqheader))
250*59bfda1fSAndroid Build Coastguard Worker return -1;
251*59bfda1fSAndroid Build Coastguard Worker
252*59bfda1fSAndroid Build Coastguard Worker /* Write information about quotafile */
253*59bfda1fSAndroid Build Coastguard Worker h->qh_info.dqi_bgrace = MAX_DQ_TIME;
254*59bfda1fSAndroid Build Coastguard Worker h->qh_info.dqi_igrace = MAX_IQ_TIME;
255*59bfda1fSAndroid Build Coastguard Worker h->qh_info.u.v2_mdqi.dqi_flags = 0;
256*59bfda1fSAndroid Build Coastguard Worker h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks = QT_TREEOFF + 1;
257*59bfda1fSAndroid Build Coastguard Worker h->qh_info.u.v2_mdqi.dqi_qtree.dqi_free_blk = 0;
258*59bfda1fSAndroid Build Coastguard Worker h->qh_info.u.v2_mdqi.dqi_qtree.dqi_free_entry = 0;
259*59bfda1fSAndroid Build Coastguard Worker h->qh_info.u.v2_mdqi.dqi_qtree.dqi_entry_size =
260*59bfda1fSAndroid Build Coastguard Worker sizeof(struct v2r1_disk_dqblk);
261*59bfda1fSAndroid Build Coastguard Worker h->qh_info.u.v2_mdqi.dqi_qtree.dqi_ops = &v2r1_fmt_ops;
262*59bfda1fSAndroid Build Coastguard Worker v2_mem2diskdqinfo(&ddqinfo, &h->qh_info);
263*59bfda1fSAndroid Build Coastguard Worker if (h->write(&h->qh_qf, V2_DQINFOOFF, &ddqinfo,
264*59bfda1fSAndroid Build Coastguard Worker sizeof(ddqinfo)) !=
265*59bfda1fSAndroid Build Coastguard Worker sizeof(ddqinfo))
266*59bfda1fSAndroid Build Coastguard Worker return -1;
267*59bfda1fSAndroid Build Coastguard Worker
268*59bfda1fSAndroid Build Coastguard Worker return 0;
269*59bfda1fSAndroid Build Coastguard Worker }
270*59bfda1fSAndroid Build Coastguard Worker
271*59bfda1fSAndroid Build Coastguard Worker /*
272*59bfda1fSAndroid Build Coastguard Worker * Write information (grace times to file)
273*59bfda1fSAndroid Build Coastguard Worker */
v2_write_info(struct quota_handle * h)274*59bfda1fSAndroid Build Coastguard Worker static int v2_write_info(struct quota_handle *h)
275*59bfda1fSAndroid Build Coastguard Worker {
276*59bfda1fSAndroid Build Coastguard Worker struct v2_disk_dqinfo ddqinfo;
277*59bfda1fSAndroid Build Coastguard Worker
278*59bfda1fSAndroid Build Coastguard Worker v2_mem2diskdqinfo(&ddqinfo, &h->qh_info);
279*59bfda1fSAndroid Build Coastguard Worker if (h->write(&h->qh_qf, V2_DQINFOOFF, &ddqinfo, sizeof(ddqinfo)) !=
280*59bfda1fSAndroid Build Coastguard Worker sizeof(ddqinfo))
281*59bfda1fSAndroid Build Coastguard Worker return -1;
282*59bfda1fSAndroid Build Coastguard Worker
283*59bfda1fSAndroid Build Coastguard Worker return 0;
284*59bfda1fSAndroid Build Coastguard Worker }
285*59bfda1fSAndroid Build Coastguard Worker
286*59bfda1fSAndroid Build Coastguard Worker /*
287*59bfda1fSAndroid Build Coastguard Worker * Read dquot from disk
288*59bfda1fSAndroid Build Coastguard Worker */
v2_read_dquot(struct quota_handle * h,qid_t id)289*59bfda1fSAndroid Build Coastguard Worker static struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id)
290*59bfda1fSAndroid Build Coastguard Worker {
291*59bfda1fSAndroid Build Coastguard Worker return qtree_read_dquot(h, id);
292*59bfda1fSAndroid Build Coastguard Worker }
293*59bfda1fSAndroid Build Coastguard Worker
294*59bfda1fSAndroid Build Coastguard Worker /*
295*59bfda1fSAndroid Build Coastguard Worker * Commit changes of dquot to disk - it might also mean deleting it when quota
296*59bfda1fSAndroid Build Coastguard Worker * became fake one and user has no blocks.
297*59bfda1fSAndroid Build Coastguard Worker * User can process use 'errno' to detect errstr.
298*59bfda1fSAndroid Build Coastguard Worker */
v2_commit_dquot(struct dquot * dquot)299*59bfda1fSAndroid Build Coastguard Worker static int v2_commit_dquot(struct dquot *dquot)
300*59bfda1fSAndroid Build Coastguard Worker {
301*59bfda1fSAndroid Build Coastguard Worker struct util_dqblk *b = &dquot->dq_dqb;
302*59bfda1fSAndroid Build Coastguard Worker
303*59bfda1fSAndroid Build Coastguard Worker if (!b->dqb_curspace && !b->dqb_curinodes && !b->dqb_bsoftlimit &&
304*59bfda1fSAndroid Build Coastguard Worker !b->dqb_isoftlimit && !b->dqb_bhardlimit && !b->dqb_ihardlimit)
305*59bfda1fSAndroid Build Coastguard Worker {
306*59bfda1fSAndroid Build Coastguard Worker qtree_delete_dquot(dquot);
307*59bfda1fSAndroid Build Coastguard Worker } else {
308*59bfda1fSAndroid Build Coastguard Worker return qtree_write_dquot(dquot);
309*59bfda1fSAndroid Build Coastguard Worker }
310*59bfda1fSAndroid Build Coastguard Worker return 0;
311*59bfda1fSAndroid Build Coastguard Worker }
312*59bfda1fSAndroid Build Coastguard Worker
v2_scan_dquots(struct quota_handle * h,int (* process_dquot)(struct dquot *,void *),void * data)313*59bfda1fSAndroid Build Coastguard Worker static int v2_scan_dquots(struct quota_handle *h,
314*59bfda1fSAndroid Build Coastguard Worker int (*process_dquot) (struct dquot *, void *),
315*59bfda1fSAndroid Build Coastguard Worker void *data)
316*59bfda1fSAndroid Build Coastguard Worker {
317*59bfda1fSAndroid Build Coastguard Worker return qtree_scan_dquots(h, process_dquot, data);
318*59bfda1fSAndroid Build Coastguard Worker }
319*59bfda1fSAndroid Build Coastguard Worker
320*59bfda1fSAndroid Build Coastguard Worker /* Report information about quotafile.
321*59bfda1fSAndroid Build Coastguard Worker * TODO: Not used right now, but we should be able to use this when we add
322*59bfda1fSAndroid Build Coastguard Worker * support to debugfs to read quota files.
323*59bfda1fSAndroid Build Coastguard Worker */
v2_report(struct quota_handle * UNUSED (h),int UNUSED (verbose))324*59bfda1fSAndroid Build Coastguard Worker static int v2_report(struct quota_handle *UNUSED(h), int UNUSED(verbose))
325*59bfda1fSAndroid Build Coastguard Worker {
326*59bfda1fSAndroid Build Coastguard Worker log_err("Not Implemented.");
327*59bfda1fSAndroid Build Coastguard Worker return -1;
328*59bfda1fSAndroid Build Coastguard Worker }
329