| QUOTACTL(2) | Руководство программиста Linux | QUOTACTL(2) | 
quotactl - управление дисковыми квотами
#include <sys/quota.h> #include <xfs/xqm.h> /* для квот XFS */
int quotactl(int cmd, const char *special, int id, caddr_t addr);
С помощью системы квот можно задать каждому пользователю, группе или проекту лимит использования дискового пространства. Для пользователя или группы в каждой файловой системе можно указать необязательный (soft) и обязательный (hard) лимиты. Обязательный лимит не может быть превышен. Необязательный лимит превышать можно, но будет выдано соответствующее предостережение. Более того, пользователь может превышать необязательный лимит только в течении льготного срока (по умолчанию,одна неделя); после этого необязательный лимит будет считаться обязательным.
Управление квотами выполняется с помощью вызова quotactl(). В аргументе cmd задаётся команда, которая должна быть применена для пользовательского или группового идентификатора, указанного в id. Для инициализации значения аргумента cmd используйте макрос QCMD(subcmd, type). Значение type может быть USRQUOTA (для пользовательских квот), GRPQUOTA (для групповых квот) или (начиная с Linux 4.1) PRJQUOTA (для проектных квот). Значение subcmd описано ниже.
Аргумент special представляет собой указатель на строку, завершающуюся null и содержащую путь к блочному устройству (смонтированному) с файловой системой, на которую накладывается квота.
Аргумент addr представляет собой адрес необязательной, зависящей от команды, структуры данных, которые копируются в или из системы. Интерпретация addr указана ниже (для каждой команды).
Значением subcmd может быть одно из:
/* uint64_t имеет тип unsigned 64-bit integer;
   uint32_t имеет тип unsigned 32-bit integer */
struct dqblk {      /* определение, действующее с Linux 2.4.22 */
    uint64_t dqb_bhardlimit;  /* абсолютный лимит на выделяемые
                                 блоки дисковых квот */
    uint64_t dqb_bsoftlimit;  /* предпочтительный лимит на выделяемые
                                 блоки дисковых квот */
    uint64_t dqb_curspace;    /* занятое в данный момент пространство
                                 (в байтах) */
    uint64_t dqb_ihardlimit;  /* максимальное количество
                                 выделенных инод */
    uint64_t dqb_isoftlimit;  /* предпочтительный лимит на иноды */
    uint64_t dqb_curinodes;   /* текущее количество
                                 выделенных инод */
    uint64_t dqb_btime;       /* временной лимит по превышению
                                 использования диска */
    uint64_t dqb_itime;       /* временной лимит по превышению
                                 файлов */
    uint32_t dqb_valid;       /* битовая маска констант
                                 QIF_* */
};
/* Флаги в dqb_valid указывают, какие поля в
   структуре dqblk являются рабочими. */
#define QIF_BLIMITS   1
#define QIF_SPACE     2
#define QIF_ILIMITS   4
#define QIF_INODES    8
#define QIF_BTIME     16
#define QIF_ITIME     32
#define QIF_LIMITS    (QIF_BLIMITS | QIF_ILIMITS)
#define QIF_USAGE     (QIF_SPACE | QIF_INODES)
#define QIF_TIMES     (QIF_BTIME | QIF_ITIME)
#define QIF_ALL       (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
    
  struct nextdqblk {
    uint64_t dqb_bhardlimit;
    uint64_t dqb_bsoftlimit;
    uint64_t dqb_curspace;
    uint64_t dqb_ihardlimit;
    uint64_t dqb_isoftlimit;
    uint64_t dqb_curinodes;
    uint64_t dqb_btime;
    uint64_t dqb_itime;
    uint32_t dqb_valid;
    uint32_t dqb_id;
};
    
  /* uint64_t имеет тип unsigned 64-bit integer;
   uint32_t имеет тип unsigned 32-bit integer */
struct dqinfo {         /* определена начиная с ядра 2.4.22 */
    uint64_t dqi_bgrace;  /* период времени, после которого блоковый
                             необязательный лимит становится обязательным */
    uint64_t dqi_igrace;  /* период времени, после которого инодовый
                             необязательный лимит становится обязательным */
    uint32_t dqi_flags;   /* флаги quotafile
                             (DQF_*) */
    uint32_t dqi_valid;
};
/* биты из dqi_flags */
/* формат квот QFMT_VFS_OLD */
#define DQF_ROOT_SQUASH (1 << 0) /* включено ограничение для */
              /* суперпользователя; до Linux v4.0 это было закрытым
                 определением с именем V1_DQF_RSQUASH */
/* формат квот QFMT_VFS_V0 / QFMT_VFS_V1 */
#define DQF_SYS_FILE    (1 << 16)   /* квота хранится в
                                       системном файле */
/* флаги в dqi_valid, которые показывают какие поля в
   структуре dqinfo рабочие. */
#define IIF_BGRACE  1
#define IIF_IGRACE  2
#define IIF_FLAGS   4
#define IIF_ALL     (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
    
  Для файловых систем XFS, использующих XFS Quota Manager (XQM), приведённые выше команды не выполняются, а используются следующие команды:
#define XFS_QUOTA_UDQ_ACCT (1<<0) /* учёт пользовательских
                                     квот */
#define XFS_QUOTA_UDQ_ENFD (1<<1) /* применение лимитов
                                     пользовательских квот */
#define XFS_QUOTA_GDQ_ACCT (1<<2) /* учёт групповых
                                     квот */
#define XFS_QUOTA_GDQ_ENFD (1<<3) /* применение лимитов
                                     групповых квот */
#define XFS_QUOTA_PDQ_ACCT (1<<4) /* учёт проектных
                                     квот */
#define XFS_QUOTA_PDQ_ENFD (1<<5) /* применение лимитов
                                     проектных квот */
    
  /* все части blk в BB (Basic Blocks)
   размером 512 байт */
#define FS_DQUOT_VERSION  1  /* fs_disk_quota.d_version */
#define XFS_USER_QUOTA    (1<<0)  /* тип пользовательской квоты */
#define XFS_PROJ_QUOTA    (1<<1)  /* тип проектной квоты */
#define XFS_GROUP_QUOTA   (1<<2)  /* тип групповой квоты */
struct fs_disk_quota {
    int8_t   d_version;   /* версия данной структуры */
    int8_t   d_flags;     /* XFS_{USER,PROJ,GROUP}_QUOTA */
    uint16_t d_fieldmask; /* определитель поля */
    uint32_t d_id;        /* ID пользователя, группы или проекта */
    uint64_t d_blk_hardlimit; /* абсолютный лимит на
                                 дисковые блоки */
    uint64_t d_blk_softlimit; /* предпочтительный лимит на
                                 дисковые блоки */
    uint64_t d_ino_hardlimit; /* максимальное кол-во выделяемых
                                 инод */
    uint64_t d_ino_softlimit; /* предпочтительный лимит на иноды */
    uint64_t d_bcount;    /* # кол-во дисковых блоков,
                             принадлежащих пользователю */
    uint64_t d_icount;    /* # кол-во инод, принадлежащих пользователю */
    int32_t  d_itimer;    /* ноль, если лимит на иноды не превышен */
                          /* если нет, то нам отказывают */
    int32_t  d_btimer;    /* подобное предыдущему, но для
                             дисковых блоков */
    uint16_t d_iwarns;    /* кол-во предупреждений в соответствии с
                             кол-вом инод */
    uint16_t d_bwarns;    /* кол-во предупреждений в соответствии с
                             кол-вом дисковых блоков */
    int32_t  d_padding2;  /* заполнитель, для использования в будущем */
    uint64_t d_rtb_hardlimit; /* абсолютный лимит на работу с дисковыми
                                 блоками в реальном времени (RT) */
    uint64_t d_rtb_softlimit; /* предпочтительный лимит на дисковые блоки
                                 в RT */
    uint64_t d_rtbcount;  /* кол-во дисковых блоков под реальное время */
    int32_t  d_rtbtimer;  /* подобное предыдущему, но
                             для дисковых блоков RT */
    uint16_t d_rtbwarns;  /*  кол-во предупреждений в соответствии с
                             дисковыми блоками RT */
    int16_t  d_padding3;  /* заполнитель, для использования в будущем */
    char     d_padding4[8];   /* ещё заполнитель */
};
    
  #define FS_QSTAT_VERSION 1  /* fs_quota_stat.qs_version */
struct fs_qfilestat {
    uint64_t qfs_ino;       /* номер иноды */
    uint64_t qfs_nblks;     /* количество BB блоков
                               размером 512 байт */
    uint32_t qfs_nextents;  /* количество экстентов */
};
struct fs_quota_stat {
    int8_t   qs_version; /* номер версии
                            для изменений в будущем */
    uint16_t qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
    int8_t   qs_pad;   /* не используется */
    struct fs_qfilestat qs_uquota;  /* информация о хранилище
                                       пользовательской квоты */
    struct fs_qfilestat qs_gquota;  /* информация о хранилище
                                       групповой квоты */
    uint32_t qs_incoredqs;   /* количество dquots в ядре */
    int32_t  qs_btimelimit;  /* лимит для таймера на блоки*/
    int32_t  qs_itimelimit;  /* лимит для таймера на иноды */
    int32_t  qs_rtbtimelimit;/* лимит для таймера на
                                блоки RT */
    uint16_t qs_bwarnlimit;  /* лимит на количество предупреждений */
    uint16_t qs_iwarnlimit;  /* лимит на количество предупреждений */
};
    
  #define FS_QSTATV_VERSION1 1 /* fs_quota_statv.qs_version */
struct fs_qfilestatv {
    uint64_t qfs_ino;       /* номер иноды */
    uint64_t qfs_nblks;     /* количество BB блоков
                               размером 512 байт */
    uint32_t qfs_nextents;  /* количество экстентов */
    uint32_t qfs_pad;       /* заполнитель для 8-байтового выравнивания */
};
struct fs_quota_statv {
    int8_t   qs_version;    /* версия для изменений
                               в будущем */
    uint8_t  qs_pad1;       /* заполнитель для 16-битного выравнивания */
    uint16_t qs_flags;      /* флаги XFS_QUOTA_.* */
    uint32_t qs_incoredqs;  /* количество dquots incore */
    struct fs_qfilestatv qs_uquota;  /* информация
                                        о пользовательской квоте */
    struct fs_qfilestatv qs_gquota;  /* информация
                                        о групповой квоте */
    struct fs_qfilestatv qs_pquota;  /* информация
                                        о проектной квоте */
    int32_t  qs_btimelimit;   /* лимит по таймеру на блоки */
    int32_t  qs_itimelimit;   /* лимит по таймеру на иноды */
    int32_t  qs_rtbtimelimit; /* лимит по таймеру
                                 на блоки RT */
    uint16_t qs_bwarnlimit;   /* лимит на кол-во предупреждений */
    uint16_t qs_iwarnlimit;   /* лимит на кол-во предупреждений */
    uint64_t qs_pad2[8];      /* для использования в будущем */
};
    
  При успешном выполнении quotactl() возвращается 0; при ошибке возвращается -1, а в errno содержится код ошибки.
Вместо <xfs/xqm.h> может быть использован <linux/dqblk_xfs.h>, но следует учесть, что есть несколько несоответствий названий:
| 2017-09-15 | Linux |