Whamcloud - gitweb
Revert "b=19427 correct lmm_object_id and reserve fids for fid-on-OST."
[fs/lustre-release.git] / lustre / lov / lov_ea.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/lov/lov_ea.c
37  *
38  * Author: Wang Di <wangdi@clusterfs.com>
39  */
40
41 #ifndef EXPORT_SYMTAB
42 # define EXPORT_SYMTAB
43 #endif
44 #define DEBUG_SUBSYSTEM S_LOV
45
46 #ifdef __KERNEL__
47 #include <asm/div64.h>
48 #include <libcfs/libcfs.h>
49 #else
50 #include <liblustre.h>
51 #endif
52
53 #include <obd_class.h>
54 #include <obd_lov.h>
55 #include <lustre/lustre_idl.h>
56 #include <lustre_log.h>
57
58 #include "lov_internal.h"
59
60 struct lovea_unpack_args {
61         struct lov_stripe_md *lsm;
62         int                   cursor;
63 };
64
65 static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes,
66                                  int stripe_count)
67 {
68
69         if (stripe_count == 0 || stripe_count > LOV_V1_INSANE_STRIPE_COUNT) {
70                 CERROR("bad stripe count %d\n", stripe_count);
71                 lov_dump_lmm(D_WARNING, lmm);
72                 return -EINVAL;
73         }
74
75         if (lmm->lmm_object_id == 0) {
76                 CERROR("zero object id\n");
77                 lov_dump_lmm(D_WARNING, lmm);
78                 return -EINVAL;
79         }
80
81         if (lmm->lmm_pattern != cpu_to_le32(LOV_PATTERN_RAID0)) {
82                 CERROR("bad striping pattern\n");
83                 lov_dump_lmm(D_WARNING, lmm);
84                 return -EINVAL;
85         }
86
87         if (lmm->lmm_stripe_size == 0 ||
88              (le32_to_cpu(lmm->lmm_stripe_size)&(LOV_MIN_STRIPE_SIZE-1)) != 0) {
89                 CERROR("bad stripe size %u\n",
90                        le32_to_cpu(lmm->lmm_stripe_size));
91                 lov_dump_lmm(D_WARNING, lmm);
92                 return -EINVAL;
93         }
94         return 0;
95 }
96
97 struct lov_stripe_md *lsm_alloc_plain(int stripe_count, int *size)
98 {
99         struct lov_stripe_md *lsm;
100         int i, oinfo_ptrs_size;
101         struct lov_oinfo *loi;
102
103         LASSERT(stripe_count > 0);
104
105         oinfo_ptrs_size = sizeof(struct lov_oinfo *) * stripe_count;
106         *size = sizeof(struct lov_stripe_md) + oinfo_ptrs_size;
107
108         OBD_ALLOC(lsm, *size);
109         if (!lsm)
110                 return NULL;;
111
112         for (i = 0; i < stripe_count; i++) {
113                 OBD_SLAB_ALLOC_PTR_GFP(loi, lov_oinfo_slab, CFS_ALLOC_IO);
114                 if (loi == NULL)
115                         goto err;
116                 lsm->lsm_oinfo[i] = loi;
117         }
118         lsm->lsm_stripe_count = stripe_count;
119         lsm->lsm_pool_name[0] = '\0';
120         return lsm;
121
122 err:
123         while (--i >= 0)
124                 OBD_SLAB_FREE(lsm->lsm_oinfo[i], lov_oinfo_slab, sizeof(*loi));
125         OBD_FREE(lsm, *size);
126         return NULL;
127 }
128
129 void lsm_free_plain(struct lov_stripe_md *lsm)
130 {
131         int stripe_count = lsm->lsm_stripe_count;
132         int i;
133
134         for (i = 0; i < stripe_count; i++)
135                 OBD_SLAB_FREE(lsm->lsm_oinfo[i], lov_oinfo_slab,
136                               sizeof(struct lov_oinfo));
137         OBD_FREE(lsm, sizeof(struct lov_stripe_md) +
138                  stripe_count * sizeof(struct lov_oinfo *));
139 }
140
141 static void lsm_unpackmd_common(struct lov_stripe_md *lsm,
142                                 struct lov_mds_md *lmm)
143 {
144         /*
145          * This supposes lov_mds_md_v1/v3 first fields are
146          * are the same
147          */
148         lsm->lsm_object_id = le64_to_cpu(lmm->lmm_object_id);
149         lsm->lsm_object_gr = le64_to_cpu(lmm->lmm_object_gr);
150         lsm->lsm_stripe_size = le32_to_cpu(lmm->lmm_stripe_size);
151         lsm->lsm_pattern = le32_to_cpu(lmm->lmm_pattern);
152         lsm->lsm_pool_name[0] = '\0';
153 }
154
155 static void
156 lsm_stripe_by_index_plain(struct lov_stripe_md *lsm, int *stripeno,
157                            obd_off *lov_off, obd_off *swidth)
158 {
159         if (swidth)
160                 *swidth = (obd_off)lsm->lsm_stripe_size * lsm->lsm_stripe_count;
161 }
162
163 static void
164 lsm_stripe_by_offset_plain(struct lov_stripe_md *lsm, int *stripeno,
165                            obd_off *lov_off, obd_off *swidth)
166 {
167         if (swidth)
168                 *swidth = (obd_off)lsm->lsm_stripe_size * lsm->lsm_stripe_count;
169 }
170
171 static int lsm_destroy_plain(struct lov_stripe_md *lsm, struct obdo *oa,
172                              struct obd_export *md_exp)
173 {
174         return 0;
175 }
176
177 static int lsm_lmm_verify_v1(struct lov_mds_md_v1 *lmm, int lmm_bytes,
178                              int *stripe_count)
179 {
180         if (lmm_bytes < sizeof(*lmm)) {
181                 CERROR("lov_mds_md_v1 too small: %d, need at least %d\n",
182                        lmm_bytes, (int)sizeof(*lmm));
183                 return -EINVAL;
184         }
185
186         *stripe_count = le32_to_cpu(lmm->lmm_stripe_count);
187
188         if (lmm_bytes < lov_mds_md_size(*stripe_count, LOV_MAGIC_V1)) {
189                 CERROR("LOV EA V1 too small: %d, need %d\n",
190                        lmm_bytes, lov_mds_md_size(*stripe_count, LOV_MAGIC_V1));
191                 lov_dump_lmm_v1(D_WARNING, lmm);
192                 return -EINVAL;
193         }
194
195         return lsm_lmm_verify_common(lmm, lmm_bytes, *stripe_count);
196 }
197
198 int lsm_unpackmd_v1(struct lov_obd *lov, struct lov_stripe_md *lsm,
199                     struct lov_mds_md_v1 *lmm)
200 {
201         struct lov_oinfo *loi;
202         int i;
203
204         lsm_unpackmd_common(lsm, lmm);
205
206         for (i = 0; i < lsm->lsm_stripe_count; i++) {
207                 /* XXX LOV STACKING call down to osc_unpackmd() */
208                 loi = lsm->lsm_oinfo[i];
209                 loi->loi_id = le64_to_cpu(lmm->lmm_objects[i].l_object_id);
210                 loi->loi_gr = le64_to_cpu(lmm->lmm_objects[i].l_object_gr);
211                 loi->loi_ost_idx = le32_to_cpu(lmm->lmm_objects[i].l_ost_idx);
212                 loi->loi_ost_gen = le32_to_cpu(lmm->lmm_objects[i].l_ost_gen);
213                 if (loi->loi_ost_idx >= lov->desc.ld_tgt_count) {
214                         CERROR("OST index %d more than OST count %d\n",
215                                loi->loi_ost_idx, lov->desc.ld_tgt_count);
216                         lov_dump_lmm_v1(D_WARNING, lmm);
217                         return -EINVAL;
218                 }
219                 if (!lov->lov_tgts[loi->loi_ost_idx]) {
220                         CERROR("OST index %d missing\n", loi->loi_ost_idx);
221                         lov_dump_lmm_v1(D_WARNING, lmm);
222                         return -EINVAL;
223                 }
224         }
225
226         return 0;
227 }
228
229 const struct lsm_operations lsm_v1_ops = {
230         .lsm_free            = lsm_free_plain,
231         .lsm_destroy         = lsm_destroy_plain,
232         .lsm_stripe_by_index    = lsm_stripe_by_index_plain,
233         .lsm_stripe_by_offset   = lsm_stripe_by_offset_plain,
234         .lsm_lmm_verify         = lsm_lmm_verify_v1,
235         .lsm_unpackmd           = lsm_unpackmd_v1,
236 };
237
238 static int lsm_lmm_verify_v3(struct lov_mds_md *lmmv1, int lmm_bytes,
239                              int *stripe_count)
240 {
241         struct lov_mds_md_v3 *lmm;
242
243         lmm = (struct lov_mds_md_v3 *)lmmv1;
244
245         if (lmm_bytes < sizeof(*lmm)) {
246                 CERROR("lov_mds_md_v3 too small: %d, need at least %d\n",
247                        lmm_bytes, (int)sizeof(*lmm));
248                 return -EINVAL;
249         }
250
251         *stripe_count = le32_to_cpu(lmm->lmm_stripe_count);
252
253         if (lmm_bytes < lov_mds_md_size(*stripe_count, LOV_MAGIC_V3)) {
254                 CERROR("LOV EA V3 too small: %d, need %d\n",
255                        lmm_bytes, lov_mds_md_size(*stripe_count, LOV_MAGIC_V3));
256                 lov_dump_lmm_v3(D_WARNING, lmm);
257                 return -EINVAL;
258         }
259
260         return lsm_lmm_verify_common((struct lov_mds_md_v1 *)lmm, lmm_bytes,
261                                      *stripe_count);
262 }
263
264 int lsm_unpackmd_v3(struct lov_obd *lov, struct lov_stripe_md *lsm,
265                     struct lov_mds_md *lmmv1)
266 {
267         struct lov_mds_md_v3 *lmm;
268         struct lov_oinfo *loi;
269         int i;
270
271         lmm = (struct lov_mds_md_v3 *)lmmv1;
272
273         lsm_unpackmd_common(lsm, (struct lov_mds_md_v1 *)lmm);
274         strncpy(lsm->lsm_pool_name, lmm->lmm_pool_name, LOV_MAXPOOLNAME);
275
276         for (i = 0; i < lsm->lsm_stripe_count; i++) {
277                 /* XXX LOV STACKING call down to osc_unpackmd() */
278                 loi = lsm->lsm_oinfo[i];
279                 loi->loi_id = le64_to_cpu(lmm->lmm_objects[i].l_object_id);
280                 loi->loi_gr = le64_to_cpu(lmm->lmm_objects[i].l_object_gr);
281                 loi->loi_ost_idx = le32_to_cpu(lmm->lmm_objects[i].l_ost_idx);
282                 loi->loi_ost_gen = le32_to_cpu(lmm->lmm_objects[i].l_ost_gen);
283                 if (loi->loi_ost_idx >= lov->desc.ld_tgt_count) {
284                         CERROR("OST index %d more than OST count %d\n",
285                                loi->loi_ost_idx, lov->desc.ld_tgt_count);
286                         lov_dump_lmm_v3(D_WARNING, lmm);
287                         return -EINVAL;
288                 }
289                 if (!lov->lov_tgts[loi->loi_ost_idx]) {
290                         CERROR("OST index %d missing\n", loi->loi_ost_idx);
291                         lov_dump_lmm_v3(D_WARNING, lmm);
292                         return -EINVAL;
293                 }
294         }
295
296         return 0;
297 }
298
299 const struct lsm_operations lsm_v3_ops = {
300         .lsm_free            = lsm_free_plain,
301         .lsm_destroy         = lsm_destroy_plain,
302         .lsm_stripe_by_index    = lsm_stripe_by_index_plain,
303         .lsm_stripe_by_offset   = lsm_stripe_by_offset_plain,
304         .lsm_lmm_verify         = lsm_lmm_verify_v3,
305         .lsm_unpackmd           = lsm_unpackmd_v3,
306 };
307