Blame view
fs/quota/quota_v1.c
6.62 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 |
d->dqb_itime = m->dqb_itime; d->dqb_btime = m->dqb_btime; } static int v1_read_dqblk(struct dquot *dquot) { |
4c376dcae userns: Convert s... |
53 |
int type = dquot->dq_id.type; |
1da177e4c Linux-2.6.12-rc2 |
54 |
struct v1_disk_dqblk dqblk; |
e342e38df quota: Push dqio_... |
55 |
struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
1da177e4c Linux-2.6.12-rc2 |
56 |
|
e342e38df quota: Push dqio_... |
57 |
if (!dqopt->files[type]) |
1da177e4c Linux-2.6.12-rc2 |
58 59 60 61 |
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... |
62 |
dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, |
4c376dcae userns: Convert s... |
63 64 |
sizeof(struct v1_disk_dqblk), v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id))); |
1da177e4c Linux-2.6.12-rc2 |
65 66 |
v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); |
268157ba6 quota: Coding sty... |
67 68 69 70 |
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 |
71 |
set_bit(DQ_FAKE_B, &dquot->dq_flags); |
dde958885 quota: Make quota... |
72 |
dqstats_inc(DQST_READS); |
1da177e4c Linux-2.6.12-rc2 |
73 74 75 76 77 78 |
return 0; } static int v1_commit_dqblk(struct dquot *dquot) { |
4c376dcae userns: Convert s... |
79 |
short type = dquot->dq_id.type; |
1da177e4c Linux-2.6.12-rc2 |
80 81 82 83 |
ssize_t ret; struct v1_disk_dqblk dqblk; v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); |
4c376dcae userns: Convert s... |
84 85 |
if (((type == USRQUOTA) && uid_eq(dquot->dq_id.uid, GLOBAL_ROOT_UID)) || ((type == GRPQUOTA) && gid_eq(dquot->dq_id.gid, GLOBAL_ROOT_GID))) { |
268157ba6 quota: Coding sty... |
86 87 88 89 |
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 |
90 91 92 |
} ret = 0; if (sb_dqopt(dquot->dq_sb)->files[type]) |
268157ba6 quota: Coding sty... |
93 94 |
ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), |
4c376dcae userns: Convert s... |
95 |
v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id))); |
1da177e4c Linux-2.6.12-rc2 |
96 |
if (ret != sizeof(struct v1_disk_dqblk)) { |
fb5ffb0e1 quota: Change quo... |
97 |
quota_error(dquot->dq_sb, "dquota write failed"); |
1da177e4c Linux-2.6.12-rc2 |
98 99 100 101 102 103 104 |
if (ret >= 0) ret = -EIO; goto out; } ret = 0; out: |
dde958885 quota: Make quota... |
105 |
dqstats_inc(DQST_WRITES); |
1da177e4c Linux-2.6.12-rc2 |
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 134 135 136 |
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... |
137 138 |
if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk)) |
1da177e4c Linux-2.6.12-rc2 |
139 |
return 0; |
268157ba6 quota: Coding sty... |
140 141 142 143 |
/* 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 |
144 145 146 147 |
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... |
148 149 150 151 |
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 |
152 153 154 155 156 157 158 159 |
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; |
42fdb8583 quota: Push dqio_... |
160 |
down_read(&dqopt->dqio_sem); |
268157ba6 quota: Coding sty... |
161 162 163 |
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 |
164 165 166 167 168 |
if (ret >= 0) ret = -EIO; goto out; } ret = 0; |
338bf9afd quota: do not all... |
169 |
/* limits are stored as unsigned 32-bit data */ |
b10a08194 quota: Store maxi... |
170 171 |
dqopt->info[type].dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS; dqopt->info[type].dqi_max_ino_limit = 0xffffffff; |
268157ba6 quota: Coding sty... |
172 173 174 175 |
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 |
176 |
out: |
42fdb8583 quota: Push dqio_... |
177 |
up_read(&dqopt->dqio_sem); |
1da177e4c Linux-2.6.12-rc2 |
178 179 180 181 182 183 184 185 |
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; |
9a8ae30e7 quota: Push dqio_... |
186 |
down_write(&dqopt->dqio_sem); |
268157ba6 quota: Coding sty... |
187 188 189 |
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 |
190 191 192 193 |
if (ret >= 0) ret = -EIO; goto out; } |
15512377b quota: Fix possib... |
194 195 |
spin_lock(&dq_data_lock); dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; |
1da177e4c Linux-2.6.12-rc2 |
196 197 |
dqblk.dqb_itime = dqopt->info[type].dqi_igrace; dqblk.dqb_btime = dqopt->info[type].dqi_bgrace; |
15512377b quota: Fix possib... |
198 |
spin_unlock(&dq_data_lock); |
1da177e4c Linux-2.6.12-rc2 |
199 200 201 202 203 204 205 |
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: |
9a8ae30e7 quota: Push dqio_... |
206 |
up_write(&dqopt->dqio_sem); |
1da177e4c Linux-2.6.12-rc2 |
207 208 |
return ret; } |
1472da5fd const: struct quo... |
209 |
static const struct quota_format_ops v1_format_ops = { |
1da177e4c Linux-2.6.12-rc2 |
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
.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); |