4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/lov/lov_pack.c
38 * (Un)packing of OST/MDS requests
40 * Author: Andreas Dilger <adilger@clusterfs.com>
43 #define DEBUG_SUBSYSTEM S_LOV
45 #include "../include/lustre_net.h"
46 #include "../include/obd.h"
47 #include "../include/obd_class.h"
48 #include "../include/obd_support.h"
49 #include "../include/lustre/lustre_user.h"
51 #include "lov_internal.h"
53 void lov_dump_lmm_common(int level
, void *lmmp
)
55 struct lov_mds_md
*lmm
= lmmp
;
58 lmm_oi_le_to_cpu(&oi
, &lmm
->lmm_oi
);
59 CDEBUG(level
, "objid "DOSTID
", magic 0x%08x, pattern %#x\n",
60 POSTID(&oi
), le32_to_cpu(lmm
->lmm_magic
),
61 le32_to_cpu(lmm
->lmm_pattern
));
62 CDEBUG(level
, "stripe_size %u, stripe_count %u, layout_gen %u\n",
63 le32_to_cpu(lmm
->lmm_stripe_size
),
64 le16_to_cpu(lmm
->lmm_stripe_count
),
65 le16_to_cpu(lmm
->lmm_layout_gen
));
68 static void lov_dump_lmm_objects(int level
, struct lov_ost_data
*lod
,
73 if (stripe_count
> LOV_V1_INSANE_STRIPE_COUNT
) {
74 CDEBUG(level
, "bad stripe_count %u > max_stripe_count %u\n",
75 stripe_count
, LOV_V1_INSANE_STRIPE_COUNT
);
79 for (i
= 0; i
< stripe_count
; ++i
, ++lod
) {
82 ostid_le_to_cpu(&lod
->l_ost_oi
, &oi
);
83 CDEBUG(level
, "stripe %u idx %u subobj "DOSTID
"\n", i
,
84 le32_to_cpu(lod
->l_ost_idx
), POSTID(&oi
));
88 void lov_dump_lmm_v1(int level
, struct lov_mds_md_v1
*lmm
)
90 lov_dump_lmm_common(level
, lmm
);
91 lov_dump_lmm_objects(level
, lmm
->lmm_objects
,
92 le16_to_cpu(lmm
->lmm_stripe_count
));
95 void lov_dump_lmm_v3(int level
, struct lov_mds_md_v3
*lmm
)
97 lov_dump_lmm_common(level
, lmm
);
98 CDEBUG(level
,"pool_name "LOV_POOLNAMEF
"\n", lmm
->lmm_pool_name
);
99 lov_dump_lmm_objects(level
, lmm
->lmm_objects
,
100 le16_to_cpu(lmm
->lmm_stripe_count
));
103 void lov_dump_lmm(int level
, void *lmm
)
107 magic
= le32_to_cpu(((struct lov_mds_md
*)lmm
)->lmm_magic
);
110 lov_dump_lmm_v1(level
, (struct lov_mds_md_v1
*)lmm
);
113 lov_dump_lmm_v3(level
, (struct lov_mds_md_v3
*)lmm
);
116 CDEBUG(level
, "unrecognized lmm_magic %x, assuming %x\n",
117 magic
, LOV_MAGIC_V1
);
118 lov_dump_lmm_common(level
, lmm
);
123 /* Pack LOV object metadata for disk storage. It is packed in LE byte
124 * order and is opaque to the networking layer.
126 * XXX In the future, this will be enhanced to get the EA size from the
127 * underlying OSC device(s) to get their EA sizes so we can stack
128 * LOVs properly. For now lov_mds_md_size() just assumes one u64
131 int lov_packmd(struct obd_export
*exp
, struct lov_mds_md
**lmmp
,
132 struct lov_stripe_md
*lsm
)
134 struct obd_device
*obd
= class_exp2obd(exp
);
135 struct lov_obd
*lov
= &obd
->u
.lov
;
136 struct lov_mds_md_v1
*lmmv1
;
137 struct lov_mds_md_v3
*lmmv3
;
139 struct lov_ost_data_v1
*lmm_objects
;
140 int lmm_size
, lmm_magic
;
145 lmm_magic
= lsm
->lsm_magic
;
148 lmm_magic
= le32_to_cpu((*lmmp
)->lmm_magic
);
150 /* lsm == NULL and lmmp == NULL */
151 lmm_magic
= LOV_MAGIC
;
154 if ((lmm_magic
!= LOV_MAGIC_V1
) &&
155 (lmm_magic
!= LOV_MAGIC_V3
)) {
156 CERROR("bad mem LOV MAGIC: 0x%08X != 0x%08X nor 0x%08X\n",
157 lmm_magic
, LOV_MAGIC_V1
, LOV_MAGIC_V3
);
163 /* If we are just sizing the EA, limit the stripe count
164 * to the actual number of OSTs in this filesystem. */
166 stripe_count
= lov_get_stripecnt(lov
, lmm_magic
,
167 lsm
->lsm_stripe_count
);
168 lsm
->lsm_stripe_count
= stripe_count
;
169 } else if (!lsm_is_released(lsm
)) {
170 stripe_count
= lsm
->lsm_stripe_count
;
175 /* No need to allocate more than maximum supported stripes.
176 * Anyway, this is pretty inaccurate since ld_tgt_count now
177 * represents max index and we should rely on the actual number
179 stripe_count
= lov_mds_md_max_stripe_count(
180 lov
->lov_ocd
.ocd_max_easize
, lmm_magic
);
182 if (stripe_count
> lov
->desc
.ld_tgt_count
)
183 stripe_count
= lov
->desc
.ld_tgt_count
;
186 /* XXX LOV STACKING call into osc for sizes */
187 lmm_size
= lov_mds_md_size(stripe_count
, lmm_magic
);
193 stripe_count
= le16_to_cpu((*lmmp
)->lmm_stripe_count
);
194 lmm_size
= lov_mds_md_size(stripe_count
, lmm_magic
);
195 OBD_FREE_LARGE(*lmmp
, lmm_size
);
201 OBD_ALLOC_LARGE(*lmmp
, lmm_size
);
206 CDEBUG(D_INFO
, "lov_packmd: LOV_MAGIC 0x%08X, lmm_size = %d \n",
207 lmm_magic
, lmm_size
);
210 lmmv3
= (struct lov_mds_md_v3
*)*lmmp
;
211 if (lmm_magic
== LOV_MAGIC_V3
)
212 lmmv3
->lmm_magic
= cpu_to_le32(LOV_MAGIC_V3
);
214 lmmv1
->lmm_magic
= cpu_to_le32(LOV_MAGIC_V1
);
219 /* lmmv1 and lmmv3 point to the same struct and have the
222 lmm_oi_cpu_to_le(&lmmv1
->lmm_oi
, &lsm
->lsm_oi
);
223 lmmv1
->lmm_stripe_size
= cpu_to_le32(lsm
->lsm_stripe_size
);
224 lmmv1
->lmm_stripe_count
= cpu_to_le16(stripe_count
);
225 lmmv1
->lmm_pattern
= cpu_to_le32(lsm
->lsm_pattern
);
226 lmmv1
->lmm_layout_gen
= cpu_to_le16(lsm
->lsm_layout_gen
);
227 if (lsm
->lsm_magic
== LOV_MAGIC_V3
) {
228 cplen
= strlcpy(lmmv3
->lmm_pool_name
, lsm
->lsm_pool_name
,
229 sizeof(lmmv3
->lmm_pool_name
));
230 if (cplen
>= sizeof(lmmv3
->lmm_pool_name
))
232 lmm_objects
= lmmv3
->lmm_objects
;
234 lmm_objects
= lmmv1
->lmm_objects
;
237 for (i
= 0; i
< stripe_count
; i
++) {
238 struct lov_oinfo
*loi
= lsm
->lsm_oinfo
[i
];
239 /* XXX LOV STACKING call down to osc_packmd() to do packing */
240 LASSERTF(ostid_id(&loi
->loi_oi
) != 0, "lmm_oi "DOSTID
241 " stripe %u/%u idx %u\n", POSTID(&lmmv1
->lmm_oi
),
242 i
, stripe_count
, loi
->loi_ost_idx
);
243 ostid_cpu_to_le(&loi
->loi_oi
, &lmm_objects
[i
].l_ost_oi
);
244 lmm_objects
[i
].l_ost_gen
= cpu_to_le32(loi
->loi_ost_gen
);
245 lmm_objects
[i
].l_ost_idx
= cpu_to_le32(loi
->loi_ost_idx
);
251 /* Find the max stripecount we should use */
252 __u16
lov_get_stripecnt(struct lov_obd
*lov
, __u32 magic
, __u16 stripe_count
)
254 __u32 max_stripes
= LOV_MAX_STRIPE_COUNT_OLD
;
257 stripe_count
= lov
->desc
.ld_default_stripe_count
;
258 if (stripe_count
> lov
->desc
.ld_active_tgt_count
)
259 stripe_count
= lov
->desc
.ld_active_tgt_count
;
263 /* stripe count is based on whether ldiskfs can handle
265 if (lov
->lov_ocd
.ocd_connect_flags
& OBD_CONNECT_MAX_EASIZE
&&
266 lov
->lov_ocd
.ocd_max_easize
)
267 max_stripes
= lov_mds_md_max_stripe_count(
268 lov
->lov_ocd
.ocd_max_easize
, magic
);
270 if (stripe_count
> max_stripes
)
271 stripe_count
= max_stripes
;
277 static int lov_verify_lmm(void *lmm
, int lmm_bytes
, __u16
*stripe_count
)
281 if (lsm_op_find(le32_to_cpu(*(__u32
*)lmm
)) == NULL
) {
285 CERROR("bad disk LOV MAGIC: 0x%08X; dumping LMM (size=%d):\n",
286 le32_to_cpu(*(__u32
*)lmm
), lmm_bytes
);
287 sz
= lmm_bytes
* 2 + 1;
288 OBD_ALLOC_LARGE(buffer
, sz
);
289 if (buffer
!= NULL
) {
292 for (i
= 0; i
< lmm_bytes
; i
++)
293 sprintf(buffer
+2*i
, "%.2X", ((char *)lmm
)[i
]);
294 buffer
[sz
- 1] = '\0';
295 CERROR("%s\n", buffer
);
296 OBD_FREE_LARGE(buffer
, sz
);
300 rc
= lsm_op_find(le32_to_cpu(*(__u32
*)lmm
))->lsm_lmm_verify(lmm
,
301 lmm_bytes
, stripe_count
);
305 int lov_alloc_memmd(struct lov_stripe_md
**lsmp
, __u16 stripe_count
,
306 int pattern
, int magic
)
310 CDEBUG(D_INFO
, "alloc lsm, stripe_count %d\n", stripe_count
);
312 *lsmp
= lsm_alloc_plain(stripe_count
, &lsm_size
);
314 CERROR("can't allocate lsmp stripe_count %d\n", stripe_count
);
318 atomic_set(&(*lsmp
)->lsm_refc
, 1);
319 spin_lock_init(&(*lsmp
)->lsm_lock
);
320 (*lsmp
)->lsm_magic
= magic
;
321 (*lsmp
)->lsm_stripe_count
= stripe_count
;
322 (*lsmp
)->lsm_maxbytes
= LUSTRE_STRIPE_MAXBYTES
* stripe_count
;
323 (*lsmp
)->lsm_pattern
= pattern
;
324 (*lsmp
)->lsm_pool_name
[0] = '\0';
325 (*lsmp
)->lsm_layout_gen
= 0;
326 if (stripe_count
> 0)
327 (*lsmp
)->lsm_oinfo
[0]->loi_ost_idx
= ~0;
329 for (i
= 0; i
< stripe_count
; i
++)
330 loi_init((*lsmp
)->lsm_oinfo
[i
]);
335 int lov_free_memmd(struct lov_stripe_md
**lsmp
)
337 struct lov_stripe_md
*lsm
= *lsmp
;
341 LASSERT(atomic_read(&lsm
->lsm_refc
) > 0);
342 refc
= atomic_dec_return(&lsm
->lsm_refc
);
344 LASSERT(lsm_op_find(lsm
->lsm_magic
) != NULL
);
345 lsm_op_find(lsm
->lsm_magic
)->lsm_free(lsm
);
351 /* Unpack LOV object metadata from disk storage. It is packed in LE byte
352 * order and is opaque to the networking layer.
354 int lov_unpackmd(struct obd_export
*exp
, struct lov_stripe_md
**lsmp
,
355 struct lov_mds_md
*lmm
, int lmm_bytes
)
357 struct obd_device
*obd
= class_exp2obd(exp
);
358 struct lov_obd
*lov
= &obd
->u
.lov
;
359 int rc
= 0, lsm_size
;
364 /* If passed an MDS struct use values from there, otherwise defaults */
366 rc
= lov_verify_lmm(lmm
, lmm_bytes
, &stripe_count
);
369 magic
= le32_to_cpu(lmm
->lmm_magic
);
372 stripe_count
= lov_get_stripecnt(lov
, magic
, 0);
375 /* If we aren't passed an lsmp struct, we just want the size */
377 /* XXX LOV STACKING call into osc for sizes */
379 return lov_stripe_md_size(stripe_count
);
381 /* If we are passed an allocated struct but nothing to unpack, free */
383 lov_free_memmd(lsmp
);
387 pattern
= le32_to_cpu(lmm
->lmm_pattern
);
388 lsm_size
= lov_alloc_memmd(lsmp
, stripe_count
, pattern
, magic
);
392 /* If we are passed a pointer but nothing to unpack, we only alloc */
396 LASSERT(lsm_op_find(magic
) != NULL
);
397 rc
= lsm_op_find(magic
)->lsm_unpackmd(lov
, *lsmp
, lmm
);
399 lov_free_memmd(lsmp
);
406 static int __lov_setstripe(struct obd_export
*exp
, int max_lmm_size
,
407 struct lov_stripe_md
**lsmp
,
408 struct lov_user_md
*lump
)
410 struct obd_device
*obd
= class_exp2obd(exp
);
411 struct lov_obd
*lov
= &obd
->u
.lov
;
412 char buffer
[sizeof(struct lov_user_md_v3
)];
413 struct lov_user_md_v3
*lumv3
= (struct lov_user_md_v3
*)&buffer
[0];
414 struct lov_user_md_v1
*lumv1
= (struct lov_user_md_v1
*)&buffer
[0];
420 rc
= lov_lum_swab_if_needed(lumv3
, &lmm_magic
, lump
);
424 /* in the rest of the tests, as *lumv1 and lumv3 have the same
425 * fields, we use lumv1 to avoid code duplication */
427 if (lumv1
->lmm_pattern
== 0) {
428 lumv1
->lmm_pattern
= lov
->desc
.ld_pattern
?
429 lov
->desc
.ld_pattern
: LOV_PATTERN_RAID0
;
432 if (lov_pattern(lumv1
->lmm_pattern
) != LOV_PATTERN_RAID0
) {
433 CDEBUG(D_IOCTL
, "bad userland stripe pattern: %#x\n",
438 /* 64kB is the largest common page size we see (ia64), and matches the
440 if (lumv1
->lmm_stripe_size
& (LOV_MIN_STRIPE_SIZE
- 1)) {
441 CDEBUG(D_IOCTL
, "stripe size %u not multiple of %u, fixing\n",
442 lumv1
->lmm_stripe_size
, LOV_MIN_STRIPE_SIZE
);
443 lumv1
->lmm_stripe_size
= LOV_MIN_STRIPE_SIZE
;
446 if ((lumv1
->lmm_stripe_offset
>= lov
->desc
.ld_tgt_count
) &&
447 (lumv1
->lmm_stripe_offset
!=
448 (typeof(lumv1
->lmm_stripe_offset
))(-1))) {
449 CDEBUG(D_IOCTL
, "stripe offset %u > number of OSTs %u\n",
450 lumv1
->lmm_stripe_offset
, lov
->desc
.ld_tgt_count
);
453 stripe_count
= lov_get_stripecnt(lov
, lmm_magic
,
454 lumv1
->lmm_stripe_count
);
457 int max_stripes
= (max_lmm_size
-
458 lov_mds_md_size(0, lmm_magic
)) /
459 sizeof(struct lov_ost_data_v1
);
460 if (unlikely(max_stripes
< stripe_count
)) {
461 CDEBUG(D_IOCTL
, "stripe count reset from %d to %d\n",
462 stripe_count
, max_stripes
);
463 stripe_count
= max_stripes
;
467 if (lmm_magic
== LOV_USER_MAGIC_V3
) {
468 struct pool_desc
*pool
;
470 /* In the function below, .hs_keycmp resolves to
471 * pool_hashkey_keycmp() */
472 /* coverity[overrun-buffer-val] */
473 pool
= lov_find_pool(lov
, lumv3
->lmm_pool_name
);
475 if (lumv3
->lmm_stripe_offset
!=
476 (typeof(lumv3
->lmm_stripe_offset
))(-1)) {
477 rc
= lov_check_index_in_pool(
478 lumv3
->lmm_stripe_offset
, pool
);
480 lov_pool_putref(pool
);
485 if (stripe_count
> pool_tgt_count(pool
))
486 stripe_count
= pool_tgt_count(pool
);
488 lov_pool_putref(pool
);
492 if (lumv1
->lmm_pattern
& LOV_PATTERN_F_RELEASED
)
495 rc
= lov_alloc_memmd(lsmp
, stripe_count
, lumv1
->lmm_pattern
, lmm_magic
);
498 (*lsmp
)->lsm_oinfo
[0]->loi_ost_idx
= lumv1
->lmm_stripe_offset
;
499 (*lsmp
)->lsm_stripe_size
= lumv1
->lmm_stripe_size
;
500 if (lmm_magic
== LOV_USER_MAGIC_V3
) {
501 cplen
= strlcpy((*lsmp
)->lsm_pool_name
,
502 lumv3
->lmm_pool_name
,
503 sizeof((*lsmp
)->lsm_pool_name
));
504 if (cplen
>= sizeof((*lsmp
)->lsm_pool_name
))
513 /* Configure object striping information on a new file.
515 * @lmmu is a pointer to a user struct with one or more of the fields set to
516 * indicate the application preference: lmm_stripe_count, lmm_stripe_size,
517 * lmm_stripe_offset, and lmm_stripe_pattern. lmm_magic must be LOV_MAGIC.
518 * @lsmp is a pointer to an in-core stripe MD that needs to be filled in.
520 int lov_setstripe(struct obd_export
*exp
, int max_lmm_size
,
521 struct lov_stripe_md
**lsmp
, struct lov_user_md
*lump
)
529 rc
= __lov_setstripe(exp
, max_lmm_size
, lsmp
, lump
);
534 int lov_setea(struct obd_export
*exp
, struct lov_stripe_md
**lsmp
,
535 struct lov_user_md
*lump
)
539 struct obd_export
*oexp
;
540 struct lov_obd
*lov
= &exp
->exp_obd
->u
.lov
;
542 struct lov_user_ost_data_v1
*lmm_objects
;
544 if (lump
->lmm_magic
== LOV_USER_MAGIC_V3
)
545 lmm_objects
= ((struct lov_user_md_v3
*)lump
)->lmm_objects
;
547 lmm_objects
= lump
->lmm_objects
;
549 for (i
= 0; i
< lump
->lmm_stripe_count
; i
++) {
550 __u32 len
= sizeof(last_id
);
551 oexp
= lov
->lov_tgts
[lmm_objects
[i
].l_ost_idx
]->ltd_exp
;
552 rc
= obd_get_info(NULL
, oexp
, sizeof(KEY_LAST_ID
), KEY_LAST_ID
,
553 &len
, &last_id
, NULL
);
556 if (ostid_id(&lmm_objects
[i
].l_ost_oi
) > last_id
) {
557 CERROR("Setting EA for object > than last id on"
558 " ost idx %d "DOSTID
" > %lld \n",
559 lmm_objects
[i
].l_ost_idx
,
560 POSTID(&lmm_objects
[i
].l_ost_oi
), last_id
);
565 rc
= lov_setstripe(exp
, 0, lsmp
, lump
);
569 for (i
= 0; i
< lump
->lmm_stripe_count
; i
++) {
570 (*lsmp
)->lsm_oinfo
[i
]->loi_ost_idx
=
571 lmm_objects
[i
].l_ost_idx
;
572 (*lsmp
)->lsm_oinfo
[i
]->loi_oi
= lmm_objects
[i
].l_ost_oi
;
578 /* Retrieve object striping information.
580 * @lump is a pointer to an in-core struct with lmm_ost_count indicating
581 * the maximum number of OST indices which will fit in the user buffer.
582 * lmm_magic must be LOV_USER_MAGIC.
584 int lov_getstripe(struct obd_export
*exp
, struct lov_stripe_md
*lsm
,
585 struct lov_user_md
*lump
)
588 * XXX huge struct allocated on stack.
590 /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */
591 struct lov_user_md_v3 lum
;
592 struct lov_mds_md
*lmmk
= NULL
;
601 * "Switch to kernel segment" to allow copying from kernel space by
602 * copy_{to,from}_user().
607 /* we only need the header part from user space to get lmm_magic and
608 * lmm_stripe_count, (the header part is common to v1 and v3) */
609 lum_size
= sizeof(struct lov_user_md_v1
);
610 if (copy_from_user(&lum
, lump
, lum_size
))
611 GOTO(out_set
, rc
= -EFAULT
);
612 else if ((lum
.lmm_magic
!= LOV_USER_MAGIC
) &&
613 (lum
.lmm_magic
!= LOV_USER_MAGIC_V3
))
614 GOTO(out_set
, rc
= -EINVAL
);
616 if (lum
.lmm_stripe_count
&&
617 (lum
.lmm_stripe_count
< lsm
->lsm_stripe_count
)) {
618 /* Return right size of stripe to user */
619 lum
.lmm_stripe_count
= lsm
->lsm_stripe_count
;
620 rc
= copy_to_user(lump
, &lum
, lum_size
);
621 GOTO(out_set
, rc
= -EOVERFLOW
);
623 rc
= lov_packmd(exp
, &lmmk
, lsm
);
629 /* FIXME: Bug 1185 - copy fields properly when structs change */
630 /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */
631 CLASSERT(sizeof(lum
) == sizeof(struct lov_mds_md_v3
));
632 CLASSERT(sizeof(lum
.lmm_objects
[0]) == sizeof(lmmk
->lmm_objects
[0]));
634 if ((cpu_to_le32(LOV_MAGIC
) != LOV_MAGIC
) &&
635 ((lmmk
->lmm_magic
== cpu_to_le32(LOV_MAGIC_V1
)) ||
636 (lmmk
->lmm_magic
== cpu_to_le32(LOV_MAGIC_V3
)))) {
637 lustre_swab_lov_mds_md(lmmk
);
638 lustre_swab_lov_user_md_objects(
639 (struct lov_user_ost_data
*)lmmk
->lmm_objects
,
640 lmmk
->lmm_stripe_count
);
642 if (lum
.lmm_magic
== LOV_USER_MAGIC
) {
643 /* User request for v1, we need skip lmm_pool_name */
644 if (lmmk
->lmm_magic
== LOV_MAGIC_V3
) {
645 memmove((char *)(&lmmk
->lmm_stripe_count
) +
646 sizeof(lmmk
->lmm_stripe_count
),
647 ((struct lov_mds_md_v3
*)lmmk
)->lmm_objects
,
648 lmmk
->lmm_stripe_count
*
649 sizeof(struct lov_ost_data_v1
));
650 lmm_size
-= LOV_MAXPOOLNAME
;
653 /* if v3 we just have to update the lum_size */
654 lum_size
= sizeof(struct lov_user_md_v3
);
657 /* User wasn't expecting this many OST entries */
658 if (lum
.lmm_stripe_count
== 0)
660 else if (lum
.lmm_stripe_count
< lmmk
->lmm_stripe_count
)
661 GOTO(out_set
, rc
= -EOVERFLOW
);
663 * Have a difference between lov_mds_md & lov_user_md.
664 * So we have to re-order the data before copy to user.
666 lum
.lmm_stripe_count
= lmmk
->lmm_stripe_count
;
667 lum
.lmm_layout_gen
= lmmk
->lmm_layout_gen
;
668 ((struct lov_user_md
*)lmmk
)->lmm_layout_gen
= lum
.lmm_layout_gen
;
669 ((struct lov_user_md
*)lmmk
)->lmm_stripe_count
= lum
.lmm_stripe_count
;
670 if (copy_to_user(lump
, lmmk
, lmm_size
))
673 obd_free_diskmd(exp
, &lmmk
);