3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 only,
7 * as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License version 2 for more details (a copy is included
13 * in the LICENSE file that accompanied this code).
15 * You should have received a copy of the GNU General Public License
16 * version 2 along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 021110-1307, USA
23 * Copyright (c) 2011, 2012, Intel, Inc.
24 * Use is subject to license terms.
26 * Author: Johann Lombardi <johann.lombardi@intel.com>
27 * Author: Niu Yawei <yawei.niu@intel.com>
31 # define EXPORT_SYMTAB
34 #define DEBUG_SUBSYSTEM S_LQUOTA
36 #include <linux/module.h>
37 #include <linux/slab.h>
38 #include <obd_class.h>
39 #include "lquota_internal.h"
41 static int hash_lqs_cur_bits = HASH_LQE_CUR_BITS;
42 CFS_MODULE_PARM(hash_lqs_cur_bits, "i", int, 0444,
43 "the current bits of lqe hash");
44 cfs_mem_cache_t *lqe_kmem;
46 static unsigned lqe64_hash_hash(cfs_hash_t *hs, const void *key, unsigned mask)
48 return cfs_hash_u64_hash(*((__u64 *)key), mask);
51 static void *lqe64_hash_key(cfs_hlist_node_t *hnode)
53 struct lquota_entry *lqe;
54 lqe = cfs_hlist_entry(hnode, struct lquota_entry, lqe_hash);
55 return &lqe->lqe_id.qid_uid;
58 static int lqe64_hash_keycmp(const void *key, cfs_hlist_node_t *hnode)
60 struct lquota_entry *lqe;
61 lqe = cfs_hlist_entry(hnode, struct lquota_entry, lqe_hash);
62 return (lqe->lqe_id.qid_uid == *((__u64*)key));
65 static void *lqe_hash_object(cfs_hlist_node_t *hnode)
67 return cfs_hlist_entry(hnode, struct lquota_entry, lqe_hash);
70 static void lqe_hash_get(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
72 struct lquota_entry *lqe;
73 lqe = cfs_hlist_entry(hnode, struct lquota_entry, lqe_hash);
77 static void lqe_hash_put_locked(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
79 struct lquota_entry *lqe;
80 lqe = cfs_hlist_entry(hnode, struct lquota_entry, lqe_hash);
84 static void lqe_hash_exit(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
86 CERROR("Should not have any item left!\n");
89 /* lqe hash methods for 64-bit uid/gid, new hash functions would have to be
90 * defined for per-directory quota relying on a 128-bit FID */
91 static cfs_hash_ops_t lqe64_hash_ops = {
92 .hs_hash = lqe64_hash_hash,
93 .hs_key = lqe64_hash_key,
94 .hs_keycmp = lqe64_hash_keycmp,
95 .hs_object = lqe_hash_object,
96 .hs_get = lqe_hash_get,
97 .hs_put_locked = lqe_hash_put_locked,
98 .hs_exit = lqe_hash_exit
101 /* Logging helper function */
102 void lquota_lqe_debug0(struct lquota_entry *lqe,
103 struct libcfs_debug_msg_data *msgdata,
104 const char *fmt, ...)
106 struct lquota_site *site = lqe->lqe_site;
109 LASSERT(site->lqs_ops->lqe_debug != NULL);
112 site->lqs_ops->lqe_debug(lqe, site->lqs_parent, msgdata, fmt, args);
116 struct lqe_iter_data {
117 unsigned long lid_inuse;
118 unsigned long lid_freed;
122 static int lqe_iter_cb(cfs_hash_t *hs, cfs_hash_bd_t *bd,
123 cfs_hlist_node_t *hnode, void *data)
125 struct lqe_iter_data *d = (struct lqe_iter_data *)data;
126 struct lquota_entry *lqe;
128 lqe = cfs_hlist_entry(hnode, struct lquota_entry, lqe_hash);
129 LASSERT(atomic_read(&lqe->lqe_ref) > 0);
131 /* Only one reference held by hash table, and nobody else can
132 * grab the entry at this moment, it's safe to remove it from
133 * the hash and free it. */
134 if (atomic_read(&lqe->lqe_ref) == 1) {
135 if (!lqe_is_master(lqe)) {
136 LASSERT(lqe->lqe_pending_write == 0);
137 LASSERT(lqe->lqe_pending_req == 0);
139 if (d->lid_free_all || lqe->lqe_enforced) {
141 cfs_hash_bd_del_locked(hs, bd, hnode);
148 LQUOTA_ERROR(lqe, "Inuse quota entry");
153 * Cleanup the entries in the hashtable
155 * \param hash - hash table which stores quota entries
156 * \param free_all - free all entries or only free the entries
157 * without quota enforce ?
159 static void lqe_cleanup(cfs_hash_t *hash, bool free_all)
161 struct lqe_iter_data d;
165 memset(&d, 0, sizeof(d));
166 d.lid_free_all = free_all;
168 cfs_hash_for_each_safe(hash, lqe_iter_cb, &d);
170 /* In most case, when this function is called on master or
171 * slave finalization, there should be no inuse quota entry.
173 * If the per-fs quota updating thread is still holding
174 * some entries, we just wait for it's finished. */
175 if (free_all && d.lid_inuse) {
176 CDEBUG(D_QUOTA, "Hash:%p has entries inuse: inuse:%lu, "
177 "freed:%lu, repeat:%u\n", hash,
178 d.lid_inuse, d.lid_freed, repeat);
180 cfs_schedule_timeout_and_set_state(CFS_TASK_INTERRUPTIBLE,
181 cfs_time_seconds(1));
188 * Allocate a new lquota site.
190 * \param env - the environment passed by the caller
191 * \param parent - is a pointer to the parent structure, either a qmt_pool_info
192 * structure on the master or a qsd_qtype_info structure on the
194 * \param is_master - is set when the site belongs to a QMT.
195 * \param qtype - is the quota type managed by this site
196 * \param ops - is the quota entry operation vector to be used for quota
197 * entry belonging to this site.
199 * \retval 0 - success
200 * \retval -ve - failure
202 struct lquota_site *lquota_site_alloc(const struct lu_env *env, void *parent,
203 bool is_master, short qtype,
204 struct lquota_entry_operations *ops)
206 struct lquota_site *site;
210 LASSERT(qtype < MAXQUOTAS);
214 RETURN(ERR_PTR(-ENOMEM));
216 /* assign parameters */
217 site->lqs_qtype = qtype;
218 site->lqs_parent = parent;
219 site->lqs_is_mst = is_master;
222 /* allocate hash table */
223 memset(hashname, 0, sizeof(hashname));
224 sprintf(hashname, "LQUOTA_HASH%u", qtype);
225 site->lqs_hash= cfs_hash_create(hashname, hash_lqs_cur_bits,
227 min(hash_lqs_cur_bits,
229 0, CFS_HASH_MIN_THETA,
230 CFS_HASH_MAX_THETA, &lqe64_hash_ops,
231 CFS_HASH_DEFAULT|CFS_HASH_BIGNAME);
232 if (site->lqs_hash == NULL) {
234 RETURN(ERR_PTR(-ENOMEM));
241 * Destroy a lquota site.
243 * \param env - the environment passed by the caller
244 * \param site - lquota site to be destroyed
246 * \retval 0 - success
247 * \retval -ve - failure
249 void lquota_site_free(const struct lu_env *env, struct lquota_site *site)
251 /* cleanup hash table */
252 lqe_cleanup(site->lqs_hash, true);
253 cfs_hash_putref(site->lqs_hash);
255 site->lqs_parent = NULL;
260 * Initialize qsd/qmt-specific fields of quota entry.
262 * \param lqe - is the quota entry to initialize
264 static void lqe_init(struct lquota_entry *lqe)
266 struct lquota_site *site;
269 LASSERT(lqe != NULL);
270 site = lqe->lqe_site;
271 LASSERT(site != NULL);
272 LASSERT(site->lqs_ops->lqe_init != NULL);
274 LQUOTA_DEBUG(lqe, "init");
276 site->lqs_ops->lqe_init(lqe, site->lqs_parent);
280 * Update a lquota entry. This is done by reading quota settings from the
281 * on-disk index. The lquota entry must be write locked.
283 * \param env - the environment passed by the caller
284 * \param lqe - is the quota entry to refresh
286 static int lqe_read(const struct lu_env *env, struct lquota_entry *lqe)
288 struct lquota_site *site;
292 LASSERT(lqe != NULL);
293 site = lqe->lqe_site;
294 LASSERT(site != NULL);
295 LASSERT(site->lqs_ops->lqe_read != NULL);
297 LQUOTA_DEBUG(lqe, "read");
299 rc = site->lqs_ops->lqe_read(env, lqe, site->lqs_parent);
301 /* mark the entry as up-to-date */
302 lqe->lqe_uptodate = true;
308 * Find or create a quota entry.
310 * \param env - the environment passed by the caller
311 * \param site - lquota site which stores quota entries in a hash table
312 * \param qid - is the quota ID to be found/created
314 * \retval 0 - success
315 * \retval -ve - failure
317 struct lquota_entry *lqe_locate(const struct lu_env *env,
318 struct lquota_site *site, union lquota_id *qid)
320 struct lquota_entry *lqe, *new = NULL;
324 lqe = cfs_hash_lookup(site->lqs_hash, (void *)&qid->qid_uid);
326 LASSERT(lqe->lqe_uptodate);
330 OBD_SLAB_ALLOC_PTR_GFP(new, lqe_kmem, CFS_ALLOC_IO);
332 CERROR("Fail to allocate lqe for id:"LPU64", "
333 "hash:%s\n", qid->qid_uid, site->lqs_hash->hs_name);
334 RETURN(ERR_PTR(-ENOMEM));
337 atomic_set(&new->lqe_ref, 1); /* hold 1 for caller */
339 new->lqe_site = site;
340 CFS_INIT_LIST_HEAD(&new->lqe_link);
342 /* quota settings need to be updated from disk, that's why
343 * lqe->lqe_uptodate isn't set yet */
344 new->lqe_uptodate = false;
346 /* perform qmt/qsd specific initialization */
349 /* read quota settings from disk and mark lqe as up-to-date */
350 rc = lqe_read(env, new);
352 GOTO(out, lqe = ERR_PTR(rc));
354 /* add new entry to hash */
355 lqe = cfs_hash_findadd_unique(site->lqs_hash, &new->lqe_id.qid_uid,