2 * vfsv0 quota IO operations on file
5 #include <linux/errno.h>
7 #include <linux/mount.h>
8 #include <linux/dqblk_v2.h>
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <linux/quotaops.h>
15 #include <asm/byteorder.h>
17 #include "quota_tree.h"
18 #include "quotaio_v2.h"
20 MODULE_AUTHOR("Jan Kara");
21 MODULE_DESCRIPTION("Quota format v2 support");
22 MODULE_LICENSE("GPL");
24 #define __QUOTA_V2_PARANOIA
26 static void v2r0_mem2diskdqb(void *dp
, struct dquot
*dquot
);
27 static void v2r0_disk2memdqb(struct dquot
*dquot
, void *dp
);
28 static int v2r0_is_id(void *dp
, struct dquot
*dquot
);
29 static void v2r1_mem2diskdqb(void *dp
, struct dquot
*dquot
);
30 static void v2r1_disk2memdqb(struct dquot
*dquot
, void *dp
);
31 static int v2r1_is_id(void *dp
, struct dquot
*dquot
);
33 static const struct qtree_fmt_operations v2r0_qtree_ops
= {
34 .mem2disk_dqblk
= v2r0_mem2diskdqb
,
35 .disk2mem_dqblk
= v2r0_disk2memdqb
,
39 static const struct qtree_fmt_operations v2r1_qtree_ops
= {
40 .mem2disk_dqblk
= v2r1_mem2diskdqb
,
41 .disk2mem_dqblk
= v2r1_disk2memdqb
,
45 #define QUOTABLOCK_BITS 10
46 #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
48 static inline qsize_t
v2_stoqb(qsize_t space
)
50 return (space
+ QUOTABLOCK_SIZE
- 1) >> QUOTABLOCK_BITS
;
53 static inline qsize_t
v2_qbtos(qsize_t blocks
)
55 return blocks
<< QUOTABLOCK_BITS
;
58 static int v2_read_header(struct super_block
*sb
, int type
,
59 struct v2_disk_dqheader
*dqhead
)
63 size
= sb
->s_op
->quota_read(sb
, type
, (char *)dqhead
,
64 sizeof(struct v2_disk_dqheader
), 0);
65 if (size
!= sizeof(struct v2_disk_dqheader
)) {
66 quota_error(sb
, "Failed header read: expected=%zd got=%zd",
67 sizeof(struct v2_disk_dqheader
), size
);
75 /* Check whether given file is really vfsv0 quotafile */
76 static int v2_check_quota_file(struct super_block
*sb
, int type
)
78 struct v2_disk_dqheader dqhead
;
79 static const uint quota_magics
[] = V2_INITQMAGICS
;
80 static const uint quota_versions
[] = V2_INITQVERSIONS
;
82 if (v2_read_header(sb
, type
, &dqhead
))
84 if (le32_to_cpu(dqhead
.dqh_magic
) != quota_magics
[type
] ||
85 le32_to_cpu(dqhead
.dqh_version
) > quota_versions
[type
])
90 /* Read information header from quota file */
91 static int v2_read_file_info(struct super_block
*sb
, int type
)
93 struct v2_disk_dqinfo dinfo
;
94 struct v2_disk_dqheader dqhead
;
95 struct quota_info
*dqopt
= sb_dqopt(sb
);
96 struct mem_dqinfo
*info
= &dqopt
->info
[type
];
97 struct qtree_mem_dqinfo
*qinfo
;
102 down_read(&dqopt
->dqio_sem
);
103 ret
= v2_read_header(sb
, type
, &dqhead
);
106 version
= le32_to_cpu(dqhead
.dqh_version
);
107 if ((info
->dqi_fmt_id
== QFMT_VFS_V0
&& version
!= 0) ||
108 (info
->dqi_fmt_id
== QFMT_VFS_V1
&& version
!= 1)) {
113 size
= sb
->s_op
->quota_read(sb
, type
, (char *)&dinfo
,
114 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
115 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
116 quota_error(sb
, "Can't read info structure");
123 info
->dqi_priv
= kmalloc(sizeof(struct qtree_mem_dqinfo
), GFP_NOFS
);
124 if (!info
->dqi_priv
) {
128 qinfo
= info
->dqi_priv
;
130 /* limits are stored as unsigned 32-bit data */
131 info
->dqi_max_spc_limit
= 0xffffffffLL
<< QUOTABLOCK_BITS
;
132 info
->dqi_max_ino_limit
= 0xffffffff;
135 * Used space is stored as unsigned 64-bit value in bytes but
136 * quota core supports only signed 64-bit values so use that
139 info
->dqi_max_spc_limit
= 0x7fffffffffffffffLL
; /* 2^63-1 */
140 info
->dqi_max_ino_limit
= 0x7fffffffffffffffLL
;
142 info
->dqi_bgrace
= le32_to_cpu(dinfo
.dqi_bgrace
);
143 info
->dqi_igrace
= le32_to_cpu(dinfo
.dqi_igrace
);
144 /* No flags currently supported */
147 qinfo
->dqi_type
= type
;
148 qinfo
->dqi_blocks
= le32_to_cpu(dinfo
.dqi_blocks
);
149 qinfo
->dqi_free_blk
= le32_to_cpu(dinfo
.dqi_free_blk
);
150 qinfo
->dqi_free_entry
= le32_to_cpu(dinfo
.dqi_free_entry
);
151 qinfo
->dqi_blocksize_bits
= V2_DQBLKSIZE_BITS
;
152 qinfo
->dqi_usable_bs
= 1 << V2_DQBLKSIZE_BITS
;
153 qinfo
->dqi_qtree_depth
= qtree_depth(qinfo
);
155 qinfo
->dqi_entry_size
= sizeof(struct v2r0_disk_dqblk
);
156 qinfo
->dqi_ops
= &v2r0_qtree_ops
;
158 qinfo
->dqi_entry_size
= sizeof(struct v2r1_disk_dqblk
);
159 qinfo
->dqi_ops
= &v2r1_qtree_ops
;
163 up_read(&dqopt
->dqio_sem
);
167 /* Write information header to quota file */
168 static int v2_write_file_info(struct super_block
*sb
, int type
)
170 struct v2_disk_dqinfo dinfo
;
171 struct quota_info
*dqopt
= sb_dqopt(sb
);
172 struct mem_dqinfo
*info
= &dqopt
->info
[type
];
173 struct qtree_mem_dqinfo
*qinfo
= info
->dqi_priv
;
176 down_write(&dqopt
->dqio_sem
);
177 spin_lock(&dq_data_lock
);
178 info
->dqi_flags
&= ~DQF_INFO_DIRTY
;
179 dinfo
.dqi_bgrace
= cpu_to_le32(info
->dqi_bgrace
);
180 dinfo
.dqi_igrace
= cpu_to_le32(info
->dqi_igrace
);
181 /* No flags currently supported */
182 dinfo
.dqi_flags
= cpu_to_le32(0);
183 spin_unlock(&dq_data_lock
);
184 dinfo
.dqi_blocks
= cpu_to_le32(qinfo
->dqi_blocks
);
185 dinfo
.dqi_free_blk
= cpu_to_le32(qinfo
->dqi_free_blk
);
186 dinfo
.dqi_free_entry
= cpu_to_le32(qinfo
->dqi_free_entry
);
187 size
= sb
->s_op
->quota_write(sb
, type
, (char *)&dinfo
,
188 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
189 up_write(&dqopt
->dqio_sem
);
190 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
191 quota_error(sb
, "Can't write info structure");
197 static void v2r0_disk2memdqb(struct dquot
*dquot
, void *dp
)
199 struct v2r0_disk_dqblk
*d
= dp
, empty
;
200 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
202 m
->dqb_ihardlimit
= le32_to_cpu(d
->dqb_ihardlimit
);
203 m
->dqb_isoftlimit
= le32_to_cpu(d
->dqb_isoftlimit
);
204 m
->dqb_curinodes
= le32_to_cpu(d
->dqb_curinodes
);
205 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
206 m
->dqb_bhardlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bhardlimit
));
207 m
->dqb_bsoftlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bsoftlimit
));
208 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
209 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
210 /* We need to escape back all-zero structure */
211 memset(&empty
, 0, sizeof(struct v2r0_disk_dqblk
));
212 empty
.dqb_itime
= cpu_to_le64(1);
213 if (!memcmp(&empty
, dp
, sizeof(struct v2r0_disk_dqblk
)))
217 static void v2r0_mem2diskdqb(void *dp
, struct dquot
*dquot
)
219 struct v2r0_disk_dqblk
*d
= dp
;
220 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
221 struct qtree_mem_dqinfo
*info
=
222 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
224 d
->dqb_ihardlimit
= cpu_to_le32(m
->dqb_ihardlimit
);
225 d
->dqb_isoftlimit
= cpu_to_le32(m
->dqb_isoftlimit
);
226 d
->dqb_curinodes
= cpu_to_le32(m
->dqb_curinodes
);
227 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
228 d
->dqb_bhardlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bhardlimit
));
229 d
->dqb_bsoftlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bsoftlimit
));
230 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
231 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
232 d
->dqb_id
= cpu_to_le32(from_kqid(&init_user_ns
, dquot
->dq_id
));
233 if (qtree_entry_unused(info
, dp
))
234 d
->dqb_itime
= cpu_to_le64(1);
237 static int v2r0_is_id(void *dp
, struct dquot
*dquot
)
239 struct v2r0_disk_dqblk
*d
= dp
;
240 struct qtree_mem_dqinfo
*info
=
241 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
243 if (qtree_entry_unused(info
, dp
))
245 return qid_eq(make_kqid(&init_user_ns
, dquot
->dq_id
.type
,
246 le32_to_cpu(d
->dqb_id
)),
250 static void v2r1_disk2memdqb(struct dquot
*dquot
, void *dp
)
252 struct v2r1_disk_dqblk
*d
= dp
, empty
;
253 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
255 m
->dqb_ihardlimit
= le64_to_cpu(d
->dqb_ihardlimit
);
256 m
->dqb_isoftlimit
= le64_to_cpu(d
->dqb_isoftlimit
);
257 m
->dqb_curinodes
= le64_to_cpu(d
->dqb_curinodes
);
258 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
259 m
->dqb_bhardlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bhardlimit
));
260 m
->dqb_bsoftlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bsoftlimit
));
261 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
262 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
263 /* We need to escape back all-zero structure */
264 memset(&empty
, 0, sizeof(struct v2r1_disk_dqblk
));
265 empty
.dqb_itime
= cpu_to_le64(1);
266 if (!memcmp(&empty
, dp
, sizeof(struct v2r1_disk_dqblk
)))
270 static void v2r1_mem2diskdqb(void *dp
, struct dquot
*dquot
)
272 struct v2r1_disk_dqblk
*d
= dp
;
273 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
274 struct qtree_mem_dqinfo
*info
=
275 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
277 d
->dqb_ihardlimit
= cpu_to_le64(m
->dqb_ihardlimit
);
278 d
->dqb_isoftlimit
= cpu_to_le64(m
->dqb_isoftlimit
);
279 d
->dqb_curinodes
= cpu_to_le64(m
->dqb_curinodes
);
280 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
281 d
->dqb_bhardlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bhardlimit
));
282 d
->dqb_bsoftlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bsoftlimit
));
283 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
284 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
285 d
->dqb_id
= cpu_to_le32(from_kqid(&init_user_ns
, dquot
->dq_id
));
286 if (qtree_entry_unused(info
, dp
))
287 d
->dqb_itime
= cpu_to_le64(1);
290 static int v2r1_is_id(void *dp
, struct dquot
*dquot
)
292 struct v2r1_disk_dqblk
*d
= dp
;
293 struct qtree_mem_dqinfo
*info
=
294 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
296 if (qtree_entry_unused(info
, dp
))
298 return qid_eq(make_kqid(&init_user_ns
, dquot
->dq_id
.type
,
299 le32_to_cpu(d
->dqb_id
)),
303 static int v2_read_dquot(struct dquot
*dquot
)
305 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
308 down_read(&dqopt
->dqio_sem
);
309 ret
= qtree_read_dquot(
310 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
,
312 up_read(&dqopt
->dqio_sem
);
316 static int v2_write_dquot(struct dquot
*dquot
)
318 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
323 * If space for dquot is already allocated, we don't need any
324 * protection as we'll only overwrite the place of dquot. We are
325 * still protected by concurrent writes of the same dquot by
328 if (!dquot
->dq_off
) {
330 down_write(&dqopt
->dqio_sem
);
332 down_read(&dqopt
->dqio_sem
);
334 ret
= qtree_write_dquot(
335 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
,
338 up_write(&dqopt
->dqio_sem
);
340 up_read(&dqopt
->dqio_sem
);
344 static int v2_release_dquot(struct dquot
*dquot
)
346 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
349 down_write(&dqopt
->dqio_sem
);
350 ret
= qtree_release_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
, dquot
);
351 up_write(&dqopt
->dqio_sem
);
356 static int v2_free_file_info(struct super_block
*sb
, int type
)
358 kfree(sb_dqinfo(sb
, type
)->dqi_priv
);
362 static int v2_get_next_id(struct super_block
*sb
, struct kqid
*qid
)
364 struct quota_info
*dqopt
= sb_dqopt(sb
);
367 down_read(&dqopt
->dqio_sem
);
368 ret
= qtree_get_next_id(sb_dqinfo(sb
, qid
->type
)->dqi_priv
, qid
);
369 up_read(&dqopt
->dqio_sem
);
373 static const struct quota_format_ops v2_format_ops
= {
374 .check_quota_file
= v2_check_quota_file
,
375 .read_file_info
= v2_read_file_info
,
376 .write_file_info
= v2_write_file_info
,
377 .free_file_info
= v2_free_file_info
,
378 .read_dqblk
= v2_read_dquot
,
379 .commit_dqblk
= v2_write_dquot
,
380 .release_dqblk
= v2_release_dquot
,
381 .get_next_id
= v2_get_next_id
,
384 static struct quota_format_type v2r0_quota_format
= {
385 .qf_fmt_id
= QFMT_VFS_V0
,
386 .qf_ops
= &v2_format_ops
,
387 .qf_owner
= THIS_MODULE
390 static struct quota_format_type v2r1_quota_format
= {
391 .qf_fmt_id
= QFMT_VFS_V1
,
392 .qf_ops
= &v2_format_ops
,
393 .qf_owner
= THIS_MODULE
396 static int __init
init_v2_quota_format(void)
400 ret
= register_quota_format(&v2r0_quota_format
);
403 return register_quota_format(&v2r1_quota_format
);
406 static void __exit
exit_v2_quota_format(void)
408 unregister_quota_format(&v2r0_quota_format
);
409 unregister_quota_format(&v2r1_quota_format
);
412 module_init(init_v2_quota_format
);
413 module_exit(exit_v2_quota_format
);