GNU Linux-libre 4.14.313-gnu1
[releases.git] / drivers / staging / lustre / lustre / lov / lov_request.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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2015, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  */
32
33 #define DEBUG_SUBSYSTEM S_LOV
34
35 #include <linux/libcfs/libcfs.h>
36
37 #include <obd_class.h>
38 #include <uapi/linux/lustre/lustre_idl.h>
39 #include "lov_internal.h"
40
41 static void lov_init_set(struct lov_request_set *set)
42 {
43         set->set_count = 0;
44         atomic_set(&set->set_completes, 0);
45         atomic_set(&set->set_success, 0);
46         INIT_LIST_HEAD(&set->set_list);
47 }
48
49 static void lov_finish_set(struct lov_request_set *set)
50 {
51         struct list_head *pos, *n;
52
53         LASSERT(set);
54         list_for_each_safe(pos, n, &set->set_list) {
55                 struct lov_request *req = list_entry(pos,
56                                                          struct lov_request,
57                                                          rq_link);
58                 list_del_init(&req->rq_link);
59
60                 kfree(req->rq_oi.oi_osfs);
61                 kfree(req);
62         }
63         kfree(set);
64 }
65
66 static void lov_update_set(struct lov_request_set *set,
67                            struct lov_request *req, int rc)
68 {
69         atomic_inc(&set->set_completes);
70         if (rc == 0)
71                 atomic_inc(&set->set_success);
72 }
73
74 static void lov_set_add_req(struct lov_request *req,
75                             struct lov_request_set *set)
76 {
77         list_add_tail(&req->rq_link, &set->set_list);
78         set->set_count++;
79         req->rq_rqset = set;
80 }
81
82 static int lov_check_set(struct lov_obd *lov, int idx)
83 {
84         int rc;
85         struct lov_tgt_desc *tgt;
86
87         mutex_lock(&lov->lov_lock);
88         tgt = lov->lov_tgts[idx];
89         rc = !tgt || tgt->ltd_active ||
90                 (tgt->ltd_exp &&
91                  class_exp2cliimp(tgt->ltd_exp)->imp_connect_tried);
92         mutex_unlock(&lov->lov_lock);
93
94         return rc;
95 }
96
97 /* Check if the OSC connection exists and is active.
98  * If the OSC has not yet had a chance to connect to the OST the first time,
99  * wait once for it to connect instead of returning an error.
100  */
101 static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
102 {
103         wait_queue_head_t waitq;
104         struct l_wait_info lwi;
105         struct lov_tgt_desc *tgt;
106         int rc = 0;
107
108         mutex_lock(&lov->lov_lock);
109
110         tgt = lov->lov_tgts[ost_idx];
111
112         if (unlikely(!tgt)) {
113                 rc = 0;
114                 goto out;
115         }
116
117         if (likely(tgt->ltd_active)) {
118                 rc = 1;
119                 goto out;
120         }
121
122         if (tgt->ltd_exp && class_exp2cliimp(tgt->ltd_exp)->imp_connect_tried) {
123                 rc = 0;
124                 goto out;
125         }
126
127         mutex_unlock(&lov->lov_lock);
128
129         init_waitqueue_head(&waitq);
130         lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(obd_timeout),
131                                    cfs_time_seconds(1), NULL, NULL);
132
133         rc = l_wait_event(waitq, lov_check_set(lov, ost_idx), &lwi);
134         if (tgt->ltd_active)
135                 return 1;
136
137         return 0;
138
139 out:
140         mutex_unlock(&lov->lov_lock);
141         return rc;
142 }
143
144 #define LOV_U64_MAX ((__u64)~0ULL)
145 #define LOV_SUM_MAX(tot, add)                                      \
146         do {                                                        \
147                 if ((tot) + (add) < (tot))                            \
148                         (tot) = LOV_U64_MAX;                        \
149                 else                                                \
150                         (tot) += (add);                          \
151         } while (0)
152
153 static int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs,
154                            int success)
155 {
156         if (success) {
157                 __u32 expected_stripes = lov_get_stripecnt(&obd->u.lov,
158                                                            LOV_MAGIC, 0);
159                 if (osfs->os_files != LOV_U64_MAX)
160                         lov_do_div64(osfs->os_files, expected_stripes);
161                 if (osfs->os_ffree != LOV_U64_MAX)
162                         lov_do_div64(osfs->os_ffree, expected_stripes);
163
164                 spin_lock(&obd->obd_osfs_lock);
165                 memcpy(&obd->obd_osfs, osfs, sizeof(*osfs));
166                 obd->obd_osfs_age = cfs_time_current_64();
167                 spin_unlock(&obd->obd_osfs_lock);
168                 return 0;
169         }
170
171         return -EIO;
172 }
173
174 int lov_fini_statfs_set(struct lov_request_set *set)
175 {
176         int rc = 0;
177
178         if (!set)
179                 return 0;
180
181         if (atomic_read(&set->set_completes)) {
182                 rc = lov_fini_statfs(set->set_obd, set->set_oi->oi_osfs,
183                                      atomic_read(&set->set_success));
184         }
185
186         lov_finish_set(set);
187
188         return rc;
189 }
190
191 static void lov_update_statfs(struct obd_statfs *osfs,
192                               struct obd_statfs *lov_sfs,
193                               int success)
194 {
195         int shift = 0, quit = 0;
196         __u64 tmp;
197
198         if (success == 0) {
199                 memcpy(osfs, lov_sfs, sizeof(*lov_sfs));
200         } else {
201                 if (osfs->os_bsize != lov_sfs->os_bsize) {
202                         /* assume all block sizes are always powers of 2 */
203                         /* get the bits difference */
204                         tmp = osfs->os_bsize | lov_sfs->os_bsize;
205                         for (shift = 0; shift <= 64; ++shift) {
206                                 if (tmp & 1) {
207                                         if (quit)
208                                                 break;
209                                         quit = 1;
210                                         shift = 0;
211                                 }
212                                 tmp >>= 1;
213                         }
214                 }
215
216                 if (osfs->os_bsize < lov_sfs->os_bsize) {
217                         osfs->os_bsize = lov_sfs->os_bsize;
218
219                         osfs->os_bfree  >>= shift;
220                         osfs->os_bavail >>= shift;
221                         osfs->os_blocks >>= shift;
222                 } else if (shift != 0) {
223                         lov_sfs->os_bfree  >>= shift;
224                         lov_sfs->os_bavail >>= shift;
225                         lov_sfs->os_blocks >>= shift;
226                 }
227                 osfs->os_bfree += lov_sfs->os_bfree;
228                 osfs->os_bavail += lov_sfs->os_bavail;
229                 osfs->os_blocks += lov_sfs->os_blocks;
230                 /* XXX not sure about this one - depends on policy.
231                  *   - could be minimum if we always stripe on all OBDs
232                  *     (but that would be wrong for any other policy,
233                  *     if one of the OBDs has no more objects left)
234                  *   - could be sum if we stripe whole objects
235                  *   - could be average, just to give a nice number
236                  *
237                  * To give a "reasonable" (if not wholly accurate)
238                  * number, we divide the total number of free objects
239                  * by expected stripe count (watch out for overflow).
240                  */
241                 LOV_SUM_MAX(osfs->os_files, lov_sfs->os_files);
242                 LOV_SUM_MAX(osfs->os_ffree, lov_sfs->os_ffree);
243         }
244 }
245
246 /* The callback for osc_statfs_async that finalizes a request info when a
247  * response is received.
248  */
249 static int cb_statfs_update(void *cookie, int rc)
250 {
251         struct obd_info *oinfo = cookie;
252         struct lov_request *lovreq;
253         struct lov_request_set *set;
254         struct obd_statfs *osfs, *lov_sfs;
255         struct lov_obd *lov;
256         struct lov_tgt_desc *tgt;
257         struct obd_device *lovobd, *tgtobd;
258         int success;
259
260         lovreq = container_of(oinfo, struct lov_request, rq_oi);
261         set = lovreq->rq_rqset;
262         lovobd = set->set_obd;
263         lov = &lovobd->u.lov;
264         osfs = set->set_oi->oi_osfs;
265         lov_sfs = oinfo->oi_osfs;
266         success = atomic_read(&set->set_success);
267         /* XXX: the same is done in lov_update_common_set, however
268          * lovset->set_exp is not initialized.
269          */
270         lov_update_set(set, lovreq, rc);
271         if (rc)
272                 goto out;
273
274         obd_getref(lovobd);
275         tgt = lov->lov_tgts[lovreq->rq_idx];
276         if (!tgt || !tgt->ltd_active)
277                 goto out_update;
278
279         tgtobd = class_exp2obd(tgt->ltd_exp);
280         spin_lock(&tgtobd->obd_osfs_lock);
281         memcpy(&tgtobd->obd_osfs, lov_sfs, sizeof(*lov_sfs));
282         if ((oinfo->oi_flags & OBD_STATFS_FROM_CACHE) == 0)
283                 tgtobd->obd_osfs_age = cfs_time_current_64();
284         spin_unlock(&tgtobd->obd_osfs_lock);
285
286 out_update:
287         lov_update_statfs(osfs, lov_sfs, success);
288         obd_putref(lovobd);
289 out:
290         return 0;
291 }
292
293 int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo,
294                         struct lov_request_set **reqset)
295 {
296         struct lov_request_set *set;
297         struct lov_obd *lov = &obd->u.lov;
298         int rc = 0, i;
299
300         set = kzalloc(sizeof(*set), GFP_NOFS);
301         if (!set)
302                 return -ENOMEM;
303         lov_init_set(set);
304
305         set->set_obd = obd;
306         set->set_oi = oinfo;
307
308         /* We only get block data from the OBD */
309         for (i = 0; i < lov->desc.ld_tgt_count; i++) {
310                 struct lov_request *req;
311
312                 if (!lov->lov_tgts[i] ||
313                     (oinfo->oi_flags & OBD_STATFS_NODELAY &&
314                      !lov->lov_tgts[i]->ltd_active)) {
315                         CDEBUG(D_HA, "lov idx %d inactive\n", i);
316                         continue;
317                 }
318
319                 /* skip targets that have been explicitly disabled by the
320                  * administrator
321                  */
322                 if (!lov->lov_tgts[i]->ltd_exp) {
323                         CDEBUG(D_HA, "lov idx %d administratively disabled\n", i);
324                         continue;
325                 }
326
327                 if (!lov->lov_tgts[i]->ltd_active)
328                         lov_check_and_wait_active(lov, i);
329
330                 req = kzalloc(sizeof(*req), GFP_NOFS);
331                 if (!req) {
332                         rc = -ENOMEM;
333                         goto out_set;
334                 }
335
336                 req->rq_oi.oi_osfs = kzalloc(sizeof(*req->rq_oi.oi_osfs),
337                                              GFP_NOFS);
338                 if (!req->rq_oi.oi_osfs) {
339                         kfree(req);
340                         rc = -ENOMEM;
341                         goto out_set;
342                 }
343
344                 req->rq_idx = i;
345                 req->rq_oi.oi_cb_up = cb_statfs_update;
346                 req->rq_oi.oi_flags = oinfo->oi_flags;
347
348                 lov_set_add_req(req, set);
349         }
350         if (!set->set_count) {
351                 rc = -EIO;
352                 goto out_set;
353         }
354         *reqset = set;
355         return rc;
356 out_set:
357         lov_fini_statfs_set(set);
358         return rc;
359 }