diff options
Diffstat (limited to 'fs/quota')
-rw-r--r-- | fs/quota/dquot.c | 67 | ||||
-rw-r--r-- | fs/quota/quota.c | 36 |
2 files changed, 74 insertions, 29 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 6aed77fc99c7..b1a5036560a9 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -2338,51 +2338,70 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
2338 | } | 2338 | } |
2339 | EXPORT_SYMBOL(vfs_get_dqblk); | 2339 | EXPORT_SYMBOL(vfs_get_dqblk); |
2340 | 2340 | ||
2341 | #define VFS_FS_DQ_MASK \ | ||
2342 | (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ | ||
2343 | FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \ | ||
2344 | FS_DQ_BTIMER | FS_DQ_ITIMER) | ||
2345 | |||
2341 | /* Generic routine for setting common part of quota structure */ | 2346 | /* Generic routine for setting common part of quota structure */ |
2342 | static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | 2347 | static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) |
2343 | { | 2348 | { |
2344 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2349 | struct mem_dqblk *dm = &dquot->dq_dqb; |
2345 | int check_blim = 0, check_ilim = 0; | 2350 | int check_blim = 0, check_ilim = 0; |
2346 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; | 2351 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; |
2347 | 2352 | ||
2348 | if ((di->dqb_valid & QIF_BLIMITS && | 2353 | if (di->d_fieldmask & ~VFS_FS_DQ_MASK) |
2349 | (di->dqb_bhardlimit > dqi->dqi_maxblimit || | 2354 | return -EINVAL; |
2350 | di->dqb_bsoftlimit > dqi->dqi_maxblimit)) || | 2355 | |
2351 | (di->dqb_valid & QIF_ILIMITS && | 2356 | if (((di->d_fieldmask & FS_DQ_BSOFT) && |
2352 | (di->dqb_ihardlimit > dqi->dqi_maxilimit || | 2357 | (di->d_blk_softlimit > dqi->dqi_maxblimit)) || |
2353 | di->dqb_isoftlimit > dqi->dqi_maxilimit))) | 2358 | ((di->d_fieldmask & FS_DQ_BHARD) && |
2359 | (di->d_blk_hardlimit > dqi->dqi_maxblimit)) || | ||
2360 | ((di->d_fieldmask & FS_DQ_ISOFT) && | ||
2361 | (di->d_ino_softlimit > dqi->dqi_maxilimit)) || | ||
2362 | ((di->d_fieldmask & FS_DQ_IHARD) && | ||
2363 | (di->d_ino_hardlimit > dqi->dqi_maxilimit))) | ||
2354 | return -ERANGE; | 2364 | return -ERANGE; |
2355 | 2365 | ||
2356 | spin_lock(&dq_data_lock); | 2366 | spin_lock(&dq_data_lock); |
2357 | if (di->dqb_valid & QIF_SPACE) { | 2367 | if (di->d_fieldmask & FS_DQ_BCOUNT) { |
2358 | dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; | 2368 | dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace; |
2359 | check_blim = 1; | 2369 | check_blim = 1; |
2360 | set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | 2370 | set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); |
2361 | } | 2371 | } |
2362 | if (di->dqb_valid & QIF_BLIMITS) { | 2372 | |
2363 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); | 2373 | if (di->d_fieldmask & FS_DQ_BSOFT) |
2364 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); | 2374 | dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit); |
2375 | if (di->d_fieldmask & FS_DQ_BHARD) | ||
2376 | dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit); | ||
2377 | if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) { | ||
2365 | check_blim = 1; | 2378 | check_blim = 1; |
2366 | set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | 2379 | set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); |
2367 | } | 2380 | } |
2368 | if (di->dqb_valid & QIF_INODES) { | 2381 | |
2369 | dm->dqb_curinodes = di->dqb_curinodes; | 2382 | if (di->d_fieldmask & FS_DQ_ICOUNT) { |
2383 | dm->dqb_curinodes = di->d_icount; | ||
2370 | check_ilim = 1; | 2384 | check_ilim = 1; |
2371 | set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | 2385 | set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); |
2372 | } | 2386 | } |
2373 | if (di->dqb_valid & QIF_ILIMITS) { | 2387 | |
2374 | dm->dqb_isoftlimit = di->dqb_isoftlimit; | 2388 | if (di->d_fieldmask & FS_DQ_ISOFT) |
2375 | dm->dqb_ihardlimit = di->dqb_ihardlimit; | 2389 | dm->dqb_isoftlimit = di->d_ino_softlimit; |
2390 | if (di->d_fieldmask & FS_DQ_IHARD) | ||
2391 | dm->dqb_ihardlimit = di->d_ino_hardlimit; | ||
2392 | if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) { | ||
2376 | check_ilim = 1; | 2393 | check_ilim = 1; |
2377 | set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | 2394 | set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); |
2378 | } | 2395 | } |
2379 | if (di->dqb_valid & QIF_BTIME) { | 2396 | |
2380 | dm->dqb_btime = di->dqb_btime; | 2397 | if (di->d_fieldmask & FS_DQ_BTIMER) { |
2398 | dm->dqb_btime = di->d_btimer; | ||
2381 | check_blim = 1; | 2399 | check_blim = 1; |
2382 | set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); | 2400 | set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); |
2383 | } | 2401 | } |
2384 | if (di->dqb_valid & QIF_ITIME) { | 2402 | |
2385 | dm->dqb_itime = di->dqb_itime; | 2403 | if (di->d_fieldmask & FS_DQ_ITIMER) { |
2404 | dm->dqb_itime = di->d_itimer; | ||
2386 | check_ilim = 1; | 2405 | check_ilim = 1; |
2387 | set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | 2406 | set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); |
2388 | } | 2407 | } |
@@ -2392,7 +2411,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
2392 | dm->dqb_curspace < dm->dqb_bsoftlimit) { | 2411 | dm->dqb_curspace < dm->dqb_bsoftlimit) { |
2393 | dm->dqb_btime = 0; | 2412 | dm->dqb_btime = 0; |
2394 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 2413 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
2395 | } else if (!(di->dqb_valid & QIF_BTIME)) | 2414 | } else if (!(di->d_fieldmask & FS_DQ_BTIMER)) |
2396 | /* Set grace only if user hasn't provided his own... */ | 2415 | /* Set grace only if user hasn't provided his own... */ |
2397 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; | 2416 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; |
2398 | } | 2417 | } |
@@ -2401,7 +2420,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
2401 | dm->dqb_curinodes < dm->dqb_isoftlimit) { | 2420 | dm->dqb_curinodes < dm->dqb_isoftlimit) { |
2402 | dm->dqb_itime = 0; | 2421 | dm->dqb_itime = 0; |
2403 | clear_bit(DQ_INODES_B, &dquot->dq_flags); | 2422 | clear_bit(DQ_INODES_B, &dquot->dq_flags); |
2404 | } else if (!(di->dqb_valid & QIF_ITIME)) | 2423 | } else if (!(di->d_fieldmask & FS_DQ_ITIMER)) |
2405 | /* Set grace only if user hasn't provided his own... */ | 2424 | /* Set grace only if user hasn't provided his own... */ |
2406 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; | 2425 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; |
2407 | } | 2426 | } |
@@ -2417,7 +2436,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
2417 | } | 2436 | } |
2418 | 2437 | ||
2419 | int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, | 2438 | int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, |
2420 | struct if_dqblk *di) | 2439 | struct fs_disk_quota *di) |
2421 | { | 2440 | { |
2422 | struct dquot *dquot; | 2441 | struct dquot *dquot; |
2423 | int rc; | 2442 | int rc; |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 8680e257c2bd..d6ee49dda4fd 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -167,18 +167,44 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id, | |||
167 | return 0; | 167 | return 0; |
168 | } | 168 | } |
169 | 169 | ||
170 | static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src) | ||
171 | { | ||
172 | dst->d_blk_hardlimit = src->dqb_bhardlimit; | ||
173 | dst->d_blk_softlimit = src->dqb_bsoftlimit; | ||
174 | dst->d_bcount = src->dqb_curspace; | ||
175 | dst->d_ino_hardlimit = src->dqb_ihardlimit; | ||
176 | dst->d_ino_softlimit = src->dqb_isoftlimit; | ||
177 | dst->d_icount = src->dqb_curinodes; | ||
178 | dst->d_btimer = src->dqb_btime; | ||
179 | dst->d_itimer = src->dqb_itime; | ||
180 | |||
181 | dst->d_fieldmask = 0; | ||
182 | if (src->dqb_valid & QIF_BLIMITS) | ||
183 | dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD; | ||
184 | if (src->dqb_valid & QIF_SPACE) | ||
185 | dst->d_fieldmask |= FS_DQ_BCOUNT; | ||
186 | if (src->dqb_valid & QIF_ILIMITS) | ||
187 | dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD; | ||
188 | if (src->dqb_valid & QIF_INODES) | ||
189 | dst->d_fieldmask |= FS_DQ_ICOUNT; | ||
190 | if (src->dqb_valid & QIF_BTIME) | ||
191 | dst->d_fieldmask |= FS_DQ_BTIMER; | ||
192 | if (src->dqb_valid & QIF_ITIME) | ||
193 | dst->d_fieldmask |= FS_DQ_ITIMER; | ||
194 | } | ||
195 | |||
170 | static int quota_setquota(struct super_block *sb, int type, qid_t id, | 196 | static int quota_setquota(struct super_block *sb, int type, qid_t id, |
171 | void __user *addr) | 197 | void __user *addr) |
172 | { | 198 | { |
199 | struct fs_disk_quota fdq; | ||
173 | struct if_dqblk idq; | 200 | struct if_dqblk idq; |
174 | 201 | ||
175 | if (copy_from_user(&idq, addr, sizeof(idq))) | 202 | if (copy_from_user(&idq, addr, sizeof(idq))) |
176 | return -EFAULT; | 203 | return -EFAULT; |
177 | if (!sb_has_quota_active(sb, type)) | ||
178 | return -ESRCH; | ||
179 | if (!sb->s_qcop->set_dqblk) | 204 | if (!sb->s_qcop->set_dqblk) |
180 | return -ENOSYS; | 205 | return -ENOSYS; |
181 | return sb->s_qcop->set_dqblk(sb, type, id, &idq); | 206 | copy_from_if_dqblk(&fdq, &idq); |
207 | return sb->s_qcop->set_dqblk(sb, type, id, &fdq); | ||
182 | } | 208 | } |
183 | 209 | ||
184 | static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) | 210 | static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) |
@@ -212,9 +238,9 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id, | |||
212 | 238 | ||
213 | if (copy_from_user(&fdq, addr, sizeof(fdq))) | 239 | if (copy_from_user(&fdq, addr, sizeof(fdq))) |
214 | return -EFAULT; | 240 | return -EFAULT; |
215 | if (!sb->s_qcop->set_xquota) | 241 | if (!sb->s_qcop->set_dqblk) |
216 | return -ENOSYS; | 242 | return -ENOSYS; |
217 | return sb->s_qcop->set_xquota(sb, type, id, &fdq); | 243 | return sb->s_qcop->set_dqblk(sb, type, id, &fdq); |
218 | } | 244 | } |
219 | 245 | ||
220 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, | 246 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, |