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@google.com> 11 * Header of IO operations for quota utilities 12 * 13 * Jan Kara <jack@suse.cz> 14 * 15 * Hyojun Kim <hyojun@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