~daniel-mehrmann/e2fsprogs/master

« back to all changes in this revision

Viewing changes to lib/quota/mkquota.c

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2012-06-14 13:01:21 UTC
  • mfrom: (8.4.18 sid)
  • Revision ID: package-import@ubuntu.com-20120614130121-t2gct0d09jepx0y6
Tags: 1.42.4-3ubuntu1
* Merge from Debian unstable (LP: #978012), remainging changes:
  - debian/control.in: 
      Build-depend on gettext:any instead of on gettext for (cross-building)
      Drop build dependency on dc, which hasn't been needed for some time.
      Update maintainer field.
  - debian/rules:
      Block pkg-create-dbgsym from operating on this package.
      Build without dietlibc-dev, which is in universe 
  - debian/control:
      Regenerate with ./debian/rules debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
#include "ext2fs/ext2fs.h"
16
16
#include "e2p/e2p.h"
17
17
 
18
 
#include "quota.h"
19
18
#include "quotaio.h"
20
19
#include "quotaio_v2.h"
21
20
#include "quotaio_tree.h"
46
45
        return;
47
46
}
48
47
 
49
 
int quota_is_on(ext2_filsys fs, int type)
50
 
{
51
 
        char tmp[1024];
52
 
        qid_t id = (type == USRQUOTA) ? getuid() : getgid();
53
 
 
54
 
#ifdef HAVE_QUOTACTL
55
 
        if (!quotactl(QCMD(Q_V2_GETQUOTA, type), fs->device_name, id, tmp))
56
 
                return 1;
57
 
#endif
58
 
        return 0;
59
 
}
60
 
 
61
48
/*
62
49
 * Returns 0 if not able to find the quota file, otherwise returns its
63
50
 * inode number.
71
58
        if (qtype >= MAXQUOTAS)
72
59
                return -EINVAL;
73
60
 
74
 
        quota_get_qf_name(qtype, fmt, qf_name);
 
61
        quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name);
75
62
 
76
63
        ret = ext2fs_lookup(fs, EXT2_ROOT_INO, qf_name, strlen(qf_name), 0,
77
64
                            &ino);
412
399
}
413
400
 
414
401
struct scan_dquots_data {
415
 
        quota_ctx_t         qctx;
416
 
        int                 limit_only; /* read limit only */
 
402
        dict_t          *quota_dict;
 
403
        int             update_limits; /* update limits from disk */
 
404
        int             update_usage;
 
405
        int             usage_is_inconsistent;
417
406
};
418
407
 
419
408
static int scan_dquots_callback(struct dquot *dquot, void *cb_data)
420
409
{
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;
425
413
 
426
 
        dq = get_dq(qctx->quota_dict[dquot->dq_h->qh_type], dquot->dq_id);
427
 
 
 
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;
 
416
 
 
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);
 
425
        }
 
426
 
 
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;
435
 
        } else {
436
 
                dq->dq_dqb = dquot->dq_dqb;
437
 
        }
 
432
        }
 
433
 
 
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;
 
437
        }
 
438
 
438
439
        return 0;
439
440
}
440
441
 
442
443
 * Read all dquots from quota file into memory
443
444
 */
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)
446
447
{
447
448
        struct scan_dquots_data scan_data;
448
449
 
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;
451
453
 
452
454
        return qh->qh_ops->scan_dquots(qh, scan_dquots_callback, &scan_data);
453
455
}
507
509
        ext2fs_free_mem(&qh);
508
510
        return err;
509
511
}
 
512
 
 
513
/*
 
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.
 
517
 */
 
518
errcode_t quota_compare_and_update(quota_ctx_t qctx, int qtype,
 
519
                                   int *usage_inconsistent)
 
520
{
 
521
        ext2_filsys fs = qctx->fs;
 
522
        struct quota_handle qh;
 
523
        struct scan_dquots_data scan_data;
 
524
        ext2_ino_t qf_ino;
 
525
        errcode_t err = 0;
 
526
 
 
527
        if (!qctx->quota_dict[qtype])
 
528
                goto out;
 
529
 
 
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);
 
533
        if (err) {
 
534
                log_err("Open quota file failed", "");
 
535
                goto out;
 
536
        }
 
537
 
 
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);
 
543
        if (err) {
 
544
                log_err("Error scanning dquots", "");
 
545
                goto out;
 
546
        }
 
547
        *usage_inconsistent = scan_data.usage_is_inconsistent;
 
548
 
 
549
out:
 
550
        return err;
 
551
}