49
int quota_is_on(ext2_filsys fs, int type)
52
qid_t id = (type == USRQUOTA) ? getuid() : getgid();
55
if (!quotactl(QCMD(Q_V2_GETQUOTA, type), fs->device_name, id, tmp))
62
49
* Returns 0 if not able to find the quota file, otherwise returns its
71
58
if (qtype >= MAXQUOTAS)
74
quota_get_qf_name(qtype, fmt, qf_name);
61
quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name);
76
63
ret = ext2fs_lookup(fs, EXT2_ROOT_INO, qf_name, strlen(qf_name), 0,
414
401
struct scan_dquots_data {
416
int limit_only; /* read limit only */
403
int update_limits; /* update limits from disk */
405
int usage_is_inconsistent;
419
408
static int scan_dquots_callback(struct dquot *dquot, void *cb_data)
421
struct scan_dquots_data *scan_data =
422
(struct scan_dquots_data *)cb_data;
423
quota_ctx_t qctx = scan_data->qctx;
410
struct scan_dquots_data *scan_data = cb_data;
411
dict_t *quota_dict = scan_data->quota_dict;
424
412
struct dquot *dq;
426
dq = get_dq(qctx->quota_dict[dquot->dq_h->qh_type], dquot->dq_id);
414
dq = get_dq(quota_dict, dquot->dq_id);
428
415
dq->dq_id = dquot->dq_id;
429
if (scan_data->limit_only) {
430
dq->dq_dqb.u.v2_mdqb.dqb_off = dquot->dq_dqb.u.v2_mdqb.dqb_off;
417
/* Check if there is inconsistancy. */
418
if (dq->dq_dqb.dqb_curspace != dquot->dq_dqb.dqb_curspace ||
419
dq->dq_dqb.dqb_curinodes != dquot->dq_dqb.dqb_curinodes) {
420
scan_data->usage_is_inconsistent = 1;
421
log_err("Usage inconsistent for ID %d: (%llu, %llu) != "
422
"(%llu, %llu)", dq->dq_id, dq->dq_dqb.dqb_curspace,
423
dq->dq_dqb.dqb_curinodes, dquot->dq_dqb.dqb_curspace,
424
dquot->dq_dqb.dqb_curinodes);
427
if (scan_data->update_limits) {
431
428
dq->dq_dqb.dqb_ihardlimit = dquot->dq_dqb.dqb_ihardlimit;
432
429
dq->dq_dqb.dqb_isoftlimit = dquot->dq_dqb.dqb_isoftlimit;
433
430
dq->dq_dqb.dqb_bhardlimit = dquot->dq_dqb.dqb_bhardlimit;
434
431
dq->dq_dqb.dqb_bsoftlimit = dquot->dq_dqb.dqb_bsoftlimit;
436
dq->dq_dqb = dquot->dq_dqb;
434
if (scan_data->update_usage) {
435
dq->dq_dqb.dqb_curspace = dquot->dq_dqb.dqb_curspace;
436
dq->dq_dqb.dqb_curinodes = dquot->dq_dqb.dqb_curinodes;
442
443
* Read all dquots from quota file into memory
444
445
static errcode_t quota_read_all_dquots(struct quota_handle *qh,
445
quota_ctx_t qctx, int limit_only)
446
quota_ctx_t qctx, int update_limits)
447
448
struct scan_dquots_data scan_data;
449
scan_data.qctx = qctx;
450
scan_data.limit_only = limit_only;
450
scan_data.quota_dict = qctx->quota_dict[qh->qh_type];
451
scan_data.update_limits = update_limits;
452
scan_data.update_usage = 0;
452
454
return qh->qh_ops->scan_dquots(qh, scan_dquots_callback, &scan_data);
507
509
ext2fs_free_mem(&qh);
514
* Compares the measured quota in qctx->quota_dict with that in the quota inode
515
* on disk and updates the limits in qctx->quota_dict. 'usage_inconsistent' is
516
* set to 1 if the supplied and on-disk quota usage values are not identical.
518
errcode_t quota_compare_and_update(quota_ctx_t qctx, int qtype,
519
int *usage_inconsistent)
521
ext2_filsys fs = qctx->fs;
522
struct quota_handle qh;
523
struct scan_dquots_data scan_data;
527
if (!qctx->quota_dict[qtype])
530
qf_ino = qtype == USRQUOTA ? fs->super->s_usr_quota_inum :
531
fs->super->s_grp_quota_inum;
532
err = quota_file_open(&qh, fs, qf_ino, qtype, -1, 0);
534
log_err("Open quota file failed", "");
538
scan_data.quota_dict = qctx->quota_dict[qtype];
539
scan_data.update_limits = 1;
540
scan_data.update_usage = 0;
541
scan_data.usage_is_inconsistent = 0;
542
err = qh.qh_ops->scan_dquots(&qh, scan_dquots_callback, &scan_data);
544
log_err("Error scanning dquots", "");
547
*usage_inconsistent = scan_data.usage_is_inconsistent;