1 // SPDX-License-Identifier: GPL-2.0-only
3 * vfsv0 quota IO operations on file
6 #include <linux/errno.h>
8 #include <linux/mount.h>
9 #include <linux/dqblk_v2.h>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/quotaops.h>
16 #include <asm/byteorder.h>
18 #include "quota_tree.h"
19 #include "quotaio_v2.h"
21 MODULE_AUTHOR("Jan Kara");
22 MODULE_DESCRIPTION("Quota format v2 support");
23 MODULE_LICENSE("GPL");
25 #define __QUOTA_V2_PARANOIA
27 static void v2r0_mem2diskdqb(void *dp
, struct dquot
*dquot
);
28 static void v2r0_disk2memdqb(struct dquot
*dquot
, void *dp
);
29 static int v2r0_is_id(void *dp
, struct dquot
*dquot
);
30 static void v2r1_mem2diskdqb(void *dp
, struct dquot
*dquot
);
31 static void v2r1_disk2memdqb(struct dquot
*dquot
, void *dp
);
32 static int v2r1_is_id(void *dp
, struct dquot
*dquot
);
34 static const struct qtree_fmt_operations v2r0_qtree_ops
= {
35 .mem2disk_dqblk
= v2r0_mem2diskdqb
,
36 .disk2mem_dqblk
= v2r0_disk2memdqb
,
40 static const struct qtree_fmt_operations v2r1_qtree_ops
= {
41 .mem2disk_dqblk
= v2r1_mem2diskdqb
,
42 .disk2mem_dqblk
= v2r1_disk2memdqb
,
46 #define QUOTABLOCK_BITS 10
47 #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
49 static inline qsize_t
v2_stoqb(qsize_t space
)
51 return (space
+ QUOTABLOCK_SIZE
- 1) >> QUOTABLOCK_BITS
;
54 static inline qsize_t
v2_qbtos(qsize_t blocks
)
56 return blocks
<< QUOTABLOCK_BITS
;
59 static int v2_read_header(struct super_block
*sb
, int type
,
60 struct v2_disk_dqheader
*dqhead
)
64 size
= sb
->s_op
->quota_read(sb
, type
, (char *)dqhead
,
65 sizeof(struct v2_disk_dqheader
), 0);
66 if (size
!= sizeof(struct v2_disk_dqheader
)) {
67 quota_error(sb
, "Failed header read: expected=%zd got=%zd",
68 sizeof(struct v2_disk_dqheader
), size
);
76 /* Check whether given file is really vfsv0 quotafile */
77 static int v2_check_quota_file(struct super_block
*sb
, int type
)
79 struct v2_disk_dqheader dqhead
;
80 static const uint quota_magics
[] = V2_INITQMAGICS
;
81 static const uint quota_versions
[] = V2_INITQVERSIONS
;
83 if (v2_read_header(sb
, type
, &dqhead
))
85 if (le32_to_cpu(dqhead
.dqh_magic
) != quota_magics
[type
] ||
86 le32_to_cpu(dqhead
.dqh_version
) > quota_versions
[type
])
91 /* Read information header from quota file */
92 static int v2_read_file_info(struct super_block
*sb
, int type
)
94 struct v2_disk_dqinfo dinfo
;
95 struct v2_disk_dqheader dqhead
;
96 struct quota_info
*dqopt
= sb_dqopt(sb
);
97 struct mem_dqinfo
*info
= &dqopt
->info
[type
];
98 struct qtree_mem_dqinfo
*qinfo
;
100 unsigned int version
;
103 down_read(&dqopt
->dqio_sem
);
104 ret
= v2_read_header(sb
, type
, &dqhead
);
107 version
= le32_to_cpu(dqhead
.dqh_version
);
108 if ((info
->dqi_fmt_id
== QFMT_VFS_V0
&& version
!= 0) ||
109 (info
->dqi_fmt_id
== QFMT_VFS_V1
&& version
!= 1)) {
114 size
= sb
->s_op
->quota_read(sb
, type
, (char *)&dinfo
,
115 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
116 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
117 quota_error(sb
, "Can't read info structure");
124 info
->dqi_priv
= kmalloc(sizeof(struct qtree_mem_dqinfo
), GFP_NOFS
);
125 if (!info
->dqi_priv
) {
129 qinfo
= info
->dqi_priv
;
131 /* limits are stored as unsigned 32-bit data */
132 info
->dqi_max_spc_limit
= 0xffffffffLL
<< QUOTABLOCK_BITS
;
133 info
->dqi_max_ino_limit
= 0xffffffff;
136 * Used space is stored as unsigned 64-bit value in bytes but
137 * quota core supports only signed 64-bit values so use that
140 info
->dqi_max_spc_limit
= 0x7fffffffffffffffLL
; /* 2^63-1 */
141 info
->dqi_max_ino_limit
= 0x7fffffffffffffffLL
;
143 info
->dqi_bgrace
= le32_to_cpu(dinfo
.dqi_bgrace
);
144 info
->dqi_igrace
= le32_to_cpu(dinfo
.dqi_igrace
);
145 /* No flags currently supported */
148 qinfo
->dqi_type
= type
;
149 qinfo
->dqi_blocks
= le32_to_cpu(dinfo
.dqi_blocks
);
150 qinfo
->dqi_free_blk
= le32_to_cpu(dinfo
.dqi_free_blk
);
151 qinfo
->dqi_free_entry
= le32_to_cpu(dinfo
.dqi_free_entry
);
152 qinfo
->dqi_blocksize_bits
= V2_DQBLKSIZE_BITS
;
153 qinfo
->dqi_usable_bs
= 1 << V2_DQBLKSIZE_BITS
;
154 qinfo
->dqi_qtree_depth
= qtree_depth(qinfo
);
156 qinfo
->dqi_entry_size
= sizeof(struct v2r0_disk_dqblk
);
157 qinfo
->dqi_ops
= &v2r0_qtree_ops
;
159 qinfo
->dqi_entry_size
= sizeof(struct v2r1_disk_dqblk
);
160 qinfo
->dqi_ops
= &v2r1_qtree_ops
;
164 up_read(&dqopt
->dqio_sem
);
168 /* Write information header to quota file */
169 static int v2_write_file_info(struct super_block
*sb
, int type
)
171 struct v2_disk_dqinfo dinfo
;
172 struct quota_info
*dqopt
= sb_dqopt(sb
);
173 struct mem_dqinfo
*info
= &dqopt
->info
[type
];
174 struct qtree_mem_dqinfo
*qinfo
= info
->dqi_priv
;
177 down_write(&dqopt
->dqio_sem
);
178 spin_lock(&dq_data_lock
);
179 info
->dqi_flags
&= ~DQF_INFO_DIRTY
;
180 dinfo
.dqi_bgrace
= cpu_to_le32(info
->dqi_bgrace
);
181 dinfo
.dqi_igrace
= cpu_to_le32(info
->dqi_igrace
);
182 /* No flags currently supported */
183 dinfo
.dqi_flags
= cpu_to_le32(0);
184 spin_unlock(&dq_data_lock
);
185 dinfo
.dqi_blocks
= cpu_to_le32(qinfo
->dqi_blocks
);
186 dinfo
.dqi_free_blk
= cpu_to_le32(qinfo
->dqi_free_blk
);
187 dinfo
.dqi_free_entry
= cpu_to_le32(qinfo
->dqi_free_entry
);
188 size
= sb
->s_op
->quota_write(sb
, type
, (char *)&dinfo
,
189 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
190 up_write(&dqopt
->dqio_sem
);
191 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
192 quota_error(sb
, "Can't write info structure");
198 static void v2r0_disk2memdqb(struct dquot
*dquot
, void *dp
)
200 struct v2r0_disk_dqblk
*d
= dp
, empty
;
201 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
203 m
->dqb_ihardlimit
= le32_to_cpu(d
->dqb_ihardlimit
);
204 m
->dqb_isoftlimit
= le32_to_cpu(d
->dqb_isoftlimit
);
205 m
->dqb_curinodes
= le32_to_cpu(d
->dqb_curinodes
);
206 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
207 m
->dqb_bhardlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bhardlimit
));
208 m
->dqb_bsoftlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bsoftlimit
));
209 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
210 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
211 /* We need to escape back all-zero structure */
212 memset(&empty
, 0, sizeof(struct v2r0_disk_dqblk
));
213 empty
.dqb_itime
= cpu_to_le64(1);
214 if (!memcmp(&empty
, dp
, sizeof(struct v2r0_disk_dqblk
)))
218 static void v2r0_mem2diskdqb(void *dp
, struct dquot
*dquot
)
220 struct v2r0_disk_dqblk
*d
= dp
;
221 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
222 struct qtree_mem_dqinfo
*info
=
223 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
225 d
->dqb_ihardlimit
= cpu_to_le32(m
->dqb_ihardlimit
);
226 d
->dqb_isoftlimit
= cpu_to_le32(m
->dqb_isoftlimit
);
227 d
->dqb_curinodes
= cpu_to_le32(m
->dqb_curinodes
);
228 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
229 d
->dqb_bhardlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bhardlimit
));
230 d
->dqb_bsoftlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bsoftlimit
));
231 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
232 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
233 d
->dqb_id
= cpu_to_le32(from_kqid(&init_user_ns
, dquot
->dq_id
));
234 if (qtree_entry_unused(info
, dp
))
235 d
->dqb_itime
= cpu_to_le64(1);
238 static int v2r0_is_id(void *dp
, struct dquot
*dquot
)
240 struct v2r0_disk_dqblk
*d
= dp
;
241 struct qtree_mem_dqinfo
*info
=
242 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
244 if (qtree_entry_unused(info
, dp
))
246 return qid_eq(make_kqid(&init_user_ns
, dquot
->dq_id
.type
,
247 le32_to_cpu(d
->dqb_id
)),
251 static void v2r1_disk2memdqb(struct dquot
*dquot
, void *dp
)
253 struct v2r1_disk_dqblk
*d
= dp
, empty
;
254 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
256 m
->dqb_ihardlimit
= le64_to_cpu(d
->dqb_ihardlimit
);
257 m
->dqb_isoftlimit
= le64_to_cpu(d
->dqb_isoftlimit
);
258 m
->dqb_curinodes
= le64_to_cpu(d
->dqb_curinodes
);
259 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
260 m
->dqb_bhardlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bhardlimit
));
261 m
->dqb_bsoftlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bsoftlimit
));
262 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
263 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
264 /* We need to escape back all-zero structure */
265 memset(&empty
, 0, sizeof(struct v2r1_disk_dqblk
));
266 empty
.dqb_itime
= cpu_to_le64(1);
267 if (!memcmp(&empty
, dp
, sizeof(struct v2r1_disk_dqblk
)))
271 static void v2r1_mem2diskdqb(void *dp
, struct dquot
*dquot
)
273 struct v2r1_disk_dqblk
*d
= dp
;
274 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
275 struct qtree_mem_dqinfo
*info
=
276 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
278 d
->dqb_ihardlimit
= cpu_to_le64(m
->dqb_ihardlimit
);
279 d
->dqb_isoftlimit
= cpu_to_le64(m
->dqb_isoftlimit
);
280 d
->dqb_curinodes
= cpu_to_le64(m
->dqb_curinodes
);
281 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
282 d
->dqb_bhardlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bhardlimit
));
283 d
->dqb_bsoftlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bsoftlimit
));
284 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
285 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
286 d
->dqb_id
= cpu_to_le32(from_kqid(&init_user_ns
, dquot
->dq_id
));
287 if (qtree_entry_unused(info
, dp
))
288 d
->dqb_itime
= cpu_to_le64(1);
291 static int v2r1_is_id(void *dp
, struct dquot
*dquot
)
293 struct v2r1_disk_dqblk
*d
= dp
;
294 struct qtree_mem_dqinfo
*info
=
295 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
297 if (qtree_entry_unused(info
, dp
))
299 return qid_eq(make_kqid(&init_user_ns
, dquot
->dq_id
.type
,
300 le32_to_cpu(d
->dqb_id
)),
304 static int v2_read_dquot(struct dquot
*dquot
)
306 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
309 down_read(&dqopt
->dqio_sem
);
310 ret
= qtree_read_dquot(
311 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
,
313 up_read(&dqopt
->dqio_sem
);
317 static int v2_write_dquot(struct dquot
*dquot
)
319 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
324 * If space for dquot is already allocated, we don't need any
325 * protection as we'll only overwrite the place of dquot. We are
326 * still protected by concurrent writes of the same dquot by
329 if (!dquot
->dq_off
) {
331 down_write(&dqopt
->dqio_sem
);
333 down_read(&dqopt
->dqio_sem
);
335 ret
= qtree_write_dquot(
336 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
,
339 up_write(&dqopt
->dqio_sem
);
341 up_read(&dqopt
->dqio_sem
);
345 static int v2_release_dquot(struct dquot
*dquot
)
347 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
350 down_write(&dqopt
->dqio_sem
);
351 ret
= qtree_release_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
, dquot
);
352 up_write(&dqopt
->dqio_sem
);
357 static int v2_free_file_info(struct super_block
*sb
, int type
)
359 kfree(sb_dqinfo(sb
, type
)->dqi_priv
);
363 static int v2_get_next_id(struct super_block
*sb
, struct kqid
*qid
)
365 struct quota_info
*dqopt
= sb_dqopt(sb
);
368 down_read(&dqopt
->dqio_sem
);
369 ret
= qtree_get_next_id(sb_dqinfo(sb
, qid
->type
)->dqi_priv
, qid
);
370 up_read(&dqopt
->dqio_sem
);
374 static const struct quota_format_ops v2_format_ops
= {
375 .check_quota_file
= v2_check_quota_file
,
376 .read_file_info
= v2_read_file_info
,
377 .write_file_info
= v2_write_file_info
,
378 .free_file_info
= v2_free_file_info
,
379 .read_dqblk
= v2_read_dquot
,
380 .commit_dqblk
= v2_write_dquot
,
381 .release_dqblk
= v2_release_dquot
,
382 .get_next_id
= v2_get_next_id
,
385 static struct quota_format_type v2r0_quota_format
= {
386 .qf_fmt_id
= QFMT_VFS_V0
,
387 .qf_ops
= &v2_format_ops
,
388 .qf_owner
= THIS_MODULE
391 static struct quota_format_type v2r1_quota_format
= {
392 .qf_fmt_id
= QFMT_VFS_V1
,
393 .qf_ops
= &v2_format_ops
,
394 .qf_owner
= THIS_MODULE
397 static int __init
init_v2_quota_format(void)
401 ret
= register_quota_format(&v2r0_quota_format
);
404 return register_quota_format(&v2r1_quota_format
);
407 static void __exit
exit_v2_quota_format(void)
409 unregister_quota_format(&v2r0_quota_format
);
410 unregister_quota_format(&v2r1_quota_format
);
413 module_init(init_v2_quota_format
);
414 module_exit(exit_v2_quota_format
);