Home | History | Annotate | Download | only in fsck
      1 /** quotaio.h
      2  *
      3  * Interface to the quota library.
      4  *
      5  * The quota library provides interface for creating and updating the quota
      6  * files and the ext4 superblock fields. It supports the new VFS_V1 quota
      7  * format. The quota library also provides support for keeping track of quotas
      8  * in memory.
      9  *
     10  * Aditya Kali <adityakali (at) google.com>
     11  * Header of IO operations for quota utilities
     12  *
     13  * Jan Kara <jack (at) suse.cz>
     14  *
     15  * Hyojun Kim <hyojun (at) google.com> - Ported to f2fs-tools
     16  */
     17 
     18 #ifndef GUARD_QUOTAIO_H
     19 #define GUARD_QUOTAIO_H
     20 
     21 #include <limits.h>
     22 #include <sys/types.h>
     23 #include <sys/stat.h>
     24 #include <arpa/inet.h>
     25 
     26 #include "dict.h"
     27 #include "f2fs_fs.h"
     28 #include "f2fs.h"
     29 #include "node.h"
     30 #include "fsck.h"
     31 
     32 #include "dqblk_v2.h"
     33 
     34 typedef int64_t qsize_t;	/* Type in which we store size limitations */
     35 typedef int32_t f2fs_ino_t;
     36 typedef int errcode_t;
     37 
     38 enum quota_type {
     39 	USRQUOTA = 0,
     40 	GRPQUOTA = 1,
     41 	PRJQUOTA = 2,
     42 	MAXQUOTAS = 3,
     43 };
     44 
     45 #if MAXQUOTAS > 32
     46 #error "cannot have more than 32 quota types to fit in qtype_bits"
     47 #endif
     48 
     49 
     50 #define QUOTA_USR_BIT (1 << USRQUOTA)
     51 #define QUOTA_GRP_BIT (1 << GRPQUOTA)
     52 #define QUOTA_PRJ_BIT (1 << PRJQUOTA)
     53 #define QUOTA_ALL_BIT (QUOTA_USR_BIT | QUOTA_GRP_BIT | QUOTA_PRJ_BIT)
     54 
     55 typedef struct quota_ctx *quota_ctx_t;
     56 
     57 struct quota_ctx {
     58 	struct f2fs_sb_info *sbi;
     59 	struct dict_t *quota_dict[MAXQUOTAS];
     60 	struct quota_handle *quota_file[MAXQUOTAS];
     61 	struct dict_t linked_inode_dict;
     62 };
     63 
     64 /*
     65  * Definitions of magics and versions of current quota files
     66  */
     67 #define INITQMAGICS {\
     68 	0xd9c01f11,	/* USRQUOTA */\
     69 	0xd9c01927,	/* GRPQUOTA */\
     70 	0xd9c03f14	/* PRJQUOTA */\
     71 }
     72 
     73 /* Size of blocks in which are counted size limits in generic utility parts */
     74 #define QUOTABLOCK_BITS 10
     75 #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
     76 #define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
     77 
     78 /* Quota format type IDs */
     79 #define	QFMT_VFS_OLD 1
     80 #define	QFMT_VFS_V0 2
     81 #define	QFMT_VFS_V1 4
     82 
     83 /*
     84  * The following constants define the default amount of time given a user
     85  * before the soft limits are treated as hard limits (usually resulting
     86  * in an allocation failure). The timer is started when the user crosses
     87  * their soft limit, it is reset when they go below their soft limit.
     88  */
     89 #define MAX_IQ_TIME  604800	/* (7*24*60*60) 1 week */
     90 #define MAX_DQ_TIME  604800	/* (7*24*60*60) 1 week */
     91 
     92 #define IOFL_INFODIRTY	0x01	/* Did info change? */
     93 
     94 struct quotafile_ops;
     95 
     96 /* Generic information about quotafile */
     97 struct util_dqinfo {
     98 	time_t dqi_bgrace;	/* Block grace time for given quotafile */
     99 	time_t dqi_igrace;	/* Inode grace time for given quotafile */
    100 	union {
    101 		struct v2_mem_dqinfo v2_mdqi;
    102 	} u;			/* Format specific info about quotafile */
    103 };
    104 
    105 struct quota_file {
    106 	struct f2fs_sb_info *sbi;
    107 	f2fs_ino_t ino;
    108 	int64_t filesize;
    109 };
    110 
    111 /* Structure for one opened quota file */
    112 struct quota_handle {
    113 	enum quota_type qh_type;	/* Type of quotafile */
    114 	int qh_fmt;		/* Quotafile format */
    115 	int qh_file_flags;
    116 	int qh_io_flags;	/* IO flags for file */
    117 	struct quota_file qh_qf;
    118 	unsigned int (*read)(struct quota_file *qf, long offset,
    119 			 void *buf, unsigned int size);
    120 	unsigned int (*write)(struct quota_file *qf, long offset,
    121 			  void *buf, unsigned int size);
    122 	struct quotafile_ops *qh_ops;	/* Operations on quotafile */
    123 	struct util_dqinfo qh_info;	/* Generic quotafile info */
    124 };
    125 
    126 /* Utility quota block */
    127 struct util_dqblk {
    128 	qsize_t dqb_ihardlimit;
    129 	qsize_t dqb_isoftlimit;
    130 	qsize_t dqb_curinodes;
    131 	qsize_t dqb_bhardlimit;
    132 	qsize_t dqb_bsoftlimit;
    133 	qsize_t dqb_curspace;
    134 	time_t dqb_btime;
    135 	time_t dqb_itime;
    136 	union {
    137 		struct v2_mem_dqblk v2_mdqb;
    138 	} u;			/* Format specific dquot information */
    139 };
    140 
    141 /* Structure for one loaded quota */
    142 struct dquot {
    143 	struct dquot *dq_next;	/* Pointer to next dquot in the list */
    144 	qid_t dq_id;		/* ID dquot belongs to */
    145 	int dq_flags;		/* Some flags for utils */
    146 	struct quota_handle *dq_h;	/* Handle of quotafile for this dquot */
    147 	struct util_dqblk dq_dqb;	/* Parsed data of dquot */
    148 };
    149 
    150 #define DQF_SEEN	0x0001
    151 
    152 /* Structure of quotafile operations */
    153 struct quotafile_ops {
    154 	/* Check whether quotafile is in our format */
    155 	int (*check_file) (struct quota_handle *h, int type);
    156 	/* Open quotafile */
    157 	int (*init_io) (struct quota_handle *h);
    158 	/* Create new quotafile */
    159 	int (*new_io) (struct quota_handle *h);
    160 	/* Write all changes and close quotafile */
    161 	int (*end_io) (struct quota_handle *h);
    162 	/* Write info about quotafile */
    163 	int (*write_info) (struct quota_handle *h);
    164 	/* Read dquot into memory */
    165 	struct dquot *(*read_dquot) (struct quota_handle *h, qid_t id);
    166 	/* Write given dquot to disk */
    167 	int (*commit_dquot) (struct dquot *dquot);
    168 	/* Scan quotafile and call callback on every structure */
    169 	int (*scan_dquots) (struct quota_handle *h,
    170 			    int (*process_dquot) (struct dquot *dquot,
    171 						  void *data),
    172 			    void *data);
    173 	/* Function to print format specific file information */
    174 	int (*report) (struct quota_handle *h, int verbose);
    175 };
    176 
    177 #ifdef __CHECKER__
    178 # ifndef __bitwise
    179 #  define __bitwise             __attribute__((bitwise))
    180 # endif
    181 #define __force                 __attribute__((force))
    182 #else
    183 # ifndef __bitwise
    184 #  define __bitwise
    185 # endif
    186 #define __force
    187 #endif
    188 
    189 #define be32_to_cpu(n) ntohl(n)
    190 
    191 /* Open existing quotafile of given type (and verify its format) on given
    192  * filesystem. */
    193 errcode_t quota_file_open(struct f2fs_sb_info *sbi, struct quota_handle *h,
    194 			  enum quota_type qtype, int flags);
    195 
    196 /* Create new quotafile of specified format on given filesystem */
    197 errcode_t quota_file_create(struct f2fs_sb_info *sbi, struct quota_handle *h,
    198 		enum quota_type qtype);
    199 
    200 /* Close quotafile */
    201 errcode_t quota_file_close(struct f2fs_sb_info *sbi, struct quota_handle *h,
    202 		int update_filesize);
    203 
    204 /* Get empty quota structure */
    205 struct dquot *get_empty_dquot(void);
    206 const char *quota_type2name(enum quota_type qtype);
    207 void update_grace_times(struct dquot *q);
    208 
    209 /* In mkquota.c */
    210 errcode_t quota_init_context(struct f2fs_sb_info *sbi);
    211 void quota_data_inodes(quota_ctx_t qctx, struct f2fs_inode *inode, int adjust);
    212 void quota_data_add(quota_ctx_t qctx, struct f2fs_inode *inode, qsize_t space);
    213 void quota_data_sub(quota_ctx_t qctx, struct f2fs_inode *inode, qsize_t space);
    214 errcode_t quota_write_inode(struct f2fs_sb_info *sbi, enum quota_type qtype);
    215 void quota_add_inode_usage(quota_ctx_t qctx, f2fs_ino_t ino,
    216 		struct f2fs_inode* inode);
    217 void quota_release_context(quota_ctx_t *qctx);
    218 errcode_t quota_compare_and_update(struct f2fs_sb_info *sbi,
    219 		enum quota_type qtype, int *usage_inconsistent,
    220 		int preserve_limits);
    221 
    222 static inline errcode_t quota_get_mem(unsigned long size, void *ptr)
    223 {
    224         void *pp;
    225 
    226         pp = malloc(size);
    227         if (!pp)
    228                 return -1;
    229         memcpy(ptr, &pp, sizeof (pp));
    230         return 0;
    231 }
    232 
    233 static inline errcode_t quota_get_memzero(unsigned long size, void *ptr)
    234 {
    235         void *pp;
    236 
    237         pp = malloc(size);
    238         if (!pp)
    239                 return -1;
    240         memset(pp, 0, size);
    241         memcpy(ptr, &pp, sizeof(pp));
    242         return 0;
    243 }
    244 
    245 static inline errcode_t quota_free_mem(void *ptr)
    246 {
    247         void *p;
    248 
    249         memcpy(&p, ptr, sizeof(p));
    250         free(p);
    251         p = 0;
    252         memcpy(ptr, &p, sizeof(p));
    253         return 0;
    254 }
    255 
    256 #endif /* GUARD_QUOTAIO_H */
    257