Whamcloud - gitweb
LU-17592 build: kernel 6.8 removed strlcpy()
[fs/lustre-release.git] / lustre / lod / lod_pool.c
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, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  */
31 /*
32  * lustre/lod/lod_pool.c
33  *
34  * OST pool methods
35  *
36  * This file provides code related to the Logical Object Device (LOD)
37  * handling of OST Pools on the MDT.  Pools are named lists of targets
38  * that allow userspace to group targets that share a particlar property
39  * together so that users or kernel helpers can make decisions about file
40  * allocation based on these properties.  For example, pools could be
41  * defined based on fault domains (e.g. separate racks of server nodes) so
42  * that RAID-1 mirroring could select targets from independent fault
43  * domains, or pools could define target performance characteristics so
44  * that applicatins could select IOP-optimized storage or stream-optimized
45  * storage for a particular output file.
46  *
47  * This file handles creation, lookup, and removal of pools themselves, as
48  * well as adding and removing targets to pools.  It also handles lprocfs
49  * display of configured pool.  The pools are accessed by name in the pool
50  * hash, and are refcounted to ensure proper pool structure lifetimes.
51  *
52  * Author: Jacques-Charles LAFOUCRIERE <jc.lafoucriere@cea.fr>
53  * Author: Alex Lyashkov <Alexey.Lyashkov@Sun.COM>
54  * Author: Nathaniel Rutman <Nathan.Rutman@Sun.COM>
55  */
56
57 #define DEBUG_SUBSYSTEM S_LOV
58
59 #include <libcfs/libcfs.h>
60 #include <libcfs/linux/linux-hash.h>
61 #include <libcfs/linux/linux-fs.h>
62 #include <obd.h>
63 #include "lod_internal.h"
64
65 #define pool_tgt(_p, _i) OST_TGT(lu2lod_dev((_p)->pool_lobd->obd_lu_dev), \
66                                  (_p)->pool_obds.op_array[_i])
67
68 /**
69  * Get a reference on the specified pool.
70  *
71  * To ensure the pool descriptor is not freed before the caller is finished
72  * with it.  Any process that is accessing \a pool directly needs to hold
73  * reference on it, including /proc since a userspace thread may be holding
74  * the /proc file open and busy in the kernel.
75  *
76  * \param[in] pool      pool descriptor on which to gain reference
77  */
78 static void pool_getref(struct lod_pool_desc *pool)
79 {
80         CDEBUG(D_INFO, "pool %p\n", pool);
81         kref_get(&pool->pool_refcount);
82 }
83
84 static void lod_pool_putref_free(struct kref *kref)
85 {
86         struct lod_pool_desc *pool = container_of(kref, struct lod_pool_desc,
87                                                   pool_refcount);
88
89         LASSERT(list_empty(&pool->pool_list));
90         LASSERT(pool->pool_proc_entry == NULL);
91         lu_tgt_pool_free(&(pool->pool_rr.lqr_pool));
92         lu_tgt_pool_free(&(pool->pool_obds));
93         kfree_rcu(pool, pool_rcu);
94         EXIT;
95 }
96
97 /**
98  * Drop a reference on the specified pool and free its memory if needed.
99  *
100  * One reference is held by the LOD OBD device while it is configured, from
101  * the time the configuration log defines the pool until the time when it is
102  * dropped when the LOD OBD is cleaned up or the pool is deleted.  This means
103  * that the pool will not be freed while the LOD device is configured, unless
104  * it is explicitly destroyed by the sysadmin.  The pool structure is freed
105  * after the last reference on the structure is released.
106  *
107  * \param[in] pool      lod pool descriptor to drop reference on and possibly
108  *                      free
109  */
110 void lod_pool_putref(struct lod_pool_desc *pool)
111 {
112         CDEBUG(D_INFO, "pool %p\n", pool);
113         kref_put(&pool->pool_refcount, lod_pool_putref_free);
114 }
115
116 static u32 pool_hashfh(const void *data, u32 len, u32 seed)
117 {
118         const char *pool_name = data;
119
120         return hashlen_hash(cfs_hashlen_string((void *)(unsigned long)seed,
121                                                pool_name));
122 }
123
124 static int pool_cmpfn(struct rhashtable_compare_arg *arg, const void *obj)
125 {
126         const struct lod_pool_desc *pool = obj;
127         const char *pool_name = arg->key;
128
129         return strcmp(pool_name, pool->pool_name);
130 }
131
132 static const struct rhashtable_params pools_hash_params = {
133         .key_len        = 1, /* actually variable */
134         .key_offset     = offsetof(struct lod_pool_desc, pool_name),
135         .head_offset    = offsetof(struct lod_pool_desc, pool_hash),
136         .hashfn         = pool_hashfh,
137         .obj_cmpfn      = pool_cmpfn,
138         .automatic_shrinking = true,
139 };
140
141 /*
142  * Methods for /proc seq_file iteration of the defined pools.
143  */
144
145 #define POOL_IT_MAGIC 0xB001CEA0
146 struct lod_pool_iterator {
147         unsigned int      lpi_magic;    /* POOL_IT_MAGIC */
148         unsigned int      lpi_idx;      /* from 0 to pool_tgt_size - 1 */
149         struct lod_pool_desc *lpi_pool;
150 };
151
152 /**
153  * Return the next configured target within one pool for seq_file iteration.
154  *
155  * Iterator is used to go through the target entries of a single pool
156  * (i.e. the list of OSTs configured for a named pool).
157  * lpi_idx is the current target index in the pool's op_array[].
158  *
159  * The return type is a void * because this function is one of the
160  * struct seq_operations methods and must match the function template.
161  *
162  * \param[in] seq       /proc sequence file iteration tracking structure
163  * \param[in] v         unused
164  * \param[in] pos       position within iteration; 0 to number of targets - 1
165  *
166  * \retval      struct pool_iterator of the next pool descriptor
167  */
168 static void *pool_proc_next(struct seq_file *seq, void *v, loff_t *pos)
169 {
170         struct lod_pool_iterator *iter = seq->private;
171         int prev_idx;
172
173         LASSERTF(iter->lpi_magic == POOL_IT_MAGIC, "%08X\n", iter->lpi_magic);
174
175         (*pos)++;
176         /* test if end of file */
177         if (*pos > pool_tgt_count(iter->lpi_pool))
178                 return NULL;
179
180         CFS_FAIL_TIMEOUT(OBD_FAIL_OST_LIST_ASSERT, cfs_fail_val);
181
182         /* iterate to find a non empty entry */
183         prev_idx = iter->lpi_idx;
184         iter->lpi_idx++;
185         if (iter->lpi_idx >= pool_tgt_count(iter->lpi_pool)) {
186                 iter->lpi_idx = prev_idx; /* we stay on the last entry */
187                 return NULL;
188         }
189
190         /* return != NULL to continue */
191         return iter;
192 }
193
194 /**
195  * Start seq_file iteration via /proc for a single pool.
196  *
197  * The \a pos parameter may be non-zero, indicating that the iteration
198  * is starting at some offset in the target list.  Use the seq_file
199  * private field to memorize the iterator so we can free it at stop().
200  * Need to restore the private pointer to the pool before freeing it.
201  *
202  * \param[in] seq       new sequence file structure to initialize
203  * \param[in] pos       initial target number at which to start iteration
204  *
205  * \retval              initialized pool iterator private structure
206  * \retval              NULL if \a pos exceeds the number of targets in \a pool
207  * \retval              negative error number on failure
208  */
209 static void *pool_proc_start(struct seq_file *seq, loff_t *pos)
210 {
211         struct lod_pool_desc *pool = seq->private;
212         struct lod_pool_iterator *iter;
213
214         pool_getref(pool);
215         if ((pool_tgt_count(pool) == 0) ||
216             (*pos >= pool_tgt_count(pool))) {
217                 /* iter is not created, so stop() has no way to
218                  * find pool to dec ref */
219                 lod_pool_putref(pool);
220                 return NULL;
221         }
222
223         OBD_ALLOC_PTR(iter);
224         if (iter == NULL)
225                 return ERR_PTR(-ENOMEM);
226         iter->lpi_magic = POOL_IT_MAGIC;
227         iter->lpi_pool = pool;
228         iter->lpi_idx = 0;
229
230         seq->private = iter;
231         down_read(&pool_tgt_rw_sem(pool));
232         if (*pos > 0) {
233                 loff_t i;
234                 void *ptr;
235
236                 i = 0;
237                 do {
238                         ptr = pool_proc_next(seq, &iter, &i);
239                 } while ((i < *pos) && (ptr != NULL));
240
241                 return ptr;
242         }
243
244         return iter;
245 }
246
247 /**
248  * Finish seq_file iteration for a single pool.
249  *
250  * Once iteration has been completed, the pool_iterator struct must be
251  * freed, and the seq_file private pointer restored to the pool, as it
252  * was initially when pool_proc_start() was called.
253  *
254  * In some cases the stop() method may be called 2 times, without calling
255  * the start() method (see seq_read() from fs/seq_file.c). We have to free
256  * the private iterator struct only if seq->private points to the iterator.
257  *
258  * \param[in] seq       sequence file structure to clean up
259  * \param[in] v         (unused)
260  */
261 static void pool_proc_stop(struct seq_file *seq, void *v)
262 {
263         struct lod_pool_iterator *iter = seq->private;
264
265         if (iter != NULL && iter->lpi_magic == POOL_IT_MAGIC) {
266                 up_read(&pool_tgt_rw_sem(iter->lpi_pool));
267                 seq->private = iter->lpi_pool;
268                 lod_pool_putref(iter->lpi_pool);
269                 OBD_FREE_PTR(iter);
270         }
271 }
272
273 /**
274  * Print out one target entry from the pool for seq_file iteration.
275  *
276  * The currently referenced pool target is given by op_array[lpi_idx].
277  *
278  * \param[in] seq       new sequence file structure to initialize
279  * \param[in] v         (unused)
280  */
281 static int pool_proc_show(struct seq_file *seq, void *v)
282 {
283         struct lod_pool_iterator *iter = v;
284         struct lod_tgt_desc  *tgt;
285
286         LASSERTF(iter->lpi_magic == POOL_IT_MAGIC, "%08X\n", iter->lpi_magic);
287         LASSERT(iter->lpi_pool != NULL);
288         LASSERT(iter->lpi_idx <= pool_tgt_count(iter->lpi_pool));
289
290         tgt = pool_tgt(iter->lpi_pool, iter->lpi_idx);
291         if (tgt != NULL)
292                 seq_printf(seq, "%s\n", obd_uuid2str(&(tgt->ltd_uuid)));
293
294         return 0;
295 }
296
297 static const struct seq_operations pool_proc_ops = {
298         .start  = pool_proc_start,
299         .next   = pool_proc_next,
300         .stop   = pool_proc_stop,
301         .show   = pool_proc_show,
302 };
303
304 /**
305  * Open a new /proc file for seq_file iteration of targets in one pool.
306  *
307  * Initialize the seq_file private pointer to reference the pool.
308  *
309  * \param inode inode to store iteration state for /proc
310  * \param file  file descriptor to store iteration methods
311  *
312  * \retval      0 for success
313  * \retval      negative error number on failure
314  */
315 static int pool_proc_open(struct inode *inode, struct file *file)
316 {
317         int rc;
318
319         rc = seq_open(file, &pool_proc_ops);
320         if (!rc) {
321                 struct seq_file *seq = file->private_data;
322                 seq->private = pde_data(inode);
323         }
324         return rc;
325 }
326
327 const static struct proc_ops pool_proc_operations = {
328         .proc_open      = pool_proc_open,
329         .proc_read      = seq_read,
330         .proc_lseek     = seq_lseek,
331         .proc_release   = seq_release,
332 };
333
334 /**
335  * Dump the pool target list into the Lustre debug log.
336  *
337  * This is a debugging function to allow dumping the list of targets
338  * in \a pool to the Lustre kernel debug log at the given \a level.
339  *
340  * This is not currently called by any existing code, but can be called
341  * from within gdb/crash to display the contents of the pool, or from
342  * code under development.
343  *
344  * \param[in] level     Lustre debug level (D_INFO, D_WARN, D_ERROR, etc)
345  * \param[in] pool      pool descriptor to be dumped
346  */
347 void lod_dump_pool(int level, struct lod_pool_desc *pool)
348 {
349         unsigned int i;
350
351         pool_getref(pool);
352
353         CDEBUG(level, "pool "LOV_POOLNAMEF" has %d members\n",
354                pool->pool_name, pool->pool_obds.op_count);
355         down_read(&pool_tgt_rw_sem(pool));
356
357         for (i = 0; i < pool_tgt_count(pool) ; i++) {
358                 if (!pool_tgt(pool, i) || !(pool_tgt(pool, i))->ltd_exp)
359                         continue;
360                 CDEBUG(level, "pool "LOV_POOLNAMEF"[%d] = %s\n",
361                        pool->pool_name, i,
362                        obd_uuid2str(&((pool_tgt(pool, i))->ltd_uuid)));
363         }
364
365         up_read(&pool_tgt_rw_sem(pool));
366         lod_pool_putref(pool);
367 }
368
369 static void pools_hash_exit(void *vpool, void *data)
370 {
371         struct lod_pool_desc *pool = vpool;
372
373         lod_pool_putref(pool);
374 }
375
376 int lod_pool_hash_init(struct rhashtable *tbl)
377 {
378         return rhashtable_init(tbl, &pools_hash_params);
379 }
380
381 void lod_pool_hash_destroy(struct rhashtable *tbl)
382 {
383         rhashtable_free_and_destroy(tbl, pools_hash_exit, NULL);
384 }
385
386 bool lod_pool_exists(struct lod_device *lod, char *poolname)
387 {
388         struct lod_pool_desc *pool;
389
390         rcu_read_lock();
391         pool = rhashtable_lookup(&lod->lod_pools_hash_body,
392                                 poolname,
393                                 pools_hash_params);
394         rcu_read_unlock();
395         return pool != NULL;
396 }
397
398 struct lod_pool_desc *lod_pool_find(struct lod_device *lod, char *poolname)
399 {
400         struct lod_pool_desc *pool;
401
402         rcu_read_lock();
403         pool = rhashtable_lookup(&lod->lod_pools_hash_body,
404                                 poolname,
405                                 pools_hash_params);
406         if (pool && !kref_get_unless_zero(&pool->pool_refcount))
407                 pool = NULL;
408         rcu_read_unlock();
409         return pool;
410 }
411
412 static int lod_ost_pool_weights_seq_show(struct seq_file *m, void *data)
413 {
414         struct lod_pool_desc *pool = m->private;
415         struct lod_device *lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
416
417         return lod_tgt_weights_seq_show(m, lod, &pool->pool_obds, false);
418 }
419
420 static ssize_t
421 lod_ost_pool_weights_seq_write(struct file *file, const char __user *buf,
422                                size_t count, loff_t *off)
423 {
424         struct seq_file *m = file->private_data;
425         struct lod_pool_desc *pool = m->private;
426         struct lod_device *lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
427
428         return lod_tgt_weights_seq_write(m, buf, count, lod, &pool->pool_obds,
429                                          false);
430 }
431 LDEBUGFS_SEQ_FOPS(lod_ost_pool_weights);
432
433 static struct ldebugfs_vars ldebugfs_lod_pool_vars[] = {
434         { .name =       "qos_ost_weights",
435           .fops =       &lod_ost_pool_weights_fops,
436           .proc_mode =  0444 },
437         { 0 }
438 };
439
440 /**
441  * Allocate a new pool for the specified device.
442  *
443  * Allocate a new pool_desc structure for the specified \a new_pool
444  * device to create a pool with the given \a poolname.  The new pool
445  * structure is created with a single reference, and is freed when the
446  * reference count drops to zero.
447  *
448  * \param[in] obd       Lustre OBD device on which to add a pool iterator
449  * \param[in] poolname  the name of the pool to be created
450  *
451  * \retval              0 in case of success
452  * \retval              negative error code in case of error
453  */
454 int lod_pool_new(struct obd_device *obd, char *poolname)
455 {
456         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
457         struct lod_pool_desc  *new_pool;
458         int rc;
459         ENTRY;
460
461         if (strlen(poolname) > LOV_MAXPOOLNAME)
462                 RETURN(-ENAMETOOLONG);
463
464         /* OBD_ALLOC_* doesn't work with direct kfree_rcu use */
465         new_pool = kmalloc(sizeof(*new_pool), __GFP_ZERO);
466         if (new_pool == NULL)
467                 RETURN(-ENOMEM);
468
469         strscpy(new_pool->pool_name, poolname, sizeof(new_pool->pool_name));
470         new_pool->pool_spill_target[0] = '\0';
471         atomic_set(&new_pool->pool_spill_hit, 0);
472         new_pool->pool_lobd = obd;
473         kref_init(&new_pool->pool_refcount);
474         rc = lu_tgt_pool_init(&new_pool->pool_obds, 0);
475         if (rc)
476                 GOTO(out_free_pool, rc);
477
478         lu_qos_rr_init(&new_pool->pool_rr);
479
480         rc = lu_tgt_pool_init(&new_pool->pool_rr.lqr_pool, 0);
481         if (rc)
482                 GOTO(out_free_pool_obds, rc);
483
484 #ifdef CONFIG_PROC_FS
485         pool_getref(new_pool);
486         new_pool->pool_proc_entry = lprocfs_add_simple(lod->lod_pool_proc_entry,
487                                                        poolname, new_pool,
488                                                        &pool_proc_operations);
489         if (IS_ERR(new_pool->pool_proc_entry)) {
490                 CDEBUG(D_CONFIG, "%s: cannot add proc entry "LOV_POOLNAMEF"\n",
491                        obd->obd_name, poolname);
492                 new_pool->pool_proc_entry = NULL;
493                 lod_pool_putref(new_pool);
494         }
495
496         pool_getref(new_pool);
497         new_pool->pool_spill_proc_entry =
498                 lprocfs_register(poolname, lod->lod_spill_proc_entry,
499                         lprocfs_lod_spill_vars, new_pool);
500         if (IS_ERR(new_pool->pool_spill_proc_entry)) {
501                 rc = PTR_ERR(new_pool->pool_spill_proc_entry);
502                 new_pool->pool_proc_entry = NULL;
503                 lod_pool_putref(new_pool);
504         }
505
506         CDEBUG(D_INFO, "pool %p - proc %p\n", new_pool,
507                new_pool->pool_proc_entry);
508 #endif
509
510         spin_lock(&obd->obd_dev_lock);
511         list_add_tail(&new_pool->pool_list, &lod->lod_pool_list);
512         lod->lod_pool_count++;
513         spin_unlock(&obd->obd_dev_lock);
514
515         /* Add to hash table only when it is fully ready. */
516         rc = rhashtable_lookup_insert_fast(&lod->lod_pools_hash_body,
517                                            &new_pool->pool_hash,
518                                            pools_hash_params);
519         if (rc) {
520                 if (rc != -EEXIST)
521                         /*
522                          * Hide -E2BIG and -EBUSY which
523                          * are not helpful.
524                          */
525                         rc = -ENOMEM;
526                 GOTO(out_err, rc);
527         }
528
529         new_pool->pool_debugfs = debugfs_create_dir(poolname,
530                                                     lod->lod_pool_debugfs);
531         ldebugfs_add_vars(new_pool->pool_debugfs, ldebugfs_lod_pool_vars,
532                           new_pool);
533
534         CDEBUG(D_CONFIG, LOV_POOLNAMEF" is pool #%d\n",
535                         poolname, lod->lod_pool_count);
536
537         RETURN(0);
538
539 out_err:
540         spin_lock(&obd->obd_dev_lock);
541         list_del_init(&new_pool->pool_list);
542         lod->lod_pool_count--;
543         spin_unlock(&obd->obd_dev_lock);
544
545         lprocfs_remove(&new_pool->pool_spill_proc_entry);
546         lprocfs_remove(&new_pool->pool_proc_entry);
547
548         lu_tgt_pool_free(&new_pool->pool_rr.lqr_pool);
549 out_free_pool_obds:
550         lu_tgt_pool_free(&new_pool->pool_obds);
551 out_free_pool:
552         OBD_FREE_PTR(new_pool);
553         return rc;
554 }
555
556 /**
557  * Remove the named pool from the OBD device.
558  *
559  * \param[in] obd       OBD device on which pool was previously created
560  * \param[in] poolname  name of pool to remove from \a obd
561  *
562  * \retval              0 on successfully removing the pool
563  * \retval              negative error numbers for failures
564  */
565 int lod_pool_del(struct obd_device *obd, char *poolname)
566 {
567         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
568         struct lod_pool_desc  *pool;
569         ENTRY;
570
571         /* lookup and kill hash reference */
572         rcu_read_lock();
573         pool = rhashtable_lookup(&lod->lod_pools_hash_body, poolname,
574                                  pools_hash_params);
575         if (pool && rhashtable_remove_fast(&lod->lod_pools_hash_body,
576                                            &pool->pool_hash,
577                                            pools_hash_params) != 0)
578                 pool = NULL;
579         rcu_read_unlock();
580         if (!pool)
581                 RETURN(-ENOENT);
582
583         debugfs_remove_recursive(pool->pool_debugfs);
584
585         if (pool->pool_proc_entry != NULL) {
586                 CDEBUG(D_INFO, "proc entry %p\n", pool->pool_proc_entry);
587                 lprocfs_remove(&pool->pool_proc_entry);
588                 lod_pool_putref(pool);
589         }
590         if (pool->pool_spill_proc_entry != NULL) {
591                 CDEBUG(D_INFO, "proc entry %p\n", pool->pool_spill_proc_entry);
592                 lprocfs_remove(&pool->pool_spill_proc_entry);
593                 lod_pool_putref(pool);
594         }
595
596         spin_lock(&obd->obd_dev_lock);
597         list_del_init(&pool->pool_list);
598         lod->lod_pool_count--;
599         spin_unlock(&obd->obd_dev_lock);
600
601         /* release last reference */
602         lod_pool_putref(pool);
603
604         RETURN(0);
605 }
606
607 /**
608  * Add a single target device to the named pool.
609  *
610  * Add the target specified by \a ostname to the specified \a poolname.
611  *
612  * \param[in] obd       OBD device on which to add the pool
613  * \param[in] poolname  name of the pool to which to add the target \a ostname
614  * \param[in] ostname   name of the target device to be added
615  *
616  * \retval              0 if \a ostname was (previously) added to the named pool
617  * \retval              negative error number on failure
618  */
619 int lod_pool_add(struct obd_device *obd, char *poolname, char *ostname)
620 {
621         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
622         struct obd_uuid ost_uuid;
623         struct lod_pool_desc *pool;
624         struct lu_tgt_desc *tgt;
625         int rc = -EINVAL;
626         ENTRY;
627
628         pool = lod_pool_find(lod, poolname);
629         if (!pool)
630                 RETURN(-ENOENT);
631
632         obd_str2uuid(&ost_uuid, ostname);
633
634         /* search ost in lod array */
635         lod_getref(&lod->lod_ost_descs);
636         lod_foreach_ost(lod, tgt) {
637                 if (obd_uuid_equals(&ost_uuid, &tgt->ltd_uuid)) {
638                         rc = 0;
639                         break;
640                 }
641         }
642
643         if (rc)
644                 GOTO(out, rc);
645
646         rc = lu_tgt_pool_add(&pool->pool_obds, tgt->ltd_index,
647                              lod->lod_ost_count);
648         if (rc)
649                 GOTO(out, rc);
650
651         set_bit(LQ_DIRTY, &pool->pool_rr.lqr_flags);
652
653         CDEBUG(D_CONFIG, "Added %s to "LOV_POOLNAMEF" as member %d\n",
654                         ostname, poolname,  pool_tgt_count(pool));
655
656         EXIT;
657 out:
658         lod_putref(lod, &lod->lod_ost_descs);
659         lod_pool_putref(pool);
660         return rc;
661 }
662
663 /**
664  * Remove the named target from the specified pool.
665  *
666  * Remove one target named \a ostname from \a poolname.  The \a ostname
667  * is searched for in the lod_device lod_ost_bitmap array, to ensure the
668  * specified name actually exists in the pool.
669  *
670  * \param[in] obd       OBD device from which to remove \a poolname
671  * \param[in] poolname  name of the pool to be changed
672  * \param[in] ostname   name of the target to remove from \a poolname
673  *
674  * \retval              0 on successfully removing \a ostname from the pool
675  * \retval              negative number on error (e.g. \a ostname not in pool)
676  */
677 int lod_pool_remove(struct obd_device *obd, char *poolname, char *ostname)
678 {
679         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
680         struct lu_tgt_desc *ost;
681         struct obd_uuid ost_uuid;
682         struct lod_pool_desc *pool;
683         int rc = -EINVAL;
684         ENTRY;
685
686         /* lookup and kill hash reference */
687         pool = lod_pool_find(lod, poolname);
688         if (!pool)
689                 RETURN(-ENOENT);
690
691         obd_str2uuid(&ost_uuid, ostname);
692
693         lod_getref(&lod->lod_ost_descs);
694         lod_foreach_ost(lod, ost) {
695                 if (obd_uuid_equals(&ost_uuid, &ost->ltd_uuid)) {
696                         rc = 0;
697                         break;
698                 }
699         }
700
701         /* test if ost found in lod array */
702         if (rc)
703                 GOTO(out, rc);
704
705         lu_tgt_pool_remove(&pool->pool_obds, ost->ltd_index);
706         set_bit(LQ_DIRTY, &pool->pool_rr.lqr_flags);
707
708         CDEBUG(D_CONFIG, "%s removed from "LOV_POOLNAMEF"\n", ostname,
709                poolname);
710
711         EXIT;
712 out:
713         lod_putref(lod, &lod->lod_ost_descs);
714         lod_pool_putref(pool);
715         return rc;
716 }
717
718 /**
719  * Check if the specified target exists in the pool.
720  *
721  * The caller may not have a reference on \a pool if it got the pool without
722  * calling lod_find_pool() (e.g. directly from the lod pool list)
723  *
724  * \param[in] idx       Target index to check
725  * \param[in] pool      Pool in which to check if target is added.
726  *
727  * \retval              0 successfully found index in \a pool
728  * \retval              negative error if device not found in \a pool
729  */
730 int lod_check_index_in_pool(__u32 idx, struct lod_pool_desc *pool)
731 {
732         int rc;
733
734         pool_getref(pool);
735         rc = lu_tgt_check_index(idx, &pool->pool_obds);
736         lod_pool_putref(pool);
737         return rc;
738 }
739
740 /**
741  * Find the pool descriptor for the specified pool and return it with a
742  * reference to the caller if found.
743  *
744  * \param[in] lod       LOD on which the pools are configured
745  * \param[in] poolname  NUL-terminated name of the pool
746  *
747  * \retval      pointer to pool descriptor on success
748  * \retval      NULL if \a poolname could not be found or poolname is empty
749  */
750 struct lod_pool_desc *lod_find_pool(struct lod_device *lod, char *poolname)
751 {
752         struct lod_pool_desc *pool;
753
754         if (poolname[0] == '\0' || lov_pool_is_reserved(poolname))
755                 return NULL;
756
757         pool = lod_pool_find(lod, poolname);
758         if (!pool)
759                 CDEBUG(D_CONFIG,
760                        "%s: request for an unknown pool (" LOV_POOLNAMEF ")\n",
761                        lod->lod_child_exp->exp_obd->obd_name, poolname);
762         if (pool != NULL && pool_tgt_count(pool) == 0) {
763                 CDEBUG(D_CONFIG, "%s: request for an empty pool ("
764                        LOV_POOLNAMEF")\n",
765                        lod->lod_child_exp->exp_obd->obd_name, poolname);
766                 /* pool is ignored, so we remove ref on it */
767                 lod_pool_putref(pool);
768                 pool = NULL;
769         }
770
771         return pool;
772 }
773
774 void lod_spill_target_refresh(const struct lu_env *env, struct lod_device *lod,
775                               struct lod_pool_desc *pool)
776 {
777         __u64 avail_bytes = 0, total_bytes = 0;
778         struct lu_tgt_pool *osts;
779         int i;
780
781         if (ktime_get_seconds() < pool->pool_spill_expire)
782                 return;
783
784         if (pool->pool_spill_threshold_pct == 0)
785                 return;
786
787         lod_qos_statfs_update(env, lod, &lod->lod_ost_descs);
788
789         down_write(&pool_tgt_rw_sem(pool));
790         if (ktime_get_seconds() < pool->pool_spill_expire)
791                 goto out_sem;
792         pool->pool_spill_expire = ktime_get_seconds() +
793                 lod->lod_ost_descs.ltd_lov_desc.ld_qos_maxage;
794
795         osts = &(pool->pool_obds);
796         for (i = 0; i < osts->op_count; i++) {
797                 int idx = osts->op_array[i];
798                 struct lod_tgt_desc *tgt;
799                 struct obd_statfs *sfs;
800
801                 if (!test_bit(idx, lod->lod_ost_bitmap))
802                         continue;
803                 tgt = OST_TGT(lod, idx);
804                 if (!tgt->ltd_active)
805                         continue;
806                 sfs = &tgt->ltd_statfs;
807
808                 avail_bytes += sfs->os_bavail * sfs->os_bsize;
809                 total_bytes += sfs->os_blocks * sfs->os_bsize;
810         }
811         if (total_bytes - avail_bytes >=
812             total_bytes * pool->pool_spill_threshold_pct / 100)
813                 pool->pool_spill_is_active = true;
814         else
815                 pool->pool_spill_is_active = false;
816
817 out_sem:
818         up_write(&pool_tgt_rw_sem(pool));
819 }
820
821 /*
822  * XXX: consider a better schema to detect loops
823  */
824 void lod_check_and_spill_pool(const struct lu_env *env, struct lod_device *lod,
825                               char **poolname)
826 {
827         struct lod_pool_desc *pool;
828
829         if (!poolname || !*poolname || (*poolname)[0] == '\0')
830                 return;
831 repeat:
832         pool = lod_pool_find(lod, *poolname);
833         if (!pool)
834                 return;
835
836         lod_spill_target_refresh(env, lod, pool);
837         if (pool->pool_spill_is_active) {
838                 lod_set_pool(poolname, pool->pool_spill_target);
839                 atomic_inc(&pool->pool_spill_hit);
840                 lod_pool_putref(pool);
841                 goto repeat;
842         }
843
844         lod_pool_putref(pool);
845 }