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 struct qtree_fmt_operations v2r0_qtree_ops
= {
34 .mem2disk_dqblk
= v2r0_mem2diskdqb
,
35 .disk2mem_dqblk
= v2r0_disk2memdqb
,
39 static 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
);
73 /* Check whether given file is really vfsv0 quotafile */
74 static int v2_check_quota_file(struct super_block
*sb
, int type
)
76 struct v2_disk_dqheader dqhead
;
77 static const uint quota_magics
[] = V2_INITQMAGICS
;
78 static const uint quota_versions
[] = V2_INITQVERSIONS
;
80 if (!v2_read_header(sb
, type
, &dqhead
))
82 if (le32_to_cpu(dqhead
.dqh_magic
) != quota_magics
[type
] ||
83 le32_to_cpu(dqhead
.dqh_version
) > quota_versions
[type
])
88 /* Read information header from quota file */
89 static int v2_read_file_info(struct super_block
*sb
, int type
)
91 struct v2_disk_dqinfo dinfo
;
92 struct v2_disk_dqheader dqhead
;
93 struct mem_dqinfo
*info
= sb_dqinfo(sb
, type
);
94 struct qtree_mem_dqinfo
*qinfo
;
98 if (!v2_read_header(sb
, type
, &dqhead
))
100 version
= le32_to_cpu(dqhead
.dqh_version
);
101 if ((info
->dqi_fmt_id
== QFMT_VFS_V0
&& version
!= 0) ||
102 (info
->dqi_fmt_id
== QFMT_VFS_V1
&& version
!= 1))
105 size
= sb
->s_op
->quota_read(sb
, type
, (char *)&dinfo
,
106 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
107 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
108 quota_error(sb
, "Can't read info structure");
111 info
->dqi_priv
= kmalloc(sizeof(struct qtree_mem_dqinfo
), GFP_NOFS
);
112 if (!info
->dqi_priv
) {
114 "Not enough memory for quota information structure.\n");
117 qinfo
= info
->dqi_priv
;
119 /* limits are stored as unsigned 32-bit data */
120 info
->dqi_maxblimit
= 0xffffffff;
121 info
->dqi_maxilimit
= 0xffffffff;
123 /* used space is stored as unsigned 64-bit value */
124 info
->dqi_maxblimit
= 0xffffffffffffffffULL
; /* 2^64-1 */
125 info
->dqi_maxilimit
= 0xffffffffffffffffULL
;
127 info
->dqi_bgrace
= le32_to_cpu(dinfo
.dqi_bgrace
);
128 info
->dqi_igrace
= le32_to_cpu(dinfo
.dqi_igrace
);
129 info
->dqi_flags
= le32_to_cpu(dinfo
.dqi_flags
);
131 qinfo
->dqi_type
= type
;
132 qinfo
->dqi_blocks
= le32_to_cpu(dinfo
.dqi_blocks
);
133 qinfo
->dqi_free_blk
= le32_to_cpu(dinfo
.dqi_free_blk
);
134 qinfo
->dqi_free_entry
= le32_to_cpu(dinfo
.dqi_free_entry
);
135 qinfo
->dqi_blocksize_bits
= V2_DQBLKSIZE_BITS
;
136 qinfo
->dqi_usable_bs
= 1 << V2_DQBLKSIZE_BITS
;
137 qinfo
->dqi_qtree_depth
= qtree_depth(qinfo
);
139 qinfo
->dqi_entry_size
= sizeof(struct v2r0_disk_dqblk
);
140 qinfo
->dqi_ops
= &v2r0_qtree_ops
;
142 qinfo
->dqi_entry_size
= sizeof(struct v2r1_disk_dqblk
);
143 qinfo
->dqi_ops
= &v2r1_qtree_ops
;
148 /* Write information header to quota file */
149 static int v2_write_file_info(struct super_block
*sb
, int type
)
151 struct v2_disk_dqinfo dinfo
;
152 struct mem_dqinfo
*info
= sb_dqinfo(sb
, type
);
153 struct qtree_mem_dqinfo
*qinfo
= info
->dqi_priv
;
156 spin_lock(&dq_data_lock
);
157 info
->dqi_flags
&= ~DQF_INFO_DIRTY
;
158 dinfo
.dqi_bgrace
= cpu_to_le32(info
->dqi_bgrace
);
159 dinfo
.dqi_igrace
= cpu_to_le32(info
->dqi_igrace
);
160 dinfo
.dqi_flags
= cpu_to_le32(info
->dqi_flags
& DQF_MASK
);
161 spin_unlock(&dq_data_lock
);
162 dinfo
.dqi_blocks
= cpu_to_le32(qinfo
->dqi_blocks
);
163 dinfo
.dqi_free_blk
= cpu_to_le32(qinfo
->dqi_free_blk
);
164 dinfo
.dqi_free_entry
= cpu_to_le32(qinfo
->dqi_free_entry
);
165 size
= sb
->s_op
->quota_write(sb
, type
, (char *)&dinfo
,
166 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
167 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
168 quota_error(sb
, "Can't write info structure");
174 static void v2r0_disk2memdqb(struct dquot
*dquot
, void *dp
)
176 struct v2r0_disk_dqblk
*d
= dp
, empty
;
177 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
179 m
->dqb_ihardlimit
= le32_to_cpu(d
->dqb_ihardlimit
);
180 m
->dqb_isoftlimit
= le32_to_cpu(d
->dqb_isoftlimit
);
181 m
->dqb_curinodes
= le32_to_cpu(d
->dqb_curinodes
);
182 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
183 m
->dqb_bhardlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bhardlimit
));
184 m
->dqb_bsoftlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bsoftlimit
));
185 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
186 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
187 /* We need to escape back all-zero structure */
188 memset(&empty
, 0, sizeof(struct v2r0_disk_dqblk
));
189 empty
.dqb_itime
= cpu_to_le64(1);
190 if (!memcmp(&empty
, dp
, sizeof(struct v2r0_disk_dqblk
)))
194 static void v2r0_mem2diskdqb(void *dp
, struct dquot
*dquot
)
196 struct v2r0_disk_dqblk
*d
= dp
;
197 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
198 struct qtree_mem_dqinfo
*info
=
199 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
201 d
->dqb_ihardlimit
= cpu_to_le32(m
->dqb_ihardlimit
);
202 d
->dqb_isoftlimit
= cpu_to_le32(m
->dqb_isoftlimit
);
203 d
->dqb_curinodes
= cpu_to_le32(m
->dqb_curinodes
);
204 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
205 d
->dqb_bhardlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bhardlimit
));
206 d
->dqb_bsoftlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bsoftlimit
));
207 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
208 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
209 d
->dqb_id
= cpu_to_le32(from_kqid(&init_user_ns
, dquot
->dq_id
));
210 if (qtree_entry_unused(info
, dp
))
211 d
->dqb_itime
= cpu_to_le64(1);
214 static int v2r0_is_id(void *dp
, struct dquot
*dquot
)
216 struct v2r0_disk_dqblk
*d
= dp
;
217 struct qtree_mem_dqinfo
*info
=
218 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
220 if (qtree_entry_unused(info
, dp
))
222 return qid_eq(make_kqid(&init_user_ns
, dquot
->dq_id
.type
,
223 le32_to_cpu(d
->dqb_id
)),
227 static void v2r1_disk2memdqb(struct dquot
*dquot
, void *dp
)
229 struct v2r1_disk_dqblk
*d
= dp
, empty
;
230 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
232 m
->dqb_ihardlimit
= le64_to_cpu(d
->dqb_ihardlimit
);
233 m
->dqb_isoftlimit
= le64_to_cpu(d
->dqb_isoftlimit
);
234 m
->dqb_curinodes
= le64_to_cpu(d
->dqb_curinodes
);
235 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
236 m
->dqb_bhardlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bhardlimit
));
237 m
->dqb_bsoftlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bsoftlimit
));
238 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
239 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
240 /* We need to escape back all-zero structure */
241 memset(&empty
, 0, sizeof(struct v2r1_disk_dqblk
));
242 empty
.dqb_itime
= cpu_to_le64(1);
243 if (!memcmp(&empty
, dp
, sizeof(struct v2r1_disk_dqblk
)))
247 static void v2r1_mem2diskdqb(void *dp
, struct dquot
*dquot
)
249 struct v2r1_disk_dqblk
*d
= dp
;
250 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
251 struct qtree_mem_dqinfo
*info
=
252 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
254 d
->dqb_ihardlimit
= cpu_to_le64(m
->dqb_ihardlimit
);
255 d
->dqb_isoftlimit
= cpu_to_le64(m
->dqb_isoftlimit
);
256 d
->dqb_curinodes
= cpu_to_le64(m
->dqb_curinodes
);
257 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
258 d
->dqb_bhardlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bhardlimit
));
259 d
->dqb_bsoftlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bsoftlimit
));
260 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
261 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
262 d
->dqb_id
= cpu_to_le32(from_kqid(&init_user_ns
, dquot
->dq_id
));
263 if (qtree_entry_unused(info
, dp
))
264 d
->dqb_itime
= cpu_to_le64(1);
267 static int v2r1_is_id(void *dp
, struct dquot
*dquot
)
269 struct v2r1_disk_dqblk
*d
= dp
;
270 struct qtree_mem_dqinfo
*info
=
271 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
;
273 if (qtree_entry_unused(info
, dp
))
275 return qid_eq(make_kqid(&init_user_ns
, dquot
->dq_id
.type
,
276 le32_to_cpu(d
->dqb_id
)),
280 static int v2_read_dquot(struct dquot
*dquot
)
282 return qtree_read_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
, dquot
);
285 static int v2_write_dquot(struct dquot
*dquot
)
287 return qtree_write_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
, dquot
);
290 static int v2_release_dquot(struct dquot
*dquot
)
292 return qtree_release_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
)->dqi_priv
, dquot
);
295 static int v2_free_file_info(struct super_block
*sb
, int type
)
297 kfree(sb_dqinfo(sb
, type
)->dqi_priv
);
301 static const struct quota_format_ops v2_format_ops
= {
302 .check_quota_file
= v2_check_quota_file
,
303 .read_file_info
= v2_read_file_info
,
304 .write_file_info
= v2_write_file_info
,
305 .free_file_info
= v2_free_file_info
,
306 .read_dqblk
= v2_read_dquot
,
307 .commit_dqblk
= v2_write_dquot
,
308 .release_dqblk
= v2_release_dquot
,
311 static struct quota_format_type v2r0_quota_format
= {
312 .qf_fmt_id
= QFMT_VFS_V0
,
313 .qf_ops
= &v2_format_ops
,
314 .qf_owner
= THIS_MODULE
317 static struct quota_format_type v2r1_quota_format
= {
318 .qf_fmt_id
= QFMT_VFS_V1
,
319 .qf_ops
= &v2_format_ops
,
320 .qf_owner
= THIS_MODULE
323 static int __init
init_v2_quota_format(void)
327 ret
= register_quota_format(&v2r0_quota_format
);
330 return register_quota_format(&v2r1_quota_format
);
333 static void __exit
exit_v2_quota_format(void)
335 unregister_quota_format(&v2r0_quota_format
);
336 unregister_quota_format(&v2r1_quota_format
);
339 module_init(init_v2_quota_format
);
340 module_exit(exit_v2_quota_format
);