diff options
Diffstat (limited to 'fs/quota/dquot.c')
| -rw-r--r-- | fs/quota/dquot.c | 67 |
1 files changed, 43 insertions, 24 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; |
