Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 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 |
Oleg Drokin | 6a5b99a | 2016-06-14 23:33:40 -0400 | [diff] [blame] | 18 | * http://www.gnu.org/licenses/gpl-2.0.html |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 19 | * |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 20 | * GPL HEADER END |
| 21 | */ |
| 22 | /* |
| 23 | * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. |
| 24 | * Use is subject to license terms. |
| 25 | * |
Andreas Dilger | 1dc563a | 2015-11-08 18:09:37 -0500 | [diff] [blame] | 26 | * Copyright (c) 2011, 2015, Intel Corporation. |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 27 | */ |
| 28 | /* |
| 29 | * This file is part of Lustre, http://www.lustre.org/ |
| 30 | * Lustre is a trademark of Sun Microsystems, Inc. |
| 31 | * |
| 32 | * lustre/fld/fld_request.c |
| 33 | * |
| 34 | * FLD (Fids Location Database) |
| 35 | * |
| 36 | * Author: Yury Umanets <umka@clusterfs.com> |
| 37 | */ |
| 38 | |
| 39 | #define DEBUG_SUBSYSTEM S_FLD |
| 40 | |
Greg Kroah-Hartman | 9fdaf8c | 2014-07-11 20:51:16 -0700 | [diff] [blame] | 41 | #include "../../include/linux/libcfs/libcfs.h" |
Greg Kroah-Hartman | 0e9ad0e | 2014-07-11 21:51:13 -0700 | [diff] [blame] | 42 | #include <linux/module.h> |
| 43 | #include <asm/div64.h> |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 44 | |
Greg Kroah-Hartman | 0e9ad0e | 2014-07-11 21:51:13 -0700 | [diff] [blame] | 45 | #include "../include/obd.h" |
| 46 | #include "../include/obd_class.h" |
| 47 | #include "../include/lustre_ver.h" |
| 48 | #include "../include/obd_support.h" |
| 49 | #include "../include/lprocfs_status.h" |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 50 | |
Greg Kroah-Hartman | 0e9ad0e | 2014-07-11 21:51:13 -0700 | [diff] [blame] | 51 | #include "../include/lustre_req_layout.h" |
| 52 | #include "../include/lustre_fld.h" |
| 53 | #include "../include/lustre_mdc.h" |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 54 | #include "fld_internal.h" |
| 55 | |
| 56 | /* TODO: these 3 functions are copies of flow-control code from mdc_lib.c |
Oleg Drokin | 52581b8 | 2016-02-24 22:00:26 -0500 | [diff] [blame] | 57 | * It should be common thing. The same about mdc RPC lock |
| 58 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 59 | static int fld_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw) |
| 60 | { |
| 61 | int rc; |
Greg Kroah-Hartman | 29aaf49 | 2013-08-02 18:14:51 +0800 | [diff] [blame] | 62 | |
John L. Hammond | 7d53d8f | 2016-03-30 19:48:36 -0400 | [diff] [blame] | 63 | spin_lock(&cli->cl_loi_list_lock); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 64 | rc = list_empty(&mcw->mcw_entry); |
John L. Hammond | 7d53d8f | 2016-03-30 19:48:36 -0400 | [diff] [blame] | 65 | spin_unlock(&cli->cl_loi_list_lock); |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 66 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 67 | }; |
| 68 | |
| 69 | static void fld_enter_request(struct client_obd *cli) |
| 70 | { |
| 71 | struct mdc_cache_waiter mcw; |
| 72 | struct l_wait_info lwi = { 0 }; |
| 73 | |
John L. Hammond | 7d53d8f | 2016-03-30 19:48:36 -0400 | [diff] [blame] | 74 | spin_lock(&cli->cl_loi_list_lock); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 75 | if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) { |
| 76 | list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters); |
| 77 | init_waitqueue_head(&mcw.mcw_waitq); |
John L. Hammond | 7d53d8f | 2016-03-30 19:48:36 -0400 | [diff] [blame] | 78 | spin_unlock(&cli->cl_loi_list_lock); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 79 | l_wait_event(mcw.mcw_waitq, fld_req_avail(cli, &mcw), &lwi); |
| 80 | } else { |
| 81 | cli->cl_r_in_flight++; |
John L. Hammond | 7d53d8f | 2016-03-30 19:48:36 -0400 | [diff] [blame] | 82 | spin_unlock(&cli->cl_loi_list_lock); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 83 | } |
| 84 | } |
| 85 | |
| 86 | static void fld_exit_request(struct client_obd *cli) |
| 87 | { |
| 88 | struct list_head *l, *tmp; |
| 89 | struct mdc_cache_waiter *mcw; |
| 90 | |
John L. Hammond | 7d53d8f | 2016-03-30 19:48:36 -0400 | [diff] [blame] | 91 | spin_lock(&cli->cl_loi_list_lock); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 92 | cli->cl_r_in_flight--; |
| 93 | list_for_each_safe(l, tmp, &cli->cl_cache_waiters) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 94 | if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) { |
| 95 | /* No free request slots anymore */ |
| 96 | break; |
| 97 | } |
| 98 | |
| 99 | mcw = list_entry(l, struct mdc_cache_waiter, mcw_entry); |
| 100 | list_del_init(&mcw->mcw_entry); |
| 101 | cli->cl_r_in_flight++; |
| 102 | wake_up(&mcw->mcw_waitq); |
| 103 | } |
John L. Hammond | 7d53d8f | 2016-03-30 19:48:36 -0400 | [diff] [blame] | 104 | spin_unlock(&cli->cl_loi_list_lock); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 105 | } |
| 106 | |
Oleg Drokin | 114acca | 2014-08-15 12:55:55 -0400 | [diff] [blame] | 107 | static int fld_rrb_hash(struct lu_client_fld *fld, u64 seq) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 108 | { |
| 109 | LASSERT(fld->lcf_count > 0); |
| 110 | return do_div(seq, fld->lcf_count); |
| 111 | } |
| 112 | |
| 113 | static struct lu_fld_target * |
Oleg Drokin | 114acca | 2014-08-15 12:55:55 -0400 | [diff] [blame] | 114 | fld_rrb_scan(struct lu_client_fld *fld, u64 seq) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 115 | { |
| 116 | struct lu_fld_target *target; |
| 117 | int hash; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 118 | |
| 119 | /* Because almost all of special sequence located in MDT0, |
| 120 | * it should go to index 0 directly, instead of calculating |
| 121 | * hash again, and also if other MDTs is not being connected, |
| 122 | * the fld lookup requests(for seq on MDT0) should not be |
Oleg Drokin | 52581b8 | 2016-02-24 22:00:26 -0500 | [diff] [blame] | 123 | * blocked because of other MDTs |
| 124 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 125 | if (fid_seq_is_norm(seq)) |
| 126 | hash = fld_rrb_hash(fld, seq); |
| 127 | else |
| 128 | hash = 0; |
| 129 | |
wang di | b7fb222 | 2015-02-01 21:52:14 -0500 | [diff] [blame] | 130 | again: |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 131 | list_for_each_entry(target, &fld->lcf_targets, ft_chain) { |
| 132 | if (target->ft_idx == hash) |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 133 | return target; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 134 | } |
| 135 | |
wang di | b7fb222 | 2015-02-01 21:52:14 -0500 | [diff] [blame] | 136 | if (hash != 0) { |
| 137 | /* It is possible the remote target(MDT) are not connected to |
| 138 | * with client yet, so we will refer this to MDT0, which should |
Oleg Drokin | 52581b8 | 2016-02-24 22:00:26 -0500 | [diff] [blame] | 139 | * be connected during mount |
| 140 | */ |
wang di | b7fb222 | 2015-02-01 21:52:14 -0500 | [diff] [blame] | 141 | hash = 0; |
| 142 | goto again; |
| 143 | } |
| 144 | |
Greg Kroah-Hartman | 55f5a82 | 2014-07-12 20:26:07 -0700 | [diff] [blame] | 145 | CERROR("%s: Can't find target by hash %d (seq %#llx). Targets (%d):\n", |
Oleg Drokin | cf67759 | 2016-02-26 01:49:51 -0500 | [diff] [blame] | 146 | fld->lcf_name, hash, seq, fld->lcf_count); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 147 | |
| 148 | list_for_each_entry(target, &fld->lcf_targets, ft_chain) { |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 149 | const char *srv_name = target->ft_srv ? |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 150 | target->ft_srv->lsf_name : "<null>"; |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 151 | const char *exp_name = target->ft_exp ? |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 152 | (char *)target->ft_exp->exp_obd->obd_uuid.uuid : |
| 153 | "<null>"; |
| 154 | |
Greg Kroah-Hartman | b0f5aad | 2014-07-12 20:06:04 -0700 | [diff] [blame] | 155 | CERROR(" exp: 0x%p (%s), srv: 0x%p (%s), idx: %llu\n", |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 156 | target->ft_exp, exp_name, target->ft_srv, |
| 157 | srv_name, target->ft_idx); |
| 158 | } |
| 159 | |
| 160 | /* |
| 161 | * If target is not found, there is logical error anyway, so here is |
| 162 | * LBUG() to catch this situation. |
| 163 | */ |
| 164 | LBUG(); |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 165 | return NULL; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 166 | } |
| 167 | |
| 168 | struct lu_fld_hash fld_hash[] = { |
| 169 | { |
| 170 | .fh_name = "RRB", |
| 171 | .fh_hash_func = fld_rrb_hash, |
| 172 | .fh_scan_func = fld_rrb_scan |
| 173 | }, |
| 174 | { |
Radek Dostal | ea7893b | 2014-07-27 23:22:57 +0200 | [diff] [blame] | 175 | NULL, |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 176 | } |
| 177 | }; |
| 178 | |
| 179 | static struct lu_fld_target * |
Oleg Drokin | 114acca | 2014-08-15 12:55:55 -0400 | [diff] [blame] | 180 | fld_client_get_target(struct lu_client_fld *fld, u64 seq) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 181 | { |
| 182 | struct lu_fld_target *target; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 183 | |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 184 | LASSERT(fld->lcf_hash); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 185 | |
| 186 | spin_lock(&fld->lcf_lock); |
| 187 | target = fld->lcf_hash->fh_scan_func(fld, seq); |
| 188 | spin_unlock(&fld->lcf_lock); |
| 189 | |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 190 | if (target) { |
Greg Kroah-Hartman | 55f5a82 | 2014-07-12 20:26:07 -0700 | [diff] [blame] | 191 | CDEBUG(D_INFO, "%s: Found target (idx %llu) by seq %#llx\n", |
Greg Kroah-Hartman | b0f5aad | 2014-07-12 20:06:04 -0700 | [diff] [blame] | 192 | fld->lcf_name, target->ft_idx, seq); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 193 | } |
| 194 | |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 195 | return target; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 196 | } |
| 197 | |
| 198 | /* |
| 199 | * Add export to FLD. This is usually done by CMM and LMV as they are main users |
| 200 | * of FLD module. |
| 201 | */ |
| 202 | int fld_client_add_target(struct lu_client_fld *fld, |
| 203 | struct lu_fld_target *tar) |
| 204 | { |
| 205 | const char *name; |
| 206 | struct lu_fld_target *target, *tmp; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 207 | |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 208 | LASSERT(tar); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 209 | name = fld_target_name(tar); |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 210 | LASSERT(name); |
| 211 | LASSERT(tar->ft_srv || tar->ft_exp); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 212 | |
| 213 | if (fld->lcf_flags != LUSTRE_FLD_INIT) { |
Greg Kroah-Hartman | b0f5aad | 2014-07-12 20:06:04 -0700 | [diff] [blame] | 214 | CERROR("%s: Attempt to add target %s (idx %llu) on fly - skip it\n", |
Oleg Drokin | cf67759 | 2016-02-26 01:49:51 -0500 | [diff] [blame] | 215 | fld->lcf_name, name, tar->ft_idx); |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 216 | return 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 217 | } |
Alberto Pires de Oliveira Neto | cb6ec7f | 2015-03-01 22:44:04 -0300 | [diff] [blame] | 218 | CDEBUG(D_INFO, "%s: Adding target %s (idx %llu)\n", |
Oleg Drokin | cf67759 | 2016-02-26 01:49:51 -0500 | [diff] [blame] | 219 | fld->lcf_name, name, tar->ft_idx); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 220 | |
Julia Lawall | 2e65101 | 2015-05-01 17:51:21 +0200 | [diff] [blame] | 221 | target = kzalloc(sizeof(*target), GFP_NOFS); |
Julia Lawall | 812f205 | 2015-06-20 18:59:00 +0200 | [diff] [blame] | 222 | if (!target) |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 223 | return -ENOMEM; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 224 | |
| 225 | spin_lock(&fld->lcf_lock); |
| 226 | list_for_each_entry(tmp, &fld->lcf_targets, ft_chain) { |
| 227 | if (tmp->ft_idx == tar->ft_idx) { |
| 228 | spin_unlock(&fld->lcf_lock); |
Julia Lawall | 2e65101 | 2015-05-01 17:51:21 +0200 | [diff] [blame] | 229 | kfree(target); |
Greg Kroah-Hartman | b0f5aad | 2014-07-12 20:06:04 -0700 | [diff] [blame] | 230 | CERROR("Target %s exists in FLD and known as %s:#%llu\n", |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 231 | name, fld_target_name(tmp), tmp->ft_idx); |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 232 | return -EEXIST; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 233 | } |
| 234 | } |
| 235 | |
| 236 | target->ft_exp = tar->ft_exp; |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 237 | if (target->ft_exp) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 238 | class_export_get(target->ft_exp); |
| 239 | target->ft_srv = tar->ft_srv; |
| 240 | target->ft_idx = tar->ft_idx; |
| 241 | |
Oleg Drokin | cf67759 | 2016-02-26 01:49:51 -0500 | [diff] [blame] | 242 | list_add_tail(&target->ft_chain, &fld->lcf_targets); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 243 | |
| 244 | fld->lcf_count++; |
| 245 | spin_unlock(&fld->lcf_lock); |
| 246 | |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 247 | return 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 248 | } |
| 249 | EXPORT_SYMBOL(fld_client_add_target); |
| 250 | |
| 251 | /* Remove export from FLD */ |
| 252 | int fld_client_del_target(struct lu_client_fld *fld, __u64 idx) |
| 253 | { |
| 254 | struct lu_fld_target *target, *tmp; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 255 | |
| 256 | spin_lock(&fld->lcf_lock); |
Oleg Drokin | cf67759 | 2016-02-26 01:49:51 -0500 | [diff] [blame] | 257 | list_for_each_entry_safe(target, tmp, &fld->lcf_targets, ft_chain) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 258 | if (target->ft_idx == idx) { |
| 259 | fld->lcf_count--; |
| 260 | list_del(&target->ft_chain); |
| 261 | spin_unlock(&fld->lcf_lock); |
| 262 | |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 263 | if (target->ft_exp) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 264 | class_export_put(target->ft_exp); |
| 265 | |
Julia Lawall | 2e65101 | 2015-05-01 17:51:21 +0200 | [diff] [blame] | 266 | kfree(target); |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 267 | return 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 268 | } |
| 269 | } |
| 270 | spin_unlock(&fld->lcf_lock); |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 271 | return -ENOENT; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 272 | } |
| 273 | EXPORT_SYMBOL(fld_client_del_target); |
| 274 | |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 275 | static struct dentry *fld_debugfs_dir; |
Liu Xuezhao | e62e5d9 | 2013-07-23 00:06:54 +0800 | [diff] [blame] | 276 | |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 277 | static int fld_client_debugfs_init(struct lu_client_fld *fld) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 278 | { |
| 279 | int rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 280 | |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 281 | fld->lcf_debugfs_entry = ldebugfs_register(fld->lcf_name, |
| 282 | fld_debugfs_dir, |
| 283 | NULL, NULL); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 284 | |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 285 | if (IS_ERR_OR_NULL(fld->lcf_debugfs_entry)) { |
| 286 | CERROR("%s: LdebugFS failed in fld-init\n", fld->lcf_name); |
| 287 | rc = fld->lcf_debugfs_entry ? PTR_ERR(fld->lcf_debugfs_entry) |
| 288 | : -ENOMEM; |
| 289 | fld->lcf_debugfs_entry = NULL; |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 290 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 291 | } |
| 292 | |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 293 | rc = ldebugfs_add_vars(fld->lcf_debugfs_entry, |
| 294 | fld_client_debugfs_list, fld); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 295 | if (rc) { |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 296 | CERROR("%s: Can't init FLD debufs, rc %d\n", fld->lcf_name, rc); |
Julia Lawall | 89180ca | 2014-08-30 16:41:23 +0200 | [diff] [blame] | 297 | goto out_cleanup; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 298 | } |
| 299 | |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 300 | return 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 301 | |
| 302 | out_cleanup: |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 303 | fld_client_debugfs_fini(fld); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 304 | return rc; |
| 305 | } |
| 306 | |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 307 | void fld_client_debugfs_fini(struct lu_client_fld *fld) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 308 | { |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 309 | if (!IS_ERR_OR_NULL(fld->lcf_debugfs_entry)) |
| 310 | ldebugfs_remove(&fld->lcf_debugfs_entry); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 311 | } |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 312 | EXPORT_SYMBOL(fld_client_debugfs_fini); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 313 | |
| 314 | static inline int hash_is_sane(int hash) |
| 315 | { |
| 316 | return (hash >= 0 && hash < ARRAY_SIZE(fld_hash)); |
| 317 | } |
| 318 | |
| 319 | int fld_client_init(struct lu_client_fld *fld, |
| 320 | const char *prefix, int hash) |
| 321 | { |
| 322 | int cache_size, cache_threshold; |
| 323 | int rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 324 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 325 | snprintf(fld->lcf_name, sizeof(fld->lcf_name), |
| 326 | "cli-%s", prefix); |
| 327 | |
| 328 | if (!hash_is_sane(hash)) { |
| 329 | CERROR("%s: Wrong hash function %#x\n", |
| 330 | fld->lcf_name, hash); |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 331 | return -EINVAL; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 332 | } |
| 333 | |
| 334 | fld->lcf_count = 0; |
| 335 | spin_lock_init(&fld->lcf_lock); |
| 336 | fld->lcf_hash = &fld_hash[hash]; |
| 337 | fld->lcf_flags = LUSTRE_FLD_INIT; |
| 338 | INIT_LIST_HEAD(&fld->lcf_targets); |
| 339 | |
| 340 | cache_size = FLD_CLIENT_CACHE_SIZE / |
| 341 | sizeof(struct fld_cache_entry); |
| 342 | |
| 343 | cache_threshold = cache_size * |
| 344 | FLD_CLIENT_CACHE_THRESHOLD / 100; |
| 345 | |
| 346 | fld->lcf_cache = fld_cache_init(fld->lcf_name, |
| 347 | cache_size, cache_threshold); |
| 348 | if (IS_ERR(fld->lcf_cache)) { |
| 349 | rc = PTR_ERR(fld->lcf_cache); |
| 350 | fld->lcf_cache = NULL; |
Julia Lawall | 89180ca | 2014-08-30 16:41:23 +0200 | [diff] [blame] | 351 | goto out; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 352 | } |
| 353 | |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 354 | rc = fld_client_debugfs_init(fld); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 355 | if (rc) |
Julia Lawall | 89180ca | 2014-08-30 16:41:23 +0200 | [diff] [blame] | 356 | goto out; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 357 | out: |
| 358 | if (rc) |
| 359 | fld_client_fini(fld); |
| 360 | else |
| 361 | CDEBUG(D_INFO, "%s: Using \"%s\" hash\n", |
| 362 | fld->lcf_name, fld->lcf_hash->fh_name); |
| 363 | return rc; |
| 364 | } |
| 365 | EXPORT_SYMBOL(fld_client_init); |
| 366 | |
| 367 | void fld_client_fini(struct lu_client_fld *fld) |
| 368 | { |
| 369 | struct lu_fld_target *target, *tmp; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 370 | |
| 371 | spin_lock(&fld->lcf_lock); |
Oleg Drokin | cf67759 | 2016-02-26 01:49:51 -0500 | [diff] [blame] | 372 | list_for_each_entry_safe(target, tmp, &fld->lcf_targets, ft_chain) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 373 | fld->lcf_count--; |
| 374 | list_del(&target->ft_chain); |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 375 | if (target->ft_exp) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 376 | class_export_put(target->ft_exp); |
Julia Lawall | 2e65101 | 2015-05-01 17:51:21 +0200 | [diff] [blame] | 377 | kfree(target); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 378 | } |
| 379 | spin_unlock(&fld->lcf_lock); |
| 380 | |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 381 | if (fld->lcf_cache) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 382 | if (!IS_ERR(fld->lcf_cache)) |
| 383 | fld_cache_fini(fld->lcf_cache); |
| 384 | fld->lcf_cache = NULL; |
| 385 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 386 | } |
| 387 | EXPORT_SYMBOL(fld_client_fini); |
| 388 | |
| 389 | int fld_client_rpc(struct obd_export *exp, |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 390 | struct lu_seq_range *range, __u32 fld_op, |
| 391 | struct ptlrpc_request **reqp) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 392 | { |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 393 | struct ptlrpc_request *req = NULL; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 394 | struct lu_seq_range *prange; |
| 395 | __u32 *op; |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 396 | int rc = 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 397 | struct obd_import *imp; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 398 | |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 399 | LASSERT(exp); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 400 | |
| 401 | imp = class_exp2cliimp(exp); |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 402 | switch (fld_op) { |
| 403 | case FLD_QUERY: |
| 404 | req = ptlrpc_request_alloc_pack(imp, &RQF_FLD_QUERY, |
| 405 | LUSTRE_MDS_VERSION, FLD_QUERY); |
| 406 | if (!req) |
| 407 | return -ENOMEM; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 408 | |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 409 | /* |
| 410 | * XXX: only needed when talking to old server(< 2.6), it should |
| 411 | * be removed when < 2.6 server is not supported |
| 412 | */ |
| 413 | op = req_capsule_client_get(&req->rq_pill, &RMF_FLD_OPC); |
| 414 | *op = FLD_LOOKUP; |
| 415 | |
| 416 | if (imp->imp_connect_flags_orig & OBD_CONNECT_MDS_MDS) |
| 417 | req->rq_allow_replay = 1; |
| 418 | break; |
| 419 | case FLD_READ: |
| 420 | req = ptlrpc_request_alloc_pack(imp, &RQF_FLD_READ, |
| 421 | LUSTRE_MDS_VERSION, FLD_READ); |
| 422 | if (!req) |
| 423 | return -ENOMEM; |
| 424 | |
| 425 | req_capsule_set_size(&req->rq_pill, &RMF_GENERIC_DATA, |
| 426 | RCL_SERVER, PAGE_SIZE); |
| 427 | break; |
| 428 | default: |
| 429 | rc = -EINVAL; |
| 430 | break; |
| 431 | } |
| 432 | if (rc) |
| 433 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 434 | |
| 435 | prange = req_capsule_client_get(&req->rq_pill, &RMF_FLD_MDFLD); |
| 436 | *prange = *range; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 437 | ptlrpc_request_set_replen(req); |
| 438 | req->rq_request_portal = FLD_REQUEST_PORTAL; |
Mikhail Pershin | a331052 | 2014-09-08 21:41:27 -0400 | [diff] [blame] | 439 | req->rq_reply_portal = MDC_REPLY_PORTAL; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 440 | ptlrpc_at_set_req_timeout(req); |
| 441 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 442 | fld_enter_request(&exp->exp_obd->u.cli); |
| 443 | rc = ptlrpc_queue_wait(req); |
| 444 | fld_exit_request(&exp->exp_obd->u.cli); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 445 | if (rc) |
Julia Lawall | 89180ca | 2014-08-30 16:41:23 +0200 | [diff] [blame] | 446 | goto out_req; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 447 | |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 448 | if (fld_op == FLD_QUERY) { |
| 449 | prange = req_capsule_server_get(&req->rq_pill, &RMF_FLD_MDFLD); |
| 450 | if (!prange) { |
| 451 | rc = -EFAULT; |
| 452 | goto out_req; |
| 453 | } |
| 454 | *range = *prange; |
Julia Lawall | 89180ca | 2014-08-30 16:41:23 +0200 | [diff] [blame] | 455 | } |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 456 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 457 | out_req: |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 458 | if (rc || !reqp) { |
| 459 | ptlrpc_req_finished(req); |
| 460 | req = NULL; |
| 461 | } |
| 462 | |
| 463 | if (reqp) |
| 464 | *reqp = req; |
| 465 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 466 | return rc; |
| 467 | } |
| 468 | |
Oleg Drokin | 114acca | 2014-08-15 12:55:55 -0400 | [diff] [blame] | 469 | int fld_client_lookup(struct lu_client_fld *fld, u64 seq, u32 *mds, |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 470 | __u32 flags, const struct lu_env *env) |
| 471 | { |
| 472 | struct lu_seq_range res = { 0 }; |
| 473 | struct lu_fld_target *target; |
| 474 | int rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 475 | |
| 476 | fld->lcf_flags |= LUSTRE_FLD_RUN; |
| 477 | |
| 478 | rc = fld_cache_lookup(fld->lcf_cache, seq, &res); |
| 479 | if (rc == 0) { |
| 480 | *mds = res.lsr_index; |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 481 | return 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 482 | } |
| 483 | |
| 484 | /* Can not find it in the cache */ |
| 485 | target = fld_client_get_target(fld, seq); |
Oleg Drokin | 6ac49ca | 2016-02-16 00:46:50 -0500 | [diff] [blame] | 486 | LASSERT(target); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 487 | |
Greg Kroah-Hartman | 55f5a82 | 2014-07-12 20:26:07 -0700 | [diff] [blame] | 488 | CDEBUG(D_INFO, "%s: Lookup fld entry (seq: %#llx) on target %s (idx %llu)\n", |
Oleg Drokin | cf67759 | 2016-02-26 01:49:51 -0500 | [diff] [blame] | 489 | fld->lcf_name, seq, fld_target_name(target), target->ft_idx); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 490 | |
| 491 | res.lsr_start = seq; |
| 492 | fld_range_set_type(&res, flags); |
wang di | b78c2b9b | 2016-04-28 12:07:34 -0400 | [diff] [blame] | 493 | rc = fld_client_rpc(target->ft_exp, &res, FLD_QUERY, NULL); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 494 | |
| 495 | if (rc == 0) { |
| 496 | *mds = res.lsr_index; |
| 497 | |
| 498 | fld_cache_insert(fld->lcf_cache, &res); |
| 499 | } |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 500 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 501 | } |
| 502 | EXPORT_SYMBOL(fld_client_lookup); |
| 503 | |
| 504 | void fld_client_flush(struct lu_client_fld *fld) |
| 505 | { |
| 506 | fld_cache_flush(fld->lcf_cache); |
| 507 | } |
| 508 | EXPORT_SYMBOL(fld_client_flush); |
Liu Xuezhao | e62e5d9 | 2013-07-23 00:06:54 +0800 | [diff] [blame] | 509 | |
Andreas Dilger | e0f9411 | 2016-02-26 11:36:05 -0500 | [diff] [blame] | 510 | static int __init fld_init(void) |
Liu Xuezhao | e62e5d9 | 2013-07-23 00:06:54 +0800 | [diff] [blame] | 511 | { |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 512 | fld_debugfs_dir = ldebugfs_register(LUSTRE_FLD_NAME, |
| 513 | debugfs_lustre_root, |
| 514 | NULL, NULL); |
| 515 | return PTR_ERR_OR_ZERO(fld_debugfs_dir); |
Liu Xuezhao | e62e5d9 | 2013-07-23 00:06:54 +0800 | [diff] [blame] | 516 | } |
| 517 | |
Andreas Dilger | e0f9411 | 2016-02-26 11:36:05 -0500 | [diff] [blame] | 518 | static void __exit fld_exit(void) |
Liu Xuezhao | e62e5d9 | 2013-07-23 00:06:54 +0800 | [diff] [blame] | 519 | { |
Dmitry Eremin | 8276504 | 2015-05-21 15:32:26 -0400 | [diff] [blame] | 520 | if (!IS_ERR_OR_NULL(fld_debugfs_dir)) |
| 521 | ldebugfs_remove(&fld_debugfs_dir); |
Liu Xuezhao | e62e5d9 | 2013-07-23 00:06:54 +0800 | [diff] [blame] | 522 | } |
| 523 | |
James Simmons | a045547 | 2015-11-04 13:40:02 -0500 | [diff] [blame] | 524 | MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>"); |
Andreas Dilger | 57878e1 | 2016-02-26 11:36:04 -0500 | [diff] [blame] | 525 | MODULE_DESCRIPTION("Lustre FID Location Database"); |
James Simmons | 5b0e50b | 2016-02-26 11:36:03 -0500 | [diff] [blame] | 526 | MODULE_VERSION(LUSTRE_VERSION_STRING); |
Liu Xuezhao | e62e5d9 | 2013-07-23 00:06:54 +0800 | [diff] [blame] | 527 | MODULE_LICENSE("GPL"); |
| 528 | |
Andreas Dilger | e0f9411 | 2016-02-26 11:36:05 -0500 | [diff] [blame] | 529 | module_init(fld_init) |
| 530 | module_exit(fld_exit) |