1/* 2 * GPL HEADER START 3 * 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 only, 8 * as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License version 2 for more details (a copy is included 14 * in the LICENSE file that accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License 17 * version 2 along with this program; if not, write to the 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 * Boston, MA 021110-1307, USA 20 * 21 * GPL HEADER END 22 */ 23/* 24 * Copyright (c) 2011, 2012, Intel Corporation. 25 * Use is subject to license terms. 26 */ 27 28#ifndef _LUSTRE_QUOTA_H 29#define _LUSTRE_QUOTA_H 30 31/** \defgroup quota quota 32 * 33 */ 34 35#include <linux/fs.h> 36#include <linux/quota.h> 37#include <linux/quotaops.h> 38 39#include "dt_object.h" 40#include "lustre_fid.h" 41#include "lustre_dlm.h" 42 43#ifndef MAX_IQ_TIME 44#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */ 45#endif 46 47#ifndef MAX_DQ_TIME 48#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */ 49#endif 50 51struct lquota_id_info; 52struct lquota_trans; 53 54/* Gather all quota record type in an union that can be used to read any records 55 * from disk. All fields of these records must be 64-bit aligned, otherwise the 56 * OSD layer may swab them incorrectly. */ 57union lquota_rec { 58 struct lquota_glb_rec lqr_glb_rec; 59 struct lquota_slv_rec lqr_slv_rec; 60 struct lquota_acct_rec lqr_acct_rec; 61}; 62 63/* Index features supported by the global index objects 64 * Only used for migration purpose and should be removed once on-disk migration 65 * is no longer needed */ 66extern struct dt_index_features dt_quota_iusr_features; 67extern struct dt_index_features dt_quota_busr_features; 68extern struct dt_index_features dt_quota_igrp_features; 69extern struct dt_index_features dt_quota_bgrp_features; 70 71/* Name used in the configuration logs to identify the default metadata pool 72 * (composed of all the MDTs, with pool ID 0) and the default data pool (all 73 * the OSTs, with pool ID 0 too). */ 74#define QUOTA_METAPOOL_NAME "mdt=" 75#define QUOTA_DATAPOOL_NAME "ost=" 76 77/* 78 * Quota Master Target support 79 */ 80 81/* Request handlers for quota master operations. 82 * This is used by the MDT to pass quota/lock requests to the quota master 83 * target. This won't be needed any more once the QMT is a real target and 84 * does not rely any more on the MDT service threads and namespace. */ 85struct qmt_handlers { 86 /* Handle quotactl request from client. */ 87 int (*qmth_quotactl)(const struct lu_env *, struct lu_device *, 88 struct obd_quotactl *); 89 90 /* Handle dqacq/dqrel request from slave. */ 91 int (*qmth_dqacq)(const struct lu_env *, struct lu_device *, 92 struct ptlrpc_request *); 93 94 /* LDLM intent policy associated with quota locks */ 95 int (*qmth_intent_policy)(const struct lu_env *, struct lu_device *, 96 struct ptlrpc_request *, struct ldlm_lock **, 97 int); 98 99 /* Initialize LVB of ldlm resource associated with quota objects */ 100 int (*qmth_lvbo_init)(struct lu_device *, struct ldlm_resource *); 101 102 /* Update LVB of ldlm resource associated with quota objects */ 103 int (*qmth_lvbo_update)(struct lu_device *, struct ldlm_resource *, 104 struct ptlrpc_request *, int); 105 106 /* Return size of LVB to be packed in ldlm message */ 107 int (*qmth_lvbo_size)(struct lu_device *, struct ldlm_lock *); 108 109 /* Fill request buffer with lvb */ 110 int (*qmth_lvbo_fill)(struct lu_device *, struct ldlm_lock *, void *, 111 int); 112 113 /* Free lvb associated with ldlm resource */ 114 int (*qmth_lvbo_free)(struct lu_device *, struct ldlm_resource *); 115}; 116 117/* actual handlers are defined in lustre/quota/qmt_handler.c */ 118extern struct qmt_handlers qmt_hdls; 119 120/* 121 * Quota enforcement support on slaves 122 */ 123 124struct qsd_instance; 125 126/* The quota slave feature is implemented under the form of a library. 127 * The API is the following: 128 * 129 * - qsd_init(): the user (mostly the OSD layer) should first allocate a qsd 130 * instance via qsd_init(). This creates all required structures 131 * to manage quota enforcement for this target and performs all 132 * low-level initialization which does not involve any lustre 133 * object. qsd_init() should typically be called when the OSD 134 * is being set up. 135 * 136 * - qsd_prepare(): This sets up on-disk objects associated with the quota slave 137 * feature and initiates the quota reintegration procedure if 138 * needed. qsd_prepare() should typically be called when 139 * ->ldo_prepare is invoked. 140 * 141 * - qsd_start(): a qsd instance should be started once recovery is completed 142 * (i.e. when ->ldo_recovery_complete is called). This is used 143 * to notify the qsd layer that quota should now be enforced 144 * again via the qsd_op_begin/end functions. The last step of the 145 * reintegration procedure (namely usage reconciliation) will be 146 * completed during start. 147 * 148 * - qsd_fini(): is used to release a qsd_instance structure allocated with 149 * qsd_init(). This releases all quota slave objects and frees the 150 * structures associated with the qsd_instance. 151 * 152 * - qsd_op_begin(): is used to enforce quota, it must be called in the 153 * declaration of each operation. qsd_op_end() should then be 154 * invoked later once all operations have been completed in 155 * order to release/adjust the quota space. 156 * Running qsd_op_begin() before qsd_start() isn't fatal and 157 * will return success. 158 * Once qsd_start() has been run, qsd_op_begin() will block 159 * until the reintegration procedure is completed. 160 * 161 * - qsd_op_end(): performs the post operation quota processing. This must be 162 * called after the operation transaction stopped. 163 * While qsd_op_begin() must be invoked each time a new 164 * operation is declared, qsd_op_end() should be called only 165 * once for the whole transaction. 166 * 167 * - qsd_op_adjust(): triggers pre-acquire/release if necessary. 168 * 169 * Below are the function prototypes to be used by OSD layer to manage quota 170 * enforcement. Arguments are documented where each function is defined. */ 171 172struct qsd_instance *qsd_init(const struct lu_env *, char *, struct dt_device *, 173 struct proc_dir_entry *); 174int qsd_prepare(const struct lu_env *, struct qsd_instance *); 175int qsd_start(const struct lu_env *, struct qsd_instance *); 176void qsd_fini(const struct lu_env *, struct qsd_instance *); 177int qsd_op_begin(const struct lu_env *, struct qsd_instance *, 178 struct lquota_trans *, struct lquota_id_info *, int *); 179void qsd_op_end(const struct lu_env *, struct qsd_instance *, 180 struct lquota_trans *); 181void qsd_op_adjust(const struct lu_env *, struct qsd_instance *, 182 union lquota_id *, int); 183/* This is exported for the ldiskfs quota migration only, 184 * see convert_quota_file() */ 185int lquota_disk_write_glb(const struct lu_env *, struct dt_object *, 186 __u64, struct lquota_glb_rec *); 187 188/* 189 * Quota information attached to a transaction 190 */ 191 192struct lquota_entry; 193 194struct lquota_id_info { 195 /* quota identifier */ 196 union lquota_id lqi_id; 197 198 /* USRQUOTA or GRPQUOTA for now, could be expanded for 199 * directory quota or other types later. */ 200 int lqi_type; 201 202 /* inodes or kbytes to be consumed or released, it could 203 * be negative when releasing space. */ 204 long long lqi_space; 205 206 /* quota slave entry structure associated with this ID */ 207 struct lquota_entry *lqi_qentry; 208 209 /* whether we are reporting blocks or inodes */ 210 bool lqi_is_blk; 211}; 212 213/* Since we enforce only inode quota in meta pool (MDTs), and block quota in 214 * data pool (OSTs), there are at most 4 quota ids being enforced in a single 215 * transaction, which is chown transaction: 216 * original uid and gid, new uid and gid. 217 * 218 * This value might need to be revised when directory quota is added. */ 219#define QUOTA_MAX_TRANSIDS 4 220 221/* all qids involved in a single transaction */ 222struct lquota_trans { 223 unsigned short lqt_id_cnt; 224 struct lquota_id_info lqt_ids[QUOTA_MAX_TRANSIDS]; 225}; 226 227/* flags for quota local enforcement */ 228#define QUOTA_FL_OVER_USRQUOTA 0x01 229#define QUOTA_FL_OVER_GRPQUOTA 0x02 230#define QUOTA_FL_SYNC 0x04 231 232#define IS_LQUOTA_RES(res) \ 233 (res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA || \ 234 res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA_GLB) 235 236/* helper function used by MDT & OFD to retrieve quota accounting information 237 * on slave */ 238int lquotactl_slv(const struct lu_env *, struct dt_device *, 239 struct obd_quotactl *); 240/** @} quota */ 241#endif /* _LUSTRE_QUOTA_H */ 242