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 printk(KERN_WARNING
"quota_v2: Failed header read:"
67 " expected=%zd got=%zd\n",
68 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 mem_dqinfo
*info
= sb_dqinfo(sb
, type
);
95 struct qtree_mem_dqinfo
*qinfo
;
99 if (!v2_read_header(sb
, type
, &dqhead
))
101 version
= le32_to_cpu(dqhead
.dqh_version
);
102 if ((info
->dqi_fmt_id
== QFMT_VFS_V0
&& version
!= 0) ||
103 (info
->dqi_fmt_id
== QFMT_VFS_V1
&& version
!= 1))
106 size
= sb
->s_op
->quota_read(sb
, type
, (char *)&dinfo
,
107 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
108 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
109 printk(KERN_WARNING
"quota_v2: Can't read info structure on device %s.\n",
113 info
->dqi_priv
= kmalloc(sizeof(struct qtree_mem_dqinfo
), GFP_NOFS
);
114 if (!info
->dqi_priv
) {
116 "Not enough memory for quota information structure.\n");
119 qinfo
= info
->dqi_priv
;
121 /* limits are stored as unsigned 32-bit data */
122 info
->dqi_maxblimit
= 0xffffffff;
123 info
->dqi_maxilimit
= 0xffffffff;
125 /* used space is stored as unsigned 64-bit value */
126 info
->dqi_maxblimit
= 0xffffffffffffffffULL
; /* 2^64-1 */
127 info
->dqi_maxilimit
= 0xffffffffffffffffULL
;
129 info
->dqi_bgrace
= le32_to_cpu(dinfo
.dqi_bgrace
);
130 info
->dqi_igrace
= le32_to_cpu(dinfo
.dqi_igrace
);
131 info
->dqi_flags
= le32_to_cpu(dinfo
.dqi_flags
);
133 qinfo
->dqi_type
= type
;
134 qinfo
->dqi_blocks
= le32_to_cpu(dinfo
.dqi_blocks
);
135 qinfo
->dqi_free_blk
= le32_to_cpu(dinfo
.dqi_free_blk
);
136 qinfo
->dqi_free_entry
= le32_to_cpu(dinfo
.dqi_free_entry
);
137 qinfo
->dqi_blocksize_bits
= V2_DQBLKSIZE_BITS
;
138 qinfo
->dqi_usable_bs
= 1 << V2_DQBLKSIZE_BITS
;
139 qinfo
->dqi_qtree_depth
= qtree_depth(qinfo
);
141 qinfo
->dqi_entry_size
= sizeof(struct v2r0_disk_dqblk
);
142 qinfo
->dqi_ops
= &v2r0_qtree_ops
;
144 qinfo
->dqi_entry_size
= sizeof(struct v2r1_disk_dqblk
);
145 qinfo
->dqi_ops
= &v2r1_qtree_ops
;
150 /* Write information header to quota file */
151 static int v2_write_file_info(struct super_block
*sb
, int type
)
153 struct v2_disk_dqinfo dinfo
;
154 struct mem_dqinfo
*info
= sb_dqinfo(sb
, type
);
155 struct qtree_mem_dqinfo
*qinfo
= info
->dqi_priv
;
158 spin_lock(&dq_data_lock
);
159 info
->dqi_flags
&= ~DQF_INFO_DIRTY
;
160 dinfo
.dqi_bgrace
= cpu_to_le32(info
->dqi_bgrace
);
161 dinfo
.dqi_igrace
= cpu_to_le32(info
->dqi_igrace
);
162 dinfo
.dqi_flags
= cpu_to_le32(info
->dqi_flags
& DQF_MASK
);
163 spin_unlock(&dq_data_lock
);
164 dinfo
.dqi_blocks
= cpu_to_le32(qinfo
->dqi_blocks
);
165 dinfo
.dqi_free_blk
= cpu_to_le32(qinfo
->dqi_free_blk
);
166 dinfo
.dqi_free_entry
= cpu_to_le32(qinfo
->dqi_free_entry
);
167 size
= sb
->s_op
->quota_write(sb
, type
, (char *)&dinfo
,
168 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
169 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
170 printk(KERN_WARNING
"Can't write info structure on device %s.\n",
177 static void v2r0_disk2memdqb(struct dquot
*dquot
, void *dp
)
179 struct v2r0_disk_dqblk
*d
= dp
, empty
;
180 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
182 m
->dqb_ihardlimit
= le32_to_cpu(d
->dqb_ihardlimit
);
183 m
->dqb_isoftlimit
= le32_to_cpu(d
->dqb_isoftlimit
);
184 m
->dqb_curinodes
= le32_to_cpu(d
->dqb_curinodes
);
185 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
186 m
->dqb_bhardlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bhardlimit
));
187 m
->dqb_bsoftlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bsoftlimit
));
188 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
189 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
190 /* We need to escape back all-zero structure */
191 memset(&empty
, 0, sizeof(struct v2r0_disk_dqblk
));
192 empty
.dqb_itime
= cpu_to_le64(1);
193 if (!memcmp(&empty
, dp
, sizeof(struct v2r0_disk_dqblk
)))
197 static void v2r0_mem2diskdqb(void *dp
, struct dquot
*dquot
)
199 struct v2r0_disk_dqblk
*d
= dp
;
200 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
201 struct qtree_mem_dqinfo
*info
=
202 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
;
204 d
->dqb_ihardlimit
= cpu_to_le32(m
->dqb_ihardlimit
);
205 d
->dqb_isoftlimit
= cpu_to_le32(m
->dqb_isoftlimit
);
206 d
->dqb_curinodes
= cpu_to_le32(m
->dqb_curinodes
);
207 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
208 d
->dqb_bhardlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bhardlimit
));
209 d
->dqb_bsoftlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bsoftlimit
));
210 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
211 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
212 d
->dqb_id
= cpu_to_le32(dquot
->dq_id
);
213 if (qtree_entry_unused(info
, dp
))
214 d
->dqb_itime
= cpu_to_le64(1);
217 static int v2r0_is_id(void *dp
, struct dquot
*dquot
)
219 struct v2r0_disk_dqblk
*d
= dp
;
220 struct qtree_mem_dqinfo
*info
=
221 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
;
223 if (qtree_entry_unused(info
, dp
))
225 return le32_to_cpu(d
->dqb_id
) == dquot
->dq_id
;
228 static void v2r1_disk2memdqb(struct dquot
*dquot
, void *dp
)
230 struct v2r1_disk_dqblk
*d
= dp
, empty
;
231 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
233 m
->dqb_ihardlimit
= le64_to_cpu(d
->dqb_ihardlimit
);
234 m
->dqb_isoftlimit
= le64_to_cpu(d
->dqb_isoftlimit
);
235 m
->dqb_curinodes
= le64_to_cpu(d
->dqb_curinodes
);
236 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
237 m
->dqb_bhardlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bhardlimit
));
238 m
->dqb_bsoftlimit
= v2_qbtos(le64_to_cpu(d
->dqb_bsoftlimit
));
239 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
240 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
241 /* We need to escape back all-zero structure */
242 memset(&empty
, 0, sizeof(struct v2r1_disk_dqblk
));
243 empty
.dqb_itime
= cpu_to_le64(1);
244 if (!memcmp(&empty
, dp
, sizeof(struct v2r1_disk_dqblk
)))
248 static void v2r1_mem2diskdqb(void *dp
, struct dquot
*dquot
)
250 struct v2r1_disk_dqblk
*d
= dp
;
251 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
252 struct qtree_mem_dqinfo
*info
=
253 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
;
255 d
->dqb_ihardlimit
= cpu_to_le64(m
->dqb_ihardlimit
);
256 d
->dqb_isoftlimit
= cpu_to_le64(m
->dqb_isoftlimit
);
257 d
->dqb_curinodes
= cpu_to_le64(m
->dqb_curinodes
);
258 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
259 d
->dqb_bhardlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bhardlimit
));
260 d
->dqb_bsoftlimit
= cpu_to_le64(v2_stoqb(m
->dqb_bsoftlimit
));
261 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
262 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
263 d
->dqb_id
= cpu_to_le32(dquot
->dq_id
);
264 if (qtree_entry_unused(info
, dp
))
265 d
->dqb_itime
= cpu_to_le64(1);
268 static int v2r1_is_id(void *dp
, struct dquot
*dquot
)
270 struct v2r1_disk_dqblk
*d
= dp
;
271 struct qtree_mem_dqinfo
*info
=
272 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
;
274 if (qtree_entry_unused(info
, dp
))
276 return le32_to_cpu(d
->dqb_id
) == dquot
->dq_id
;
279 static int v2_read_dquot(struct dquot
*dquot
)
281 return qtree_read_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
, dquot
);
284 static int v2_write_dquot(struct dquot
*dquot
)
286 return qtree_write_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
, dquot
);
289 static int v2_release_dquot(struct dquot
*dquot
)
291 return qtree_release_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
, dquot
);
294 static int v2_free_file_info(struct super_block
*sb
, int type
)
296 kfree(sb_dqinfo(sb
, type
)->dqi_priv
);
300 static const struct quota_format_ops v2_format_ops
= {
301 .check_quota_file
= v2_check_quota_file
,
302 .read_file_info
= v2_read_file_info
,
303 .write_file_info
= v2_write_file_info
,
304 .free_file_info
= v2_free_file_info
,
305 .read_dqblk
= v2_read_dquot
,
306 .commit_dqblk
= v2_write_dquot
,
307 .release_dqblk
= v2_release_dquot
,
310 static struct quota_format_type v2r0_quota_format
= {
311 .qf_fmt_id
= QFMT_VFS_V0
,
312 .qf_ops
= &v2_format_ops
,
313 .qf_owner
= THIS_MODULE
316 static struct quota_format_type v2r1_quota_format
= {
317 .qf_fmt_id
= QFMT_VFS_V1
,
318 .qf_ops
= &v2_format_ops
,
319 .qf_owner
= THIS_MODULE
322 static int __init
init_v2_quota_format(void)
326 ret
= register_quota_format(&v2r0_quota_format
);
329 return register_quota_format(&v2r1_quota_format
);
332 static void __exit
exit_v2_quota_format(void)
334 unregister_quota_format(&v2r0_quota_format
);
335 unregister_quota_format(&v2r1_quota_format
);
338 module_init(init_v2_quota_format
);
339 module_exit(exit_v2_quota_format
);