0001
0002
0003
0004
0005
0006 #include <linux/errno.h>
0007 #include <linux/fs.h>
0008 #include <linux/mount.h>
0009 #include <linux/dqblk_v2.h>
0010 #include <linux/kernel.h>
0011 #include <linux/init.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/quotaops.h>
0015
0016 #include <asm/byteorder.h>
0017
0018 #include "quota_tree.h"
0019 #include "quotaio_v2.h"
0020
0021 MODULE_AUTHOR("Jan Kara");
0022 MODULE_DESCRIPTION("Quota format v2 support");
0023 MODULE_LICENSE("GPL");
0024
0025 static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot);
0026 static void v2r0_disk2memdqb(struct dquot *dquot, void *dp);
0027 static int v2r0_is_id(void *dp, struct dquot *dquot);
0028 static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot);
0029 static void v2r1_disk2memdqb(struct dquot *dquot, void *dp);
0030 static int v2r1_is_id(void *dp, struct dquot *dquot);
0031
0032 static const struct qtree_fmt_operations v2r0_qtree_ops = {
0033 .mem2disk_dqblk = v2r0_mem2diskdqb,
0034 .disk2mem_dqblk = v2r0_disk2memdqb,
0035 .is_id = v2r0_is_id,
0036 };
0037
0038 static const struct qtree_fmt_operations v2r1_qtree_ops = {
0039 .mem2disk_dqblk = v2r1_mem2diskdqb,
0040 .disk2mem_dqblk = v2r1_disk2memdqb,
0041 .is_id = v2r1_is_id,
0042 };
0043
0044 #define QUOTABLOCK_BITS 10
0045 #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
0046
0047 static inline qsize_t v2_stoqb(qsize_t space)
0048 {
0049 return (space + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS;
0050 }
0051
0052 static inline qsize_t v2_qbtos(qsize_t blocks)
0053 {
0054 return blocks << QUOTABLOCK_BITS;
0055 }
0056
0057 static int v2_read_header(struct super_block *sb, int type,
0058 struct v2_disk_dqheader *dqhead)
0059 {
0060 ssize_t size;
0061
0062 size = sb->s_op->quota_read(sb, type, (char *)dqhead,
0063 sizeof(struct v2_disk_dqheader), 0);
0064 if (size != sizeof(struct v2_disk_dqheader)) {
0065 quota_error(sb, "Failed header read: expected=%zd got=%zd",
0066 sizeof(struct v2_disk_dqheader), size);
0067 if (size < 0)
0068 return size;
0069 return -EIO;
0070 }
0071 return 0;
0072 }
0073
0074
0075 static int v2_check_quota_file(struct super_block *sb, int type)
0076 {
0077 struct v2_disk_dqheader dqhead;
0078 static const uint quota_magics[] = V2_INITQMAGICS;
0079 static const uint quota_versions[] = V2_INITQVERSIONS;
0080
0081 if (v2_read_header(sb, type, &dqhead))
0082 return 0;
0083 if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
0084 le32_to_cpu(dqhead.dqh_version) > quota_versions[type])
0085 return 0;
0086 return 1;
0087 }
0088
0089
0090 static int v2_read_file_info(struct super_block *sb, int type)
0091 {
0092 struct v2_disk_dqinfo dinfo;
0093 struct v2_disk_dqheader dqhead;
0094 struct quota_info *dqopt = sb_dqopt(sb);
0095 struct mem_dqinfo *info = &dqopt->info[type];
0096 struct qtree_mem_dqinfo *qinfo;
0097 ssize_t size;
0098 unsigned int version;
0099 int ret;
0100
0101 down_read(&dqopt->dqio_sem);
0102 ret = v2_read_header(sb, type, &dqhead);
0103 if (ret < 0)
0104 goto out;
0105 version = le32_to_cpu(dqhead.dqh_version);
0106 if ((info->dqi_fmt_id == QFMT_VFS_V0 && version != 0) ||
0107 (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1)) {
0108 ret = -EINVAL;
0109 goto out;
0110 }
0111
0112 size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
0113 sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
0114 if (size != sizeof(struct v2_disk_dqinfo)) {
0115 quota_error(sb, "Can't read info structure");
0116 if (size < 0)
0117 ret = size;
0118 else
0119 ret = -EIO;
0120 goto out;
0121 }
0122 info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS);
0123 if (!info->dqi_priv) {
0124 ret = -ENOMEM;
0125 goto out;
0126 }
0127 qinfo = info->dqi_priv;
0128 if (version == 0) {
0129
0130 info->dqi_max_spc_limit = 0xffffffffLL << QUOTABLOCK_BITS;
0131 info->dqi_max_ino_limit = 0xffffffff;
0132 } else {
0133
0134
0135
0136
0137
0138 info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
0139 info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
0140 }
0141 info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
0142 info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
0143
0144 info->dqi_flags = 0;
0145 qinfo->dqi_sb = sb;
0146 qinfo->dqi_type = type;
0147 qinfo->dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
0148 qinfo->dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
0149 qinfo->dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
0150 qinfo->dqi_blocksize_bits = V2_DQBLKSIZE_BITS;
0151 qinfo->dqi_usable_bs = 1 << V2_DQBLKSIZE_BITS;
0152 qinfo->dqi_qtree_depth = qtree_depth(qinfo);
0153 if (version == 0) {
0154 qinfo->dqi_entry_size = sizeof(struct v2r0_disk_dqblk);
0155 qinfo->dqi_ops = &v2r0_qtree_ops;
0156 } else {
0157 qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk);
0158 qinfo->dqi_ops = &v2r1_qtree_ops;
0159 }
0160 ret = -EUCLEAN;
0161
0162 if ((loff_t)qinfo->dqi_blocks << qinfo->dqi_blocksize_bits >
0163 i_size_read(sb_dqopt(sb)->files[type])) {
0164 quota_error(sb, "Number of blocks too big for quota file size (%llu > %llu).",
0165 (loff_t)qinfo->dqi_blocks << qinfo->dqi_blocksize_bits,
0166 i_size_read(sb_dqopt(sb)->files[type]));
0167 goto out_free;
0168 }
0169 if (qinfo->dqi_free_blk >= qinfo->dqi_blocks) {
0170 quota_error(sb, "Free block number too big (%u >= %u).",
0171 qinfo->dqi_free_blk, qinfo->dqi_blocks);
0172 goto out_free;
0173 }
0174 if (qinfo->dqi_free_entry >= qinfo->dqi_blocks) {
0175 quota_error(sb, "Block with free entry too big (%u >= %u).",
0176 qinfo->dqi_free_entry, qinfo->dqi_blocks);
0177 goto out_free;
0178 }
0179 ret = 0;
0180 out_free:
0181 if (ret) {
0182 kfree(info->dqi_priv);
0183 info->dqi_priv = NULL;
0184 }
0185 out:
0186 up_read(&dqopt->dqio_sem);
0187 return ret;
0188 }
0189
0190
0191 static int v2_write_file_info(struct super_block *sb, int type)
0192 {
0193 struct v2_disk_dqinfo dinfo;
0194 struct quota_info *dqopt = sb_dqopt(sb);
0195 struct mem_dqinfo *info = &dqopt->info[type];
0196 struct qtree_mem_dqinfo *qinfo = info->dqi_priv;
0197 ssize_t size;
0198
0199 down_write(&dqopt->dqio_sem);
0200 spin_lock(&dq_data_lock);
0201 info->dqi_flags &= ~DQF_INFO_DIRTY;
0202 dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
0203 dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
0204
0205 dinfo.dqi_flags = cpu_to_le32(0);
0206 spin_unlock(&dq_data_lock);
0207 dinfo.dqi_blocks = cpu_to_le32(qinfo->dqi_blocks);
0208 dinfo.dqi_free_blk = cpu_to_le32(qinfo->dqi_free_blk);
0209 dinfo.dqi_free_entry = cpu_to_le32(qinfo->dqi_free_entry);
0210 size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
0211 sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
0212 up_write(&dqopt->dqio_sem);
0213 if (size != sizeof(struct v2_disk_dqinfo)) {
0214 quota_error(sb, "Can't write info structure");
0215 return -1;
0216 }
0217 return 0;
0218 }
0219
0220 static void v2r0_disk2memdqb(struct dquot *dquot, void *dp)
0221 {
0222 struct v2r0_disk_dqblk *d = dp, empty;
0223 struct mem_dqblk *m = &dquot->dq_dqb;
0224
0225 m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
0226 m->dqb_isoftlimit = le32_to_cpu(d->dqb_isoftlimit);
0227 m->dqb_curinodes = le32_to_cpu(d->dqb_curinodes);
0228 m->dqb_itime = le64_to_cpu(d->dqb_itime);
0229 m->dqb_bhardlimit = v2_qbtos(le32_to_cpu(d->dqb_bhardlimit));
0230 m->dqb_bsoftlimit = v2_qbtos(le32_to_cpu(d->dqb_bsoftlimit));
0231 m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
0232 m->dqb_btime = le64_to_cpu(d->dqb_btime);
0233
0234 memset(&empty, 0, sizeof(struct v2r0_disk_dqblk));
0235 empty.dqb_itime = cpu_to_le64(1);
0236 if (!memcmp(&empty, dp, sizeof(struct v2r0_disk_dqblk)))
0237 m->dqb_itime = 0;
0238 }
0239
0240 static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot)
0241 {
0242 struct v2r0_disk_dqblk *d = dp;
0243 struct mem_dqblk *m = &dquot->dq_dqb;
0244 struct qtree_mem_dqinfo *info =
0245 sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
0246
0247 d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit);
0248 d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit);
0249 d->dqb_curinodes = cpu_to_le32(m->dqb_curinodes);
0250 d->dqb_itime = cpu_to_le64(m->dqb_itime);
0251 d->dqb_bhardlimit = cpu_to_le32(v2_stoqb(m->dqb_bhardlimit));
0252 d->dqb_bsoftlimit = cpu_to_le32(v2_stoqb(m->dqb_bsoftlimit));
0253 d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
0254 d->dqb_btime = cpu_to_le64(m->dqb_btime);
0255 d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
0256 if (qtree_entry_unused(info, dp))
0257 d->dqb_itime = cpu_to_le64(1);
0258 }
0259
0260 static int v2r0_is_id(void *dp, struct dquot *dquot)
0261 {
0262 struct v2r0_disk_dqblk *d = dp;
0263 struct qtree_mem_dqinfo *info =
0264 sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
0265
0266 if (qtree_entry_unused(info, dp))
0267 return 0;
0268 return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
0269 le32_to_cpu(d->dqb_id)),
0270 dquot->dq_id);
0271 }
0272
0273 static void v2r1_disk2memdqb(struct dquot *dquot, void *dp)
0274 {
0275 struct v2r1_disk_dqblk *d = dp, empty;
0276 struct mem_dqblk *m = &dquot->dq_dqb;
0277
0278 m->dqb_ihardlimit = le64_to_cpu(d->dqb_ihardlimit);
0279 m->dqb_isoftlimit = le64_to_cpu(d->dqb_isoftlimit);
0280 m->dqb_curinodes = le64_to_cpu(d->dqb_curinodes);
0281 m->dqb_itime = le64_to_cpu(d->dqb_itime);
0282 m->dqb_bhardlimit = v2_qbtos(le64_to_cpu(d->dqb_bhardlimit));
0283 m->dqb_bsoftlimit = v2_qbtos(le64_to_cpu(d->dqb_bsoftlimit));
0284 m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
0285 m->dqb_btime = le64_to_cpu(d->dqb_btime);
0286
0287 memset(&empty, 0, sizeof(struct v2r1_disk_dqblk));
0288 empty.dqb_itime = cpu_to_le64(1);
0289 if (!memcmp(&empty, dp, sizeof(struct v2r1_disk_dqblk)))
0290 m->dqb_itime = 0;
0291 }
0292
0293 static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
0294 {
0295 struct v2r1_disk_dqblk *d = dp;
0296 struct mem_dqblk *m = &dquot->dq_dqb;
0297 struct qtree_mem_dqinfo *info =
0298 sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
0299
0300 d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
0301 d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
0302 d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
0303 d->dqb_itime = cpu_to_le64(m->dqb_itime);
0304 d->dqb_bhardlimit = cpu_to_le64(v2_stoqb(m->dqb_bhardlimit));
0305 d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit));
0306 d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
0307 d->dqb_btime = cpu_to_le64(m->dqb_btime);
0308 d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
0309 d->dqb_pad = 0;
0310 if (qtree_entry_unused(info, dp))
0311 d->dqb_itime = cpu_to_le64(1);
0312 }
0313
0314 static int v2r1_is_id(void *dp, struct dquot *dquot)
0315 {
0316 struct v2r1_disk_dqblk *d = dp;
0317 struct qtree_mem_dqinfo *info =
0318 sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
0319
0320 if (qtree_entry_unused(info, dp))
0321 return 0;
0322 return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
0323 le32_to_cpu(d->dqb_id)),
0324 dquot->dq_id);
0325 }
0326
0327 static int v2_read_dquot(struct dquot *dquot)
0328 {
0329 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
0330 int ret;
0331
0332 down_read(&dqopt->dqio_sem);
0333 ret = qtree_read_dquot(
0334 sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv,
0335 dquot);
0336 up_read(&dqopt->dqio_sem);
0337 return ret;
0338 }
0339
0340 static int v2_write_dquot(struct dquot *dquot)
0341 {
0342 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
0343 int ret;
0344 bool alloc = false;
0345
0346
0347
0348
0349
0350
0351
0352 if (!dquot->dq_off) {
0353 alloc = true;
0354 down_write(&dqopt->dqio_sem);
0355 } else {
0356 down_read(&dqopt->dqio_sem);
0357 }
0358 ret = qtree_write_dquot(
0359 sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv,
0360 dquot);
0361 if (alloc)
0362 up_write(&dqopt->dqio_sem);
0363 else
0364 up_read(&dqopt->dqio_sem);
0365 return ret;
0366 }
0367
0368 static int v2_release_dquot(struct dquot *dquot)
0369 {
0370 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
0371 int ret;
0372
0373 down_write(&dqopt->dqio_sem);
0374 ret = qtree_release_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot);
0375 up_write(&dqopt->dqio_sem);
0376
0377 return ret;
0378 }
0379
0380 static int v2_free_file_info(struct super_block *sb, int type)
0381 {
0382 kfree(sb_dqinfo(sb, type)->dqi_priv);
0383 return 0;
0384 }
0385
0386 static int v2_get_next_id(struct super_block *sb, struct kqid *qid)
0387 {
0388 struct quota_info *dqopt = sb_dqopt(sb);
0389 int ret;
0390
0391 down_read(&dqopt->dqio_sem);
0392 ret = qtree_get_next_id(sb_dqinfo(sb, qid->type)->dqi_priv, qid);
0393 up_read(&dqopt->dqio_sem);
0394 return ret;
0395 }
0396
0397 static const struct quota_format_ops v2_format_ops = {
0398 .check_quota_file = v2_check_quota_file,
0399 .read_file_info = v2_read_file_info,
0400 .write_file_info = v2_write_file_info,
0401 .free_file_info = v2_free_file_info,
0402 .read_dqblk = v2_read_dquot,
0403 .commit_dqblk = v2_write_dquot,
0404 .release_dqblk = v2_release_dquot,
0405 .get_next_id = v2_get_next_id,
0406 };
0407
0408 static struct quota_format_type v2r0_quota_format = {
0409 .qf_fmt_id = QFMT_VFS_V0,
0410 .qf_ops = &v2_format_ops,
0411 .qf_owner = THIS_MODULE
0412 };
0413
0414 static struct quota_format_type v2r1_quota_format = {
0415 .qf_fmt_id = QFMT_VFS_V1,
0416 .qf_ops = &v2_format_ops,
0417 .qf_owner = THIS_MODULE
0418 };
0419
0420 static int __init init_v2_quota_format(void)
0421 {
0422 int ret;
0423
0424 ret = register_quota_format(&v2r0_quota_format);
0425 if (ret)
0426 return ret;
0427 return register_quota_format(&v2r1_quota_format);
0428 }
0429
0430 static void __exit exit_v2_quota_format(void)
0431 {
0432 unregister_quota_format(&v2r0_quota_format);
0433 unregister_quota_format(&v2r1_quota_format);
0434 }
0435
0436 module_init(init_v2_quota_format);
0437 module_exit(exit_v2_quota_format);