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 static void v2r0_mem2diskdqb(void *dp
, struct dquot
*dquot
);
26 static void v2r0_disk2memdqb(struct dquot
*dquot
, void *dp
);
27 static int v2r0_is_id(void *dp
, struct dquot
*dquot
);
28 static void v2r1_mem2diskdqb(void *dp
, struct dquot
*dquot
);
29 static void v2r1_disk2memdqb(struct dquot
*dquot
, void *dp
);
30 static int v2r1_is_id(void *dp
, struct dquot
*dquot
);
32 static const struct qtree_fmt_operations v2r0_qtree_ops
= {
33 .mem2disk_dqblk
= v2r0_mem2diskdqb
,
34 .disk2mem_dqblk
= v2r0_disk2memdqb
,
38 static const struct qtree_fmt_operations v2r1_qtree_ops
= {
39 .mem2disk_dqblk
= v2r1_mem2diskdqb
,
40 .disk2mem_dqblk
= v2r1_disk2memdqb
,
44 #define QUOTABLOCK_BITS 10
45 #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
47 static inline qsize_t
v2_stoqb(qsize_t space
)
49 return (space
+ QUOTABLOCK_SIZE
- 1) >> QUOTABLOCK_BITS
;
52 static inline qsize_t
v2_qbtos(qsize_t blocks
)
54 return blocks
<< QUOTABLOCK_BITS
;
57 static int v2_read_header(struct super_block
*sb
, int type
,
58 struct v2_disk_dqheader
*dqhead
)
62 size
= sb
->s_op
->quota_read(sb
, type
, (char *)dqhead
,
63 sizeof(struct v2_disk_dqheader
), 0);
64 if (size
!= sizeof(struct v2_disk_dqheader
)) {
65 quota_error(sb
, "Failed header read: expected=%zd got=%zd",
66 sizeof(struct v2_disk_dqheader
), size
);
74 /* Check whether given file is really vfsv0 quotafile */
75 static int v2_check_quota_file(struct super_block
*sb
, int type
)
77 struct v2_disk_dqheader dqhead
;
78 static const uint quota_magics
[] = V2_INITQMAGICS
;
79 static const uint quota_versions
[] = V2_INITQVERSIONS
;
81 if (v2_read_header(sb
, type
, &dqhead
))
83 if (le32_to_cpu(dqhead
.dqh_magic
) != quota_magics
[type
] ||
84 le32_to_cpu(dqhead
.dqh_version
) > quota_versions
[type
])
89 /* Read information header from quota file */
90 static int v2_read_file_info(struct super_block
*sb
, int type
)
92 struct v2_disk_dqinfo dinfo
;
93 struct v2_disk_dqheader dqhead
;
94 struct quota_info
*dqopt
= sb_dqopt(sb
);
95 struct mem_dqinfo
*info
= &dqopt
->info
[type
];
96 struct qtree_mem_dqinfo
*qinfo
;
101 down_read(&dqopt
->dqio_sem
);
102 ret
= v2_read_header(sb
, type
, &dqhead
);
105 version
= le32_to_cpu(dqhead
.dqh_version
);
106 if ((info
->dqi_fmt_id
== QFMT_VFS_V0
&& version
!= 0) ||
107 (info
->dqi_fmt_id
== QFMT_VFS_V1
&& version
!= 1)) {
112 size
= sb
->s_op
->quota_read(sb
, type
, (char *)&dinfo
,
113 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
114 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
115 quota_error(sb
, "Can't read info structure");
122 info
->dqi_priv
= kmalloc(sizeof(struct qtree_mem_dqinfo
), GFP_NOFS
);
123 if (!info
->dqi_priv
) {
127 qinfo
= info
->dqi_priv
;
129 /* limits are stored as unsigned 32-bit data */
130 info
->dqi_max_spc_limit
= 0xffffffffLL
<< QUOTABLOCK_BITS
;
131 info
->dqi_max_ino_limit
= 0xffffffff;
134 * Used space is stored as unsigned 64-bit value in bytes but
135 * quota core supports only signed 64-bit values so use that
138 info
->dqi_max_spc_limit
= 0x7fffffffffffffffLL
; /* 2^63-1 */
139 info
->dqi_max_ino_limit
= 0x7fffffffffffffffLL
;
141 info
->dqi_bgrace
= le32_to_cpu(dinfo
.dqi_bgrace
);
142 info
->dqi_igrace
= le32_to_cpu(dinfo
.dqi_igrace
);
143 /* No flags currently supported */
146 qinfo
->dqi_type
= type
;
147 qinfo
->dqi_blocks
= le32_to_cpu(dinfo
.dqi_blocks
);
148 qinfo
->dqi_free_blk
= le32_to_cpu(dinfo
.dqi_free_blk
);
149 qinfo
->dqi_free_entry
= le32_to_cpu(dinfo
.dqi_free_entry
);
150 qinfo
->dqi_blocksize_bits
= V2_DQBLKSIZE_BITS
;
151 qinfo
->dqi_usable_bs
= 1 << V2_DQBLKSIZE_BITS
;
152 qinfo
->dqi_qtree_depth
= qtree_depth(qinfo
);
154 qinfo
->dqi_entry_size
= sizeof(struct v2r0_disk_dqblk
);
155 qinfo
->dqi_ops
= &v2r0_qtree_ops
;
157 qinfo
->dqi_entry_size
= sizeof(struct v2r1_disk_dqblk
);
158 qinfo
->dqi_ops
= &v2r1_qtree_ops
;
161 /* Some sanity checks of the read headers... */
162 if ((loff_t
)qinfo
->dqi_blocks
<< qinfo
->dqi_blocksize_bits
>
163 i_size_read(sb_dqopt(sb
)->files
[type
])) {
164 quota_error(sb
, "Number of blocks too big for quota file size (%llu > %llu).",
165 (loff_t
)qinfo
->dqi_blocks
<< qinfo
->dqi_blocksize_bits
,
166 i_size_read(sb_dqopt(sb
)->files
[type
]));
169 if (qinfo
->dqi_free_blk
>= qinfo
->dqi_blocks
) {
170 quota_error(sb
, "Free block number too big (%u >= %u).",
171 qinfo
->dqi_free_blk
, qinfo
->dqi_blocks
);
174 if (qinfo
->dqi_free_entry
>= qinfo
->dqi_blocks
) {
175 quota_error(sb
, "Block with free entry too big (%u >= %u).",
176 qinfo
->dqi_free_entry
, qinfo
->dqi_blocks
);
181 up_read(&dqopt
->dqio_sem
);
185 /* Write information header to quota file */
186 static int v2_write_file_info(struct super_block
*sb
, int type
)
188 struct v2_disk_dqinfo dinfo
;
189 struct quota_info
*dqopt
= sb_dqopt(sb
);
190 struct mem_dqinfo
*info
= &dqopt
->info
[type
];
191 struct qtree_mem_dqinfo
*qinfo
= info
->dqi_priv
;
194 down_write(&dqopt
->dqio_sem
);
195 spin_lock(&dq_data_lock
);
196 info
->dqi_flags
&= ~DQF_INFO_DIRTY
;
197 dinfo
.dqi_bgrace
= cpu_to_le32(info
->dqi_bgrace
);
198 dinfo
.dqi_igrace
= cpu_to_le32(info
->dqi_igrace
);
199 /* No flags currently supported */
200 dinfo
.dqi_flags
= cpu_to_le32(0);
201 spin_unlock(&dq_data_lock
);
202 dinfo
.dqi_blocks
= cpu_to_le32(qinfo
->dqi_blocks
);
203 dinfo
.dqi_free_blk
= cpu_to_le32(qinfo
->dqi_free_blk
);
204 dinfo
.dqi_free_entry
= cpu_to_le32(qinfo
->dqi_free_entry
);
205 size
= sb
->s_op
->quota_write(sb
, type
, (char *)&dinfo
,
206 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
207 up_write(&dqopt
->dqio_sem
);
208 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
209 quota_error(sb
, "Can't write info structure");
215 static void v2r0_disk2memdqb(struct dquot
*dquot
, void *dp
)
217 struct v2r0_disk_dqblk
*d
= dp
, empty
;
218 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
220 m
->dqb_ihardlimit
= le32_to_cpu(d
->dqb_ihardlimit
);
221 m
->dqb_isoftlimit
= le32_to_cpu(d
->dqb_isoftlimit
);
222 m
->dqb_curinodes
= le32_to_cpu(d
->dqb_curinodes
);
223 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
224 m
->dqb_bhardlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bhardlimit
));
225 m
->dqb_bsoftlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bsoftlimit
));
226 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
227 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
228 /* We need to escape back all-zero structure */
229 memset(&empty
, 0, sizeof(struct v2r0_disk_dqblk
));
230 empty
.dqb_itime
= cpu_to_le64(1);
231 if (!memcmp(&empty
, dp
, sizeof(struct v2r0_disk_dqblk
)))
235 static void v2r0_mem2diskdqb(void *dp
, struct dquot
*dquot
)
237 struct v2r0_disk_dqblk
*d
= dp
;
238 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
239 struct qtree_mem_dqinfo
*info
=
240 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
242 d
->dqb_ihardlimit
= cpu_to_le32(m
->dqb_ihardlimit
);
243 d
->dqb_isoftlimit
= cpu_to_le32(m
->dqb_isoftlimit
);
244 d
->dqb_curinodes
= cpu_to_le32(m
->dqb_curinodes
);
245 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
246 d
->dqb_bhardlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bhardlimit
));
247 d
->dqb_bsoftlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bsoftlimit
));
248 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
249 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
250 d
->dqb_id
= cpu_to_le32(from_kqid(&init_user_ns
, dquot
->dq_id
));
251 if (qtree_entry_unused(info
, dp
))
252 d
->dqb_itime
= cpu_to_le64(1);
255 static int v2r0_is_id(void *dp
, struct dquot
*dquot
)
257 struct v2r0_disk_dqblk
*d
= dp
;
258 struct qtree_mem_dqinfo
*info
=
259 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
261 if (qtree_entry_unused(info
, dp
))
263 return qid_eq(make_kqid(&init_user_ns
, dquot
->dq_id
.type
,
264 le32_to_cpu(d
->dqb_id
)),
268 static void v2r1_disk2memdqb(struct dquot
*dquot
, void *dp
)
270 struct v2r1_disk_dqblk
*d
= dp
, empty
;
271 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
273 m
->dqb_ihardlimit
= le64_to_cpu(d
->dqb_ihardlimit
);
274 m
->dqb_isoftlimit
= le64_to_cpu(d
->dqb_isoftlimit
);
275 m
->dqb_curinodes
= le64_to_cpu(d
->dqb_curinodes
);
276 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
277 m
->dqb_bhardlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bhardlimit
));
278 m
->dqb_bsoftlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bsoftlimit
));
279 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
280 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
281 /* We need to escape back all-zero structure */
282 memset(&empty
, 0, sizeof(struct v2r1_disk_dqblk
));
283 empty
.dqb_itime
= cpu_to_le64(1);
284 if (!memcmp(&empty
, dp
, sizeof(struct v2r1_disk_dqblk
)))
288 static void v2r1_mem2diskdqb(void *dp
, struct dquot
*dquot
)
290 struct v2r1_disk_dqblk
*d
= dp
;
291 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
292 struct qtree_mem_dqinfo
*info
=
293 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
295 d
->dqb_ihardlimit
= cpu_to_le64(m
->dqb_ihardlimit
);
296 d
->dqb_isoftlimit
= cpu_to_le64(m
->dqb_isoftlimit
);
297 d
->dqb_curinodes
= cpu_to_le64(m
->dqb_curinodes
);
298 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
299 d
->dqb_bhardlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bhardlimit
));
300 d
->dqb_bsoftlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bsoftlimit
));
301 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
302 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
303 d
->dqb_id
= cpu_to_le32(from_kqid(&init_user_ns
, dquot
->dq_id
));
305 if (qtree_entry_unused(info
, dp
))
306 d
->dqb_itime
= cpu_to_le64(1);
309 static int v2r1_is_id(void *dp
, struct dquot
*dquot
)
311 struct v2r1_disk_dqblk
*d
= dp
;
312 struct qtree_mem_dqinfo
*info
=
313 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
315 if (qtree_entry_unused(info
, dp
))
317 return qid_eq(make_kqid(&init_user_ns
, dquot
->dq_id
.type
,
318 le32_to_cpu(d
->dqb_id
)),
322 static int v2_read_dquot(struct dquot
*dquot
)
324 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
327 down_read(&dqopt
->dqio_sem
);
328 ret
= qtree_read_dquot(
329 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
,
331 up_read(&dqopt
->dqio_sem
);
335 static int v2_write_dquot(struct dquot
*dquot
)
337 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
342 * If space for dquot is already allocated, we don't need any
343 * protection as we'll only overwrite the place of dquot. We are
344 * still protected by concurrent writes of the same dquot by
347 if (!dquot
->dq_off
) {
349 down_write(&dqopt
->dqio_sem
);
351 down_read(&dqopt
->dqio_sem
);
353 ret
= qtree_write_dquot(
354 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
,
357 up_write(&dqopt
->dqio_sem
);
359 up_read(&dqopt
->dqio_sem
);
363 static int v2_release_dquot(struct dquot
*dquot
)
365 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
368 down_write(&dqopt
->dqio_sem
);
369 ret
= qtree_release_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
, dquot
);
370 up_write(&dqopt
->dqio_sem
);
375 static int v2_free_file_info(struct super_block
*sb
, int type
)
377 kfree(sb_dqinfo(sb
, type
)->dqi_priv
);
381 static int v2_get_next_id(struct super_block
*sb
, struct kqid
*qid
)
383 struct quota_info
*dqopt
= sb_dqopt(sb
);
386 down_read(&dqopt
->dqio_sem
);
387 ret
= qtree_get_next_id(sb_dqinfo(sb
, qid
->type
)->dqi_priv
, qid
);
388 up_read(&dqopt
->dqio_sem
);
392 static const struct quota_format_ops v2_format_ops
= {
393 .check_quota_file
= v2_check_quota_file
,
394 .read_file_info
= v2_read_file_info
,
395 .write_file_info
= v2_write_file_info
,
396 .free_file_info
= v2_free_file_info
,
397 .read_dqblk
= v2_read_dquot
,
398 .commit_dqblk
= v2_write_dquot
,
399 .release_dqblk
= v2_release_dquot
,
400 .get_next_id
= v2_get_next_id
,
403 static struct quota_format_type v2r0_quota_format
= {
404 .qf_fmt_id
= QFMT_VFS_V0
,
405 .qf_ops
= &v2_format_ops
,
406 .qf_owner
= THIS_MODULE
409 static struct quota_format_type v2r1_quota_format
= {
410 .qf_fmt_id
= QFMT_VFS_V1
,
411 .qf_ops
= &v2_format_ops
,
412 .qf_owner
= THIS_MODULE
415 static int __init
init_v2_quota_format(void)
419 ret
= register_quota_format(&v2r0_quota_format
);
422 return register_quota_format(&v2r1_quota_format
);
425 static void __exit
exit_v2_quota_format(void)
427 unregister_quota_format(&v2r0_quota_format
);
428 unregister_quota_format(&v2r1_quota_format
);
431 module_init(init_v2_quota_format
);
432 module_exit(exit_v2_quota_format
);