dquot.c (ca6cb0918e8765de304916a15554b42203e6e1fc) dquot.c (14bf61ffe6ac54afcd1e888a4407fe16054483db)
1/*
2 * Implementation of the diskquota system for the LINUX operating system. QUOTA
3 * is implemented using the BSD system call interface as the means of
4 * communication with the user level. This file contains the generic routines
5 * called by the different filesystems on allocation of an inode or block.
6 * These routines take care of the administration needed to have a consistent
7 * diskquota tracking system. The ideas of both user and group quotas are based
8 * on the Melbourne quota system as used on BSD derived systems. The internal

--- 1234 unchanged lines hidden (view full) ---

1243}
1244
1245static int ignore_hardlimit(struct dquot *dquot)
1246{
1247 struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
1248
1249 return capable(CAP_SYS_RESOURCE) &&
1250 (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
1/*
2 * Implementation of the diskquota system for the LINUX operating system. QUOTA
3 * is implemented using the BSD system call interface as the means of
4 * communication with the user level. This file contains the generic routines
5 * called by the different filesystems on allocation of an inode or block.
6 * These routines take care of the administration needed to have a consistent
7 * diskquota tracking system. The ideas of both user and group quotas are based
8 * on the Melbourne quota system as used on BSD derived systems. The internal

--- 1234 unchanged lines hidden (view full) ---

1243}
1244
1245static int ignore_hardlimit(struct dquot *dquot)
1246{
1247 struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
1248
1249 return capable(CAP_SYS_RESOURCE) &&
1250 (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
1251 !(info->dqi_flags & DQF_ROOT_SQUASH));
1251 !(info->dqi_flags & V1_DQF_RSQUASH));
1252}
1253
1254/* needs dq_data_lock */
1255static int check_idq(struct dquot *dquot, qsize_t inodes,
1256 struct dquot_warn *warn)
1257{
1258 qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes;
1259

--- 1131 unchanged lines hidden (view full) ---

2391}
2392
2393static inline qsize_t stoqb(qsize_t space)
2394{
2395 return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS;
2396}
2397
2398/* Generic routine for getting common part of quota structure */
1252}
1253
1254/* needs dq_data_lock */
1255static int check_idq(struct dquot *dquot, qsize_t inodes,
1256 struct dquot_warn *warn)
1257{
1258 qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes;
1259

--- 1131 unchanged lines hidden (view full) ---

2391}
2392
2393static inline qsize_t stoqb(qsize_t space)
2394{
2395 return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS;
2396}
2397
2398/* Generic routine for getting common part of quota structure */
2399static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
2399static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di)
2400{
2401 struct mem_dqblk *dm = &dquot->dq_dqb;
2402
2403 memset(di, 0, sizeof(*di));
2400{
2401 struct mem_dqblk *dm = &dquot->dq_dqb;
2402
2403 memset(di, 0, sizeof(*di));
2404 di->d_version = FS_DQUOT_VERSION;
2405 di->d_flags = dquot->dq_id.type == USRQUOTA ?
2406 FS_USER_QUOTA : FS_GROUP_QUOTA;
2407 di->d_id = from_kqid_munged(current_user_ns(), dquot->dq_id);
2408
2409 spin_lock(&dq_data_lock);
2404 spin_lock(&dq_data_lock);
2410 di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit);
2411 di->d_blk_softlimit = stoqb(dm->dqb_bsoftlimit);
2405 di->d_spc_hardlimit = dm->dqb_bhardlimit;
2406 di->d_spc_softlimit = dm->dqb_bsoftlimit;
2412 di->d_ino_hardlimit = dm->dqb_ihardlimit;
2413 di->d_ino_softlimit = dm->dqb_isoftlimit;
2407 di->d_ino_hardlimit = dm->dqb_ihardlimit;
2408 di->d_ino_softlimit = dm->dqb_isoftlimit;
2414 di->d_bcount = dm->dqb_curspace + dm->dqb_rsvspace;
2415 di->d_icount = dm->dqb_curinodes;
2416 di->d_btimer = dm->dqb_btime;
2417 di->d_itimer = dm->dqb_itime;
2409 di->d_space = dm->dqb_curspace + dm->dqb_rsvspace;
2410 di->d_ino_count = dm->dqb_curinodes;
2411 di->d_spc_timer = dm->dqb_btime;
2412 di->d_ino_timer = dm->dqb_itime;
2418 spin_unlock(&dq_data_lock);
2419}
2420
2421int dquot_get_dqblk(struct super_block *sb, struct kqid qid,
2413 spin_unlock(&dq_data_lock);
2414}
2415
2416int dquot_get_dqblk(struct super_block *sb, struct kqid qid,
2422 struct fs_disk_quota *di)
2417 struct qc_dqblk *di)
2423{
2424 struct dquot *dquot;
2425
2426 dquot = dqget(sb, qid);
2427 if (!dquot)
2428 return -ESRCH;
2429 do_get_dqblk(dquot, di);
2430 dqput(dquot);
2431
2432 return 0;
2433}
2434EXPORT_SYMBOL(dquot_get_dqblk);
2435
2418{
2419 struct dquot *dquot;
2420
2421 dquot = dqget(sb, qid);
2422 if (!dquot)
2423 return -ESRCH;
2424 do_get_dqblk(dquot, di);
2425 dqput(dquot);
2426
2427 return 0;
2428}
2429EXPORT_SYMBOL(dquot_get_dqblk);
2430
2436#define VFS_FS_DQ_MASK \
2437 (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \
2438 FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \
2439 FS_DQ_BTIMER | FS_DQ_ITIMER)
2431#define VFS_QC_MASK \
2432 (QC_SPACE | QC_SPC_SOFT | QC_SPC_HARD | \
2433 QC_INO_COUNT | QC_INO_SOFT | QC_INO_HARD | \
2434 QC_SPC_TIMER | QC_INO_TIMER)
2440
2441/* Generic routine for setting common part of quota structure */
2435
2436/* Generic routine for setting common part of quota structure */
2442static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
2437static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di)
2443{
2444 struct mem_dqblk *dm = &dquot->dq_dqb;
2445 int check_blim = 0, check_ilim = 0;
2446 struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
2447
2438{
2439 struct mem_dqblk *dm = &dquot->dq_dqb;
2440 int check_blim = 0, check_ilim = 0;
2441 struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
2442
2448 if (di->d_fieldmask & ~VFS_FS_DQ_MASK)
2443 if (di->d_fieldmask & ~VFS_QC_MASK)
2449 return -EINVAL;
2450
2444 return -EINVAL;
2445
2451 if (((di->d_fieldmask & FS_DQ_BSOFT) &&
2452 (di->d_blk_softlimit > dqi->dqi_maxblimit)) ||
2453 ((di->d_fieldmask & FS_DQ_BHARD) &&
2454 (di->d_blk_hardlimit > dqi->dqi_maxblimit)) ||
2455 ((di->d_fieldmask & FS_DQ_ISOFT) &&
2446 if (((di->d_fieldmask & QC_SPC_SOFT) &&
2447 stoqb(di->d_spc_softlimit) > dqi->dqi_maxblimit) ||
2448 ((di->d_fieldmask & QC_SPC_HARD) &&
2449 stoqb(di->d_spc_hardlimit) > dqi->dqi_maxblimit) ||
2450 ((di->d_fieldmask & QC_INO_SOFT) &&
2456 (di->d_ino_softlimit > dqi->dqi_maxilimit)) ||
2451 (di->d_ino_softlimit > dqi->dqi_maxilimit)) ||
2457 ((di->d_fieldmask & FS_DQ_IHARD) &&
2452 ((di->d_fieldmask & QC_INO_HARD) &&
2458 (di->d_ino_hardlimit > dqi->dqi_maxilimit)))
2459 return -ERANGE;
2460
2461 spin_lock(&dq_data_lock);
2453 (di->d_ino_hardlimit > dqi->dqi_maxilimit)))
2454 return -ERANGE;
2455
2456 spin_lock(&dq_data_lock);
2462 if (di->d_fieldmask & FS_DQ_BCOUNT) {
2463 dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace;
2457 if (di->d_fieldmask & QC_SPACE) {
2458 dm->dqb_curspace = di->d_space - dm->dqb_rsvspace;
2464 check_blim = 1;
2465 set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
2466 }
2467
2459 check_blim = 1;
2460 set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
2461 }
2462
2468 if (di->d_fieldmask & FS_DQ_BSOFT)
2469 dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit);
2470 if (di->d_fieldmask & FS_DQ_BHARD)
2471 dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit);
2472 if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) {
2463 if (di->d_fieldmask & QC_SPC_SOFT)
2464 dm->dqb_bsoftlimit = di->d_spc_softlimit;
2465 if (di->d_fieldmask & QC_SPC_HARD)
2466 dm->dqb_bhardlimit = di->d_spc_hardlimit;
2467 if (di->d_fieldmask & (QC_SPC_SOFT | QC_SPC_HARD)) {
2473 check_blim = 1;
2474 set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
2475 }
2476
2468 check_blim = 1;
2469 set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
2470 }
2471
2477 if (di->d_fieldmask & FS_DQ_ICOUNT) {
2478 dm->dqb_curinodes = di->d_icount;
2472 if (di->d_fieldmask & QC_INO_COUNT) {
2473 dm->dqb_curinodes = di->d_ino_count;
2479 check_ilim = 1;
2480 set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
2481 }
2482
2474 check_ilim = 1;
2475 set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
2476 }
2477
2483 if (di->d_fieldmask & FS_DQ_ISOFT)
2478 if (di->d_fieldmask & QC_INO_SOFT)
2484 dm->dqb_isoftlimit = di->d_ino_softlimit;
2479 dm->dqb_isoftlimit = di->d_ino_softlimit;
2485 if (di->d_fieldmask & FS_DQ_IHARD)
2480 if (di->d_fieldmask & QC_INO_HARD)
2486 dm->dqb_ihardlimit = di->d_ino_hardlimit;
2481 dm->dqb_ihardlimit = di->d_ino_hardlimit;
2487 if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) {
2482 if (di->d_fieldmask & (QC_INO_SOFT | QC_INO_HARD)) {
2488 check_ilim = 1;
2489 set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
2490 }
2491
2483 check_ilim = 1;
2484 set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
2485 }
2486
2492 if (di->d_fieldmask & FS_DQ_BTIMER) {
2493 dm->dqb_btime = di->d_btimer;
2487 if (di->d_fieldmask & QC_SPC_TIMER) {
2488 dm->dqb_btime = di->d_spc_timer;
2494 check_blim = 1;
2495 set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
2496 }
2497
2489 check_blim = 1;
2490 set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
2491 }
2492
2498 if (di->d_fieldmask & FS_DQ_ITIMER) {
2499 dm->dqb_itime = di->d_itimer;
2493 if (di->d_fieldmask & QC_INO_TIMER) {
2494 dm->dqb_itime = di->d_ino_timer;
2500 check_ilim = 1;
2501 set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
2502 }
2503
2504 if (check_blim) {
2505 if (!dm->dqb_bsoftlimit ||
2506 dm->dqb_curspace < dm->dqb_bsoftlimit) {
2507 dm->dqb_btime = 0;
2508 clear_bit(DQ_BLKS_B, &dquot->dq_flags);
2495 check_ilim = 1;
2496 set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
2497 }
2498
2499 if (check_blim) {
2500 if (!dm->dqb_bsoftlimit ||
2501 dm->dqb_curspace < dm->dqb_bsoftlimit) {
2502 dm->dqb_btime = 0;
2503 clear_bit(DQ_BLKS_B, &dquot->dq_flags);
2509 } else if (!(di->d_fieldmask & FS_DQ_BTIMER))
2504 } else if (!(di->d_fieldmask & QC_SPC_TIMER))
2510 /* Set grace only if user hasn't provided his own... */
2511 dm->dqb_btime = get_seconds() + dqi->dqi_bgrace;
2512 }
2513 if (check_ilim) {
2514 if (!dm->dqb_isoftlimit ||
2515 dm->dqb_curinodes < dm->dqb_isoftlimit) {
2516 dm->dqb_itime = 0;
2517 clear_bit(DQ_INODES_B, &dquot->dq_flags);
2505 /* Set grace only if user hasn't provided his own... */
2506 dm->dqb_btime = get_seconds() + dqi->dqi_bgrace;
2507 }
2508 if (check_ilim) {
2509 if (!dm->dqb_isoftlimit ||
2510 dm->dqb_curinodes < dm->dqb_isoftlimit) {
2511 dm->dqb_itime = 0;
2512 clear_bit(DQ_INODES_B, &dquot->dq_flags);
2518 } else if (!(di->d_fieldmask & FS_DQ_ITIMER))
2513 } else if (!(di->d_fieldmask & QC_INO_TIMER))
2519 /* Set grace only if user hasn't provided his own... */
2520 dm->dqb_itime = get_seconds() + dqi->dqi_igrace;
2521 }
2522 if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit ||
2523 dm->dqb_isoftlimit)
2524 clear_bit(DQ_FAKE_B, &dquot->dq_flags);
2525 else
2526 set_bit(DQ_FAKE_B, &dquot->dq_flags);
2527 spin_unlock(&dq_data_lock);
2528 mark_dquot_dirty(dquot);
2529
2530 return 0;
2531}
2532
2533int dquot_set_dqblk(struct super_block *sb, struct kqid qid,
2514 /* Set grace only if user hasn't provided his own... */
2515 dm->dqb_itime = get_seconds() + dqi->dqi_igrace;
2516 }
2517 if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit ||
2518 dm->dqb_isoftlimit)
2519 clear_bit(DQ_FAKE_B, &dquot->dq_flags);
2520 else
2521 set_bit(DQ_FAKE_B, &dquot->dq_flags);
2522 spin_unlock(&dq_data_lock);
2523 mark_dquot_dirty(dquot);
2524
2525 return 0;
2526}
2527
2528int dquot_set_dqblk(struct super_block *sb, struct kqid qid,
2534 struct fs_disk_quota *di)
2529 struct qc_dqblk *di)
2535{
2536 struct dquot *dquot;
2537 int rc;
2538
2539 dquot = dqget(sb, qid);
2540 if (!dquot) {
2541 rc = -ESRCH;
2542 goto out;

--- 34 unchanged lines hidden (view full) ---

2577 int err = 0;
2578
2579 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
2580 if (!sb_has_quota_active(sb, type)) {
2581 err = -ESRCH;
2582 goto out;
2583 }
2584 mi = sb_dqopt(sb)->info + type;
2530{
2531 struct dquot *dquot;
2532 int rc;
2533
2534 dquot = dqget(sb, qid);
2535 if (!dquot) {
2536 rc = -ESRCH;
2537 goto out;

--- 34 unchanged lines hidden (view full) ---

2572 int err = 0;
2573
2574 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
2575 if (!sb_has_quota_active(sb, type)) {
2576 err = -ESRCH;
2577 goto out;
2578 }
2579 mi = sb_dqopt(sb)->info + type;
2585 if (ii->dqi_valid & IIF_FLAGS) {
2586 if (ii->dqi_flags & ~DQF_SETINFO_MASK ||
2587 (ii->dqi_flags & DQF_ROOT_SQUASH &&
2588 mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD)) {
2589 err = -EINVAL;
2590 goto out;
2591 }
2592 }
2593 spin_lock(&dq_data_lock);
2594 if (ii->dqi_valid & IIF_BGRACE)
2595 mi->dqi_bgrace = ii->dqi_bgrace;
2596 if (ii->dqi_valid & IIF_IGRACE)
2597 mi->dqi_igrace = ii->dqi_igrace;
2598 if (ii->dqi_valid & IIF_FLAGS)
2599 mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) |
2600 (ii->dqi_flags & DQF_SETINFO_MASK);

--- 166 unchanged lines hidden ---
2580 spin_lock(&dq_data_lock);
2581 if (ii->dqi_valid & IIF_BGRACE)
2582 mi->dqi_bgrace = ii->dqi_bgrace;
2583 if (ii->dqi_valid & IIF_IGRACE)
2584 mi->dqi_igrace = ii->dqi_igrace;
2585 if (ii->dqi_valid & IIF_FLAGS)
2586 mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) |
2587 (ii->dqi_flags & DQF_SETINFO_MASK);

--- 166 unchanged lines hidden ---