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 v2_mem2diskdqb(void *dp
, struct dquot
*dquot
);
27 static void v2_disk2memdqb(struct dquot
*dquot
, void *dp
);
28 static int v2_is_id(void *dp
, struct dquot
*dquot
);
30 static struct qtree_fmt_operations v2_qtree_ops
= {
31 .mem2disk_dqblk
= v2_mem2diskdqb
,
32 .disk2mem_dqblk
= v2_disk2memdqb
,
36 #define QUOTABLOCK_BITS 10
37 #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
39 static inline qsize_t
v2_stoqb(qsize_t space
)
41 return (space
+ QUOTABLOCK_SIZE
- 1) >> QUOTABLOCK_BITS
;
44 static inline qsize_t
v2_qbtos(qsize_t blocks
)
46 return blocks
<< QUOTABLOCK_BITS
;
49 /* Check whether given file is really vfsv0 quotafile */
50 static int v2_check_quota_file(struct super_block
*sb
, int type
)
52 struct v2_disk_dqheader dqhead
;
54 static const uint quota_magics
[] = V2_INITQMAGICS
;
55 static const uint quota_versions
[] = V2_INITQVERSIONS
;
57 size
= sb
->s_op
->quota_read(sb
, type
, (char *)&dqhead
, sizeof(struct v2_disk_dqheader
), 0);
58 if (size
!= sizeof(struct v2_disk_dqheader
)) {
59 printk("quota_v2: failed read expected=%zd got=%zd\n",
60 sizeof(struct v2_disk_dqheader
), size
);
63 if (le32_to_cpu(dqhead
.dqh_magic
) != quota_magics
[type
] ||
64 le32_to_cpu(dqhead
.dqh_version
) != quota_versions
[type
])
69 /* Read information header from quota file */
70 static int v2_read_file_info(struct super_block
*sb
, int type
)
72 struct v2_disk_dqinfo dinfo
;
73 struct mem_dqinfo
*info
= sb_dqinfo(sb
, type
);
74 struct qtree_mem_dqinfo
*qinfo
;
77 size
= sb
->s_op
->quota_read(sb
, type
, (char *)&dinfo
,
78 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
79 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
80 printk(KERN_WARNING
"Can't read info structure on device %s.\n",
84 info
->dqi_priv
= kmalloc(sizeof(struct qtree_mem_dqinfo
), GFP_NOFS
);
85 if (!info
->dqi_priv
) {
87 "Not enough memory for quota information structure.\n");
90 qinfo
= info
->dqi_priv
;
91 /* limits are stored as unsigned 32-bit data */
92 info
->dqi_maxblimit
= 0xffffffff;
93 info
->dqi_maxilimit
= 0xffffffff;
94 info
->dqi_bgrace
= le32_to_cpu(dinfo
.dqi_bgrace
);
95 info
->dqi_igrace
= le32_to_cpu(dinfo
.dqi_igrace
);
96 info
->dqi_flags
= le32_to_cpu(dinfo
.dqi_flags
);
98 qinfo
->dqi_type
= type
;
99 qinfo
->dqi_blocks
= le32_to_cpu(dinfo
.dqi_blocks
);
100 qinfo
->dqi_free_blk
= le32_to_cpu(dinfo
.dqi_free_blk
);
101 qinfo
->dqi_free_entry
= le32_to_cpu(dinfo
.dqi_free_entry
);
102 qinfo
->dqi_blocksize_bits
= V2_DQBLKSIZE_BITS
;
103 qinfo
->dqi_usable_bs
= 1 << V2_DQBLKSIZE_BITS
;
104 qinfo
->dqi_qtree_depth
= qtree_depth(qinfo
);
105 qinfo
->dqi_entry_size
= sizeof(struct v2_disk_dqblk
);
106 qinfo
->dqi_ops
= &v2_qtree_ops
;
110 /* Write information header to quota file */
111 static int v2_write_file_info(struct super_block
*sb
, int type
)
113 struct v2_disk_dqinfo dinfo
;
114 struct mem_dqinfo
*info
= sb_dqinfo(sb
, type
);
115 struct qtree_mem_dqinfo
*qinfo
= info
->dqi_priv
;
118 spin_lock(&dq_data_lock
);
119 info
->dqi_flags
&= ~DQF_INFO_DIRTY
;
120 dinfo
.dqi_bgrace
= cpu_to_le32(info
->dqi_bgrace
);
121 dinfo
.dqi_igrace
= cpu_to_le32(info
->dqi_igrace
);
122 dinfo
.dqi_flags
= cpu_to_le32(info
->dqi_flags
& DQF_MASK
);
123 spin_unlock(&dq_data_lock
);
124 dinfo
.dqi_blocks
= cpu_to_le32(qinfo
->dqi_blocks
);
125 dinfo
.dqi_free_blk
= cpu_to_le32(qinfo
->dqi_free_blk
);
126 dinfo
.dqi_free_entry
= cpu_to_le32(qinfo
->dqi_free_entry
);
127 size
= sb
->s_op
->quota_write(sb
, type
, (char *)&dinfo
,
128 sizeof(struct v2_disk_dqinfo
), V2_DQINFOOFF
);
129 if (size
!= sizeof(struct v2_disk_dqinfo
)) {
130 printk(KERN_WARNING
"Can't write info structure on device %s.\n",
137 static void v2_disk2memdqb(struct dquot
*dquot
, void *dp
)
139 struct v2_disk_dqblk
*d
= dp
, empty
;
140 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
142 m
->dqb_ihardlimit
= le32_to_cpu(d
->dqb_ihardlimit
);
143 m
->dqb_isoftlimit
= le32_to_cpu(d
->dqb_isoftlimit
);
144 m
->dqb_curinodes
= le32_to_cpu(d
->dqb_curinodes
);
145 m
->dqb_itime
= le64_to_cpu(d
->dqb_itime
);
146 m
->dqb_bhardlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bhardlimit
));
147 m
->dqb_bsoftlimit
= v2_qbtos(le32_to_cpu(d
->dqb_bsoftlimit
));
148 m
->dqb_curspace
= le64_to_cpu(d
->dqb_curspace
);
149 m
->dqb_btime
= le64_to_cpu(d
->dqb_btime
);
150 /* We need to escape back all-zero structure */
151 memset(&empty
, 0, sizeof(struct v2_disk_dqblk
));
152 empty
.dqb_itime
= cpu_to_le64(1);
153 if (!memcmp(&empty
, dp
, sizeof(struct v2_disk_dqblk
)))
157 static void v2_mem2diskdqb(void *dp
, struct dquot
*dquot
)
159 struct v2_disk_dqblk
*d
= dp
;
160 struct mem_dqblk
*m
= &dquot
->dq_dqb
;
161 struct qtree_mem_dqinfo
*info
=
162 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
;
164 d
->dqb_ihardlimit
= cpu_to_le32(m
->dqb_ihardlimit
);
165 d
->dqb_isoftlimit
= cpu_to_le32(m
->dqb_isoftlimit
);
166 d
->dqb_curinodes
= cpu_to_le32(m
->dqb_curinodes
);
167 d
->dqb_itime
= cpu_to_le64(m
->dqb_itime
);
168 d
->dqb_bhardlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bhardlimit
));
169 d
->dqb_bsoftlimit
= cpu_to_le32(v2_stoqb(m
->dqb_bsoftlimit
));
170 d
->dqb_curspace
= cpu_to_le64(m
->dqb_curspace
);
171 d
->dqb_btime
= cpu_to_le64(m
->dqb_btime
);
172 d
->dqb_id
= cpu_to_le32(dquot
->dq_id
);
173 if (qtree_entry_unused(info
, dp
))
174 d
->dqb_itime
= cpu_to_le64(1);
177 static int v2_is_id(void *dp
, struct dquot
*dquot
)
179 struct v2_disk_dqblk
*d
= dp
;
180 struct qtree_mem_dqinfo
*info
=
181 sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
;
183 if (qtree_entry_unused(info
, dp
))
185 return le32_to_cpu(d
->dqb_id
) == dquot
->dq_id
;
188 static int v2_read_dquot(struct dquot
*dquot
)
190 return qtree_read_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
, dquot
);
193 static int v2_write_dquot(struct dquot
*dquot
)
195 return qtree_write_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
, dquot
);
198 static int v2_release_dquot(struct dquot
*dquot
)
200 return qtree_release_dquot(sb_dqinfo(dquot
->dq_sb
, dquot
->dq_type
)->dqi_priv
, dquot
);
203 static int v2_free_file_info(struct super_block
*sb
, int type
)
205 kfree(sb_dqinfo(sb
, type
)->dqi_priv
);
209 static struct quota_format_ops v2_format_ops
= {
210 .check_quota_file
= v2_check_quota_file
,
211 .read_file_info
= v2_read_file_info
,
212 .write_file_info
= v2_write_file_info
,
213 .free_file_info
= v2_free_file_info
,
214 .read_dqblk
= v2_read_dquot
,
215 .commit_dqblk
= v2_write_dquot
,
216 .release_dqblk
= v2_release_dquot
,
219 static struct quota_format_type v2_quota_format
= {
220 .qf_fmt_id
= QFMT_VFS_V0
,
221 .qf_ops
= &v2_format_ops
,
222 .qf_owner
= THIS_MODULE
225 static int __init
init_v2_quota_format(void)
227 return register_quota_format(&v2_quota_format
);
230 static void __exit
exit_v2_quota_format(void)
232 unregister_quota_format(&v2_quota_format
);
235 module_init(init_v2_quota_format
);
236 module_exit(exit_v2_quota_format
);