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 --- |