Blame view
fs/quota/quota_v1.c
6.21 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
#include <linux/errno.h> #include <linux/fs.h> #include <linux/quota.h> |
74abb9890 quota: move funct... |
4 |
#include <linux/quotaops.h> |
1da177e4c Linux-2.6.12-rc2 |
5 |
#include <linux/dqblk_v1.h> |
1da177e4c Linux-2.6.12-rc2 |
6 7 8 9 10 |
#include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <asm/byteorder.h> |
cf770c137 quota: Move quota... |
11 |
#include "quotaio_v1.h" |
1da177e4c Linux-2.6.12-rc2 |
12 13 14 |
MODULE_AUTHOR("Jan Kara"); MODULE_DESCRIPTION("Old quota format support"); MODULE_LICENSE("GPL"); |
12095460f quota: Increase s... |
15 16 17 18 19 20 21 22 23 24 25 26 |
#define QUOTABLOCK_BITS 10 #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS) static inline qsize_t v1_stoqb(qsize_t space) { return (space + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS; } static inline qsize_t v1_qbtos(qsize_t blocks) { return blocks << QUOTABLOCK_BITS; } |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 31 |
static void v1_disk2mem_dqblk(struct mem_dqblk *m, struct v1_disk_dqblk *d) { m->dqb_ihardlimit = d->dqb_ihardlimit; m->dqb_isoftlimit = d->dqb_isoftlimit; m->dqb_curinodes = d->dqb_curinodes; |
12095460f quota: Increase s... |
32 33 34 |
m->dqb_bhardlimit = v1_qbtos(d->dqb_bhardlimit); m->dqb_bsoftlimit = v1_qbtos(d->dqb_bsoftlimit); m->dqb_curspace = v1_qbtos(d->dqb_curblocks); |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 38 39 40 41 42 43 |
m->dqb_itime = d->dqb_itime; m->dqb_btime = d->dqb_btime; } static void v1_mem2disk_dqblk(struct v1_disk_dqblk *d, struct mem_dqblk *m) { d->dqb_ihardlimit = m->dqb_ihardlimit; d->dqb_isoftlimit = m->dqb_isoftlimit; d->dqb_curinodes = m->dqb_curinodes; |
12095460f quota: Increase s... |
44 45 46 |
d->dqb_bhardlimit = v1_stoqb(m->dqb_bhardlimit); d->dqb_bsoftlimit = v1_stoqb(m->dqb_bsoftlimit); d->dqb_curblocks = v1_stoqb(m->dqb_curspace); |
1da177e4c Linux-2.6.12-rc2 |
47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
d->dqb_itime = m->dqb_itime; d->dqb_btime = m->dqb_btime; } static int v1_read_dqblk(struct dquot *dquot) { int type = dquot->dq_type; struct v1_disk_dqblk dqblk; if (!sb_dqopt(dquot->dq_sb)->files[type]) return -EINVAL; /* Set structure to 0s in case read fails/is after end of file */ memset(&dqblk, 0, sizeof(struct v1_disk_dqblk)); |
268157ba6 quota: Coding sty... |
61 62 |
dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); |
1da177e4c Linux-2.6.12-rc2 |
63 64 |
v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); |
268157ba6 quota: Coding sty... |
65 66 67 68 |
if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 && dquot->dq_dqb.dqb_ihardlimit == 0 && dquot->dq_dqb.dqb_isoftlimit == 0) |
1da177e4c Linux-2.6.12-rc2 |
69 |
set_bit(DQ_FAKE_B, &dquot->dq_flags); |
dde958885 quota: Make quota... |
70 |
dqstats_inc(DQST_READS); |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 74 75 76 77 78 79 80 81 82 |
return 0; } static int v1_commit_dqblk(struct dquot *dquot) { short type = dquot->dq_type; ssize_t ret; struct v1_disk_dqblk dqblk; v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); if (dquot->dq_id == 0) { |
268157ba6 quota: Coding sty... |
83 84 85 86 |
dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace; |
1da177e4c Linux-2.6.12-rc2 |
87 88 89 |
} ret = 0; if (sb_dqopt(dquot->dq_sb)->files[type]) |
268157ba6 quota: Coding sty... |
90 91 92 |
ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); |
1da177e4c Linux-2.6.12-rc2 |
93 |
if (ret != sizeof(struct v1_disk_dqblk)) { |
fb5ffb0e1 quota: Change quo... |
94 |
quota_error(dquot->dq_sb, "dquota write failed"); |
1da177e4c Linux-2.6.12-rc2 |
95 96 97 98 99 100 101 |
if (ret >= 0) ret = -EIO; goto out; } ret = 0; out: |
dde958885 quota: Make quota... |
102 |
dqstats_inc(DQST_WRITES); |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
return ret; } /* Magics of new quota format */ #define V2_INITQMAGICS {\ 0xd9c01f11, /* USRQUOTA */\ 0xd9c01927 /* GRPQUOTA */\ } /* Header of new quota format */ struct v2_disk_dqheader { __le32 dqh_magic; /* Magic number identifying file */ __le32 dqh_version; /* File version */ }; static int v1_check_quota_file(struct super_block *sb, int type) { struct inode *inode = sb_dqopt(sb)->files[type]; ulong blocks; size_t off; struct v2_disk_dqheader dqhead; ssize_t size; loff_t isize; static const uint quota_magics[] = V2_INITQMAGICS; isize = i_size_read(inode); if (!isize) return 0; blocks = isize >> BLOCK_SIZE_BITS; off = isize & (BLOCK_SIZE - 1); |
268157ba6 quota: Coding sty... |
134 135 |
if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk)) |
1da177e4c Linux-2.6.12-rc2 |
136 |
return 0; |
268157ba6 quota: Coding sty... |
137 138 139 140 |
/* Doublecheck whether we didn't get file with new format - with old * quotactl() this could happen */ size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); |
1da177e4c Linux-2.6.12-rc2 |
141 142 143 144 |
if (size != sizeof(struct v2_disk_dqheader)) return 1; /* Probably not new format */ if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type]) return 1; /* Definitely not new format */ |
268157ba6 quota: Coding sty... |
145 146 147 148 |
printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file." " It probably contains newer quota format. ", sb->s_id); |
1da177e4c Linux-2.6.12-rc2 |
149 150 151 152 153 154 155 156 |
return 0; /* Seems like a new format file -> refuse it */ } static int v1_read_file_info(struct super_block *sb, int type) { struct quota_info *dqopt = sb_dqopt(sb); struct v1_disk_dqblk dqblk; int ret; |
268157ba6 quota: Coding sty... |
157 158 159 |
ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0)); if (ret != sizeof(struct v1_disk_dqblk)) { |
1da177e4c Linux-2.6.12-rc2 |
160 161 162 163 164 |
if (ret >= 0) ret = -EIO; goto out; } ret = 0; |
338bf9afd quota: do not all... |
165 166 167 |
/* limits are stored as unsigned 32-bit data */ dqopt->info[type].dqi_maxblimit = 0xffffffff; dqopt->info[type].dqi_maxilimit = 0xffffffff; |
268157ba6 quota: Coding sty... |
168 169 170 171 |
dqopt->info[type].dqi_igrace = dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME; dqopt->info[type].dqi_bgrace = dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME; |
1da177e4c Linux-2.6.12-rc2 |
172 173 174 175 176 177 178 179 180 181 182 |
out: return ret; } static int v1_write_file_info(struct super_block *sb, int type) { struct quota_info *dqopt = sb_dqopt(sb); struct v1_disk_dqblk dqblk; int ret; dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; |
268157ba6 quota: Coding sty... |
183 184 185 |
ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0)); if (ret != sizeof(struct v1_disk_dqblk)) { |
1da177e4c Linux-2.6.12-rc2 |
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
if (ret >= 0) ret = -EIO; goto out; } dqblk.dqb_itime = dqopt->info[type].dqi_igrace; dqblk.dqb_btime = dqopt->info[type].dqi_bgrace; ret = sb->s_op->quota_write(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0)); if (ret == sizeof(struct v1_disk_dqblk)) ret = 0; else if (ret > 0) ret = -EIO; out: return ret; } |
1472da5fd const: struct quo... |
201 |
static const struct quota_format_ops v1_format_ops = { |
1da177e4c Linux-2.6.12-rc2 |
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
.check_quota_file = v1_check_quota_file, .read_file_info = v1_read_file_info, .write_file_info = v1_write_file_info, .free_file_info = NULL, .read_dqblk = v1_read_dqblk, .commit_dqblk = v1_commit_dqblk, }; static struct quota_format_type v1_quota_format = { .qf_fmt_id = QFMT_VFS_OLD, .qf_ops = &v1_format_ops, .qf_owner = THIS_MODULE }; static int __init init_v1_quota_format(void) { return register_quota_format(&v1_quota_format); } static void __exit exit_v1_quota_format(void) { unregister_quota_format(&v1_quota_format); } module_init(init_v1_quota_format); module_exit(exit_v1_quota_format); |