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) 2003, 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 | |
| 33 | #ifndef LOV_INTERNAL_H |
| 34 | #define LOV_INTERNAL_H |
| 35 | |
Greg Kroah-Hartman | 0cf0f7a | 2014-07-11 22:01:58 -0700 | [diff] [blame] | 36 | #include "../include/obd_class.h" |
| 37 | #include "../include/lustre/lustre_user.h" |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 38 | |
John L. Hammond | 081b726 | 2014-04-27 13:06:40 -0400 | [diff] [blame] | 39 | /* lov_do_div64(a, b) returns a % b, and a = a / b. |
| 40 | * The 32-bit code is LOV-specific due to knowing about stripe limits in |
| 41 | * order to reduce the divisor to a 32-bit number. If the divisor is |
Oleg Drokin | acb9abc | 2016-02-24 22:00:32 -0500 | [diff] [blame] | 42 | * already a 32-bit value the compiler handles this directly. |
| 43 | */ |
John L. Hammond | 081b726 | 2014-04-27 13:06:40 -0400 | [diff] [blame] | 44 | #if BITS_PER_LONG == 64 |
| 45 | # define lov_do_div64(n, base) ({ \ |
| 46 | uint64_t __base = (base); \ |
| 47 | uint64_t __rem; \ |
| 48 | __rem = ((uint64_t)(n)) % __base; \ |
| 49 | (n) = ((uint64_t)(n)) / __base; \ |
| 50 | __rem; \ |
| 51 | }) |
| 52 | #elif BITS_PER_LONG == 32 |
| 53 | # define lov_do_div64(n, base) ({ \ |
| 54 | uint64_t __rem; \ |
| 55 | if ((sizeof(base) > 4) && (((base) & 0xffffffff00000000ULL) != 0)) { \ |
| 56 | int __remainder; \ |
| 57 | LASSERTF(!((base) & (LOV_MIN_STRIPE_SIZE - 1)), "64 bit lov " \ |
| 58 | "division %llu / %llu\n", (n), (uint64_t)(base)); \ |
| 59 | __remainder = (n) & (LOV_MIN_STRIPE_SIZE - 1); \ |
| 60 | (n) >>= LOV_MIN_STRIPE_BITS; \ |
| 61 | __rem = do_div(n, (base) >> LOV_MIN_STRIPE_BITS); \ |
| 62 | __rem <<= LOV_MIN_STRIPE_BITS; \ |
| 63 | __rem += __remainder; \ |
| 64 | } else { \ |
| 65 | __rem = do_div(n, base); \ |
| 66 | } \ |
| 67 | __rem; \ |
| 68 | }) |
| 69 | #endif |
| 70 | |
John L. Hammond | ae322e0 | 2016-05-04 10:28:54 -0400 | [diff] [blame] | 71 | #define pool_tgt_size(p) ((p)->pool_obds.op_size) |
| 72 | #define pool_tgt_count(p) ((p)->pool_obds.op_count) |
| 73 | #define pool_tgt_array(p) ((p)->pool_obds.op_array) |
| 74 | #define pool_tgt_rw_sem(p) ((p)->pool_obds.op_rw_sem) |
| 75 | |
| 76 | struct pool_desc { |
| 77 | char pool_name[LOV_MAXPOOLNAME + 1]; |
| 78 | struct ost_pool pool_obds; |
| 79 | atomic_t pool_refcount; |
| 80 | struct hlist_node pool_hash; /* access by poolname */ |
| 81 | struct list_head pool_list; /* serial access */ |
| 82 | struct dentry *pool_debugfs_entry; /* file in debugfs */ |
| 83 | struct obd_device *pool_lobd; /* owner */ |
| 84 | }; |
| 85 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 86 | struct lov_request { |
| 87 | struct obd_info rq_oi; |
| 88 | struct lov_request_set *rq_rqset; |
| 89 | |
| 90 | struct list_head rq_link; |
| 91 | |
| 92 | int rq_idx; /* index in lov->tgts array */ |
| 93 | int rq_stripe; /* stripe number */ |
| 94 | int rq_complete; |
| 95 | int rq_rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 96 | |
Oleg Drokin | 21aef7d | 2014-08-15 12:55:56 -0400 | [diff] [blame] | 97 | u32 rq_oabufs; |
| 98 | u32 rq_pgaidx; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 99 | }; |
| 100 | |
| 101 | struct lov_request_set { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 102 | struct obd_info *set_oi; |
| 103 | atomic_t set_refcount; |
| 104 | struct obd_export *set_exp; |
| 105 | /* XXX: There is @set_exp already, however obd_statfs gets obd_device |
Oleg Drokin | acb9abc | 2016-02-24 22:00:32 -0500 | [diff] [blame] | 106 | * only. |
| 107 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 108 | struct obd_device *set_obd; |
| 109 | int set_count; |
| 110 | atomic_t set_completes; |
| 111 | atomic_t set_success; |
| 112 | atomic_t set_finish_checked; |
| 113 | struct llog_cookie *set_cookies; |
| 114 | int set_cookie_sent; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 115 | struct list_head set_list; |
| 116 | wait_queue_head_t set_waitq; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 117 | }; |
| 118 | |
| 119 | extern struct kmem_cache *lov_oinfo_slab; |
| 120 | |
Dulshani Gunawardhana | 126e7da | 2013-10-20 23:05:37 +0530 | [diff] [blame] | 121 | extern struct lu_kmem_descr lov_caches[]; |
| 122 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 123 | void lov_finish_set(struct lov_request_set *set); |
| 124 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 125 | static inline void lov_put_reqset(struct lov_request_set *set) |
| 126 | { |
| 127 | if (atomic_dec_and_test(&set->set_refcount)) |
| 128 | lov_finish_set(set); |
| 129 | } |
| 130 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 131 | #define lov_uuid2str(lv, index) \ |
| 132 | (char *)((lv)->lov_tgts[index]->ltd_uuid.uuid) |
| 133 | |
| 134 | /* lov_merge.c */ |
Oleg Drokin | 21aef7d | 2014-08-15 12:55:56 -0400 | [diff] [blame] | 135 | void lov_merge_attrs(struct obdo *tgt, struct obdo *src, u64 valid, |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 136 | struct lov_stripe_md *lsm, int stripeno, int *set); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 137 | int lov_merge_lvb_kms(struct lov_stripe_md *lsm, |
| 138 | struct ost_lvb *lvb, __u64 *kms_place); |
| 139 | |
| 140 | /* lov_offset.c */ |
Oleg Drokin | f1564f1 | 2016-02-26 01:50:05 -0500 | [diff] [blame] | 141 | u64 lov_stripe_size(struct lov_stripe_md *lsm, u64 ost_size, int stripeno); |
Oleg Drokin | 21aef7d | 2014-08-15 12:55:56 -0400 | [diff] [blame] | 142 | int lov_stripe_offset(struct lov_stripe_md *lsm, u64 lov_off, |
| 143 | int stripeno, u64 *u64); |
Oleg Drokin | f1564f1 | 2016-02-26 01:50:05 -0500 | [diff] [blame] | 144 | u64 lov_size_to_stripe(struct lov_stripe_md *lsm, u64 file_size, int stripeno); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 145 | int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno, |
Oleg Drokin | 21aef7d | 2014-08-15 12:55:56 -0400 | [diff] [blame] | 146 | u64 start, u64 end, |
| 147 | u64 *obd_start, u64 *obd_end); |
| 148 | int lov_stripe_number(struct lov_stripe_md *lsm, u64 lov_off); |
Jinshan Xiong | fd7444f | 2016-03-30 19:48:33 -0400 | [diff] [blame] | 149 | pgoff_t lov_stripe_pgoff(struct lov_stripe_md *lsm, pgoff_t stripe_index, |
| 150 | int stripe); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 151 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 152 | /* lov_request.c */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 153 | int lov_update_common_set(struct lov_request_set *set, |
| 154 | struct lov_request *req, int rc); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 155 | int lov_prep_getattr_set(struct obd_export *exp, struct obd_info *oinfo, |
| 156 | struct lov_request_set **reqset); |
| 157 | int lov_fini_getattr_set(struct lov_request_set *set); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 158 | int lov_prep_setattr_set(struct obd_export *exp, struct obd_info *oinfo, |
| 159 | struct obd_trans_info *oti, |
| 160 | struct lov_request_set **reqset); |
| 161 | int lov_update_setattr_set(struct lov_request_set *set, |
| 162 | struct lov_request *req, int rc); |
| 163 | int lov_fini_setattr_set(struct lov_request_set *set); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 164 | int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo, |
| 165 | struct lov_request_set **reqset); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 166 | int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs, |
| 167 | int success); |
| 168 | int lov_fini_statfs_set(struct lov_request_set *set); |
| 169 | int lov_statfs_interpret(struct ptlrpc_request_set *rqset, void *data, int rc); |
| 170 | |
| 171 | /* lov_obd.c */ |
John L. Hammond | ae322e0 | 2016-05-04 10:28:54 -0400 | [diff] [blame] | 172 | void lov_stripe_lock(struct lov_stripe_md *md); |
| 173 | void lov_stripe_unlock(struct lov_stripe_md *md); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 174 | void lov_fix_desc(struct lov_desc *desc); |
| 175 | void lov_fix_desc_stripe_size(__u64 *val); |
| 176 | void lov_fix_desc_stripe_count(__u32 *val); |
| 177 | void lov_fix_desc_pattern(__u32 *val); |
| 178 | void lov_fix_desc_qos_maxage(__u32 *val); |
| 179 | __u16 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u16 stripe_count); |
| 180 | int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, |
| 181 | struct obd_connect_data *data); |
| 182 | int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg); |
| 183 | int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg, |
| 184 | __u32 *indexp, int *genp); |
| 185 | int lov_del_target(struct obd_device *obd, __u32 index, |
| 186 | struct obd_uuid *uuidp, int gen); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 187 | |
| 188 | /* lov_pack.c */ |
| 189 | int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmm, |
| 190 | struct lov_stripe_md *lsm); |
| 191 | int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, |
| 192 | struct lov_mds_md *lmm, int lmm_bytes); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 193 | int lov_alloc_memmd(struct lov_stripe_md **lsmp, __u16 stripe_count, |
| 194 | int pattern, int magic); |
| 195 | int lov_free_memmd(struct lov_stripe_md **lsmp); |
| 196 | |
| 197 | void lov_dump_lmm_v1(int level, struct lov_mds_md_v1 *lmm); |
| 198 | void lov_dump_lmm_v3(int level, struct lov_mds_md_v3 *lmm); |
Andreas Dilger | 53b7853 | 2013-06-03 21:40:47 +0800 | [diff] [blame] | 199 | void lov_dump_lmm_common(int level, void *lmmp); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 200 | |
| 201 | /* lov_ea.c */ |
| 202 | struct lov_stripe_md *lsm_alloc_plain(__u16 stripe_count, int *size); |
| 203 | void lsm_free_plain(struct lov_stripe_md *lsm); |
John L. Hammond | 081b726 | 2014-04-27 13:06:40 -0400 | [diff] [blame] | 204 | void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 205 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 206 | /* lproc_lov.c */ |
Peng Tao | 2c185ff | 2013-12-04 01:54:59 +0800 | [diff] [blame] | 207 | extern const struct file_operations lov_proc_target_fops; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 208 | void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 209 | |
| 210 | /* lov_cl.c */ |
| 211 | extern struct lu_device_type lov_device_type; |
| 212 | |
| 213 | /* pools */ |
James Simmons | db9fc06 | 2015-10-28 12:54:24 -0400 | [diff] [blame] | 214 | extern struct cfs_hash_ops pool_hash_operations; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 215 | /* ost_pool methods */ |
| 216 | int lov_ost_pool_init(struct ost_pool *op, unsigned int count); |
| 217 | int lov_ost_pool_extend(struct ost_pool *op, unsigned int min_count); |
| 218 | int lov_ost_pool_add(struct ost_pool *op, __u32 idx, unsigned int min_count); |
| 219 | int lov_ost_pool_remove(struct ost_pool *op, __u32 idx); |
| 220 | int lov_ost_pool_free(struct ost_pool *op); |
| 221 | |
| 222 | /* high level pool methods */ |
| 223 | int lov_pool_new(struct obd_device *obd, char *poolname); |
| 224 | int lov_pool_del(struct obd_device *obd, char *poolname); |
| 225 | int lov_pool_add(struct obd_device *obd, char *poolname, char *ostname); |
| 226 | int lov_pool_remove(struct obd_device *obd, char *poolname, char *ostname); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 227 | void lov_pool_putref(struct pool_desc *pool); |
| 228 | |
| 229 | static inline struct lov_stripe_md *lsm_addref(struct lov_stripe_md *lsm) |
| 230 | { |
| 231 | LASSERT(atomic_read(&lsm->lsm_refc) > 0); |
| 232 | atomic_inc(&lsm->lsm_refc); |
| 233 | return lsm; |
| 234 | } |
| 235 | |
Yang Sheng | 397632e | 2015-03-25 21:53:22 -0400 | [diff] [blame] | 236 | static inline bool lov_oinfo_is_dummy(const struct lov_oinfo *loi) |
| 237 | { |
| 238 | if (unlikely(loi->loi_oi.oi.oi_id == 0 && |
| 239 | loi->loi_oi.oi.oi_seq == 0 && |
| 240 | loi->loi_ost_idx == 0 && |
| 241 | loi->loi_ost_gen == 0)) |
| 242 | return true; |
| 243 | |
| 244 | return false; |
| 245 | } |
| 246 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 247 | #endif |