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_obd.c
38 * Author: Phil Schwan <phil@clusterfs.com>
39 * Author: Peter Braam <braam@clusterfs.com>
40 * Author: Mike Shaver <shaver@clusterfs.com>
41 * Author: Nathan Rutman <nathan@clusterfs.com>
44 #define DEBUG_SUBSYSTEM S_LOV
45 #include "../../include/linux/libcfs/libcfs.h"
47 #include "../include/obd_support.h"
48 #include "../include/lustre_lib.h"
49 #include "../include/lustre_net.h"
50 #include "../include/lustre/lustre_idl.h"
51 #include "../include/lustre_dlm.h"
52 #include "../include/lustre_mds.h"
53 #include "../include/obd_class.h"
54 #include "../include/obd_ost.h"
55 #include "../include/lprocfs_status.h"
56 #include "../include/lustre_param.h"
57 #include "../include/cl_object.h"
58 #include "../include/lclient.h" /* for cl_client_lru */
59 #include "../include/lustre/ll_fiemap.h"
60 #include "../include/lustre_fid.h"
62 #include "lov_internal.h"
64 /* Keep a refcount of lov->tgt usage to prevent racing with addition/deletion.
65 Any function that expects lov_tgts to remain stationary must take a ref. */
66 static void lov_getref(struct obd_device
*obd
)
68 struct lov_obd
*lov
= &obd
->u
.lov
;
70 /* nobody gets through here until lov_putref is done */
71 mutex_lock(&lov
->lov_lock
);
72 atomic_inc(&lov
->lov_refcount
);
73 mutex_unlock(&lov
->lov_lock
);
77 static void __lov_del_obd(struct obd_device
*obd
, struct lov_tgt_desc
*tgt
);
79 static void lov_putref(struct obd_device
*obd
)
81 struct lov_obd
*lov
= &obd
->u
.lov
;
83 mutex_lock(&lov
->lov_lock
);
84 /* ok to dec to 0 more than once -- ltd_exp's will be null */
85 if (atomic_dec_and_test(&lov
->lov_refcount
) && lov
->lov_death_row
) {
88 struct lov_tgt_desc
*tgt
, *n
;
89 CDEBUG(D_CONFIG
, "destroying %d lov targets\n",
91 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
92 tgt
= lov
->lov_tgts
[i
];
94 if (!tgt
|| !tgt
->ltd_reap
)
96 list_add(&tgt
->ltd_kill
, &kill
);
97 /* XXX - right now there is a dependency on ld_tgt_count
98 * being the maximum tgt index for computing the
99 * mds_max_easize. So we can't shrink it. */
100 lov_ost_pool_remove(&lov
->lov_packed
, i
);
101 lov
->lov_tgts
[i
] = NULL
;
102 lov
->lov_death_row
--;
104 mutex_unlock(&lov
->lov_lock
);
106 list_for_each_entry_safe(tgt
, n
, &kill
, ltd_kill
) {
107 list_del(&tgt
->ltd_kill
);
109 __lov_del_obd(obd
, tgt
);
112 mutex_unlock(&lov
->lov_lock
);
116 static int lov_set_osc_active(struct obd_device
*obd
, struct obd_uuid
*uuid
,
117 enum obd_notify_event ev
);
118 static int lov_notify(struct obd_device
*obd
, struct obd_device
*watched
,
119 enum obd_notify_event ev
, void *data
);
122 #define MAX_STRING_SIZE 128
123 int lov_connect_obd(struct obd_device
*obd
, __u32 index
, int activate
,
124 struct obd_connect_data
*data
)
126 struct lov_obd
*lov
= &obd
->u
.lov
;
127 struct obd_uuid
*tgt_uuid
;
128 struct obd_device
*tgt_obd
;
129 static struct obd_uuid lov_osc_uuid
= { "LOV_OSC_UUID" };
130 struct obd_import
*imp
;
131 struct proc_dir_entry
*lov_proc_dir
;
134 if (!lov
->lov_tgts
[index
])
137 tgt_uuid
= &lov
->lov_tgts
[index
]->ltd_uuid
;
138 tgt_obd
= lov
->lov_tgts
[index
]->ltd_obd
;
140 if (!tgt_obd
->obd_set_up
) {
141 CERROR("Target %s not set up\n", obd_uuid2str(tgt_uuid
));
145 /* override the sp_me from lov */
146 tgt_obd
->u
.cli
.cl_sp_me
= lov
->lov_sp_me
;
148 if (data
&& (data
->ocd_connect_flags
& OBD_CONNECT_INDEX
))
149 data
->ocd_index
= index
;
152 * Divine LOV knows that OBDs under it are OSCs.
154 imp
= tgt_obd
->u
.cli
.cl_import
;
157 tgt_obd
->obd_no_recov
= 0;
158 /* FIXME this is probably supposed to be
159 ptlrpc_set_import_active. Horrible naming. */
160 ptlrpc_activate_import(imp
);
163 rc
= obd_register_observer(tgt_obd
, obd
);
165 CERROR("Target %s register_observer error %d\n",
166 obd_uuid2str(tgt_uuid
), rc
);
171 if (imp
->imp_invalid
) {
172 CDEBUG(D_CONFIG
, "not connecting OSC %s; administratively "
173 "disabled\n", obd_uuid2str(tgt_uuid
));
177 rc
= obd_connect(NULL
, &lov
->lov_tgts
[index
]->ltd_exp
, tgt_obd
,
178 &lov_osc_uuid
, data
, NULL
);
179 if (rc
|| !lov
->lov_tgts
[index
]->ltd_exp
) {
180 CERROR("Target %s connect error %d\n",
181 obd_uuid2str(tgt_uuid
), rc
);
185 lov
->lov_tgts
[index
]->ltd_reap
= 0;
187 CDEBUG(D_CONFIG
, "Connected tgt idx %d %s (%s) %sactive\n", index
,
188 obd_uuid2str(tgt_uuid
), tgt_obd
->obd_name
, activate
? "":"in");
190 lov_proc_dir
= obd
->obd_proc_private
;
192 struct obd_device
*osc_obd
= lov
->lov_tgts
[index
]->ltd_exp
->exp_obd
;
193 struct proc_dir_entry
*osc_symlink
;
195 LASSERT(osc_obd
!= NULL
);
196 LASSERT(osc_obd
->obd_magic
== OBD_DEVICE_MAGIC
);
197 LASSERT(osc_obd
->obd_type
->typ_name
!= NULL
);
199 osc_symlink
= lprocfs_add_symlink(osc_obd
->obd_name
,
202 osc_obd
->obd_type
->typ_name
,
204 if (osc_symlink
== NULL
) {
205 CERROR("could not register LOV target "
206 "/proc/fs/lustre/%s/%s/target_obds/%s.",
207 obd
->obd_type
->typ_name
, obd
->obd_name
,
209 lprocfs_remove(&lov_proc_dir
);
210 obd
->obd_proc_private
= NULL
;
217 static int lov_connect(const struct lu_env
*env
,
218 struct obd_export
**exp
, struct obd_device
*obd
,
219 struct obd_uuid
*cluuid
, struct obd_connect_data
*data
,
222 struct lov_obd
*lov
= &obd
->u
.lov
;
223 struct lov_tgt_desc
*tgt
;
224 struct lustre_handle conn
;
227 CDEBUG(D_CONFIG
, "connect #%d\n", lov
->lov_connects
);
229 rc
= class_connect(&conn
, obd
, cluuid
);
233 *exp
= class_conn2export(&conn
);
235 /* Why should there ever be more than 1 connect? */
237 LASSERT(lov
->lov_connects
== 1);
239 memset(&lov
->lov_ocd
, 0, sizeof(lov
->lov_ocd
));
241 lov
->lov_ocd
= *data
;
244 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
245 tgt
= lov
->lov_tgts
[i
];
246 if (!tgt
|| obd_uuid_empty(&tgt
->ltd_uuid
))
248 /* Flags will be lowest common denominator */
249 rc
= lov_connect_obd(obd
, i
, tgt
->ltd_activate
, &lov
->lov_ocd
);
251 CERROR("%s: lov connect tgt %d failed: %d\n",
252 obd
->obd_name
, i
, rc
);
255 /* connect to administrative disabled ost */
256 if (!lov
->lov_tgts
[i
]->ltd_exp
)
259 rc
= lov_notify(obd
, lov
->lov_tgts
[i
]->ltd_exp
->exp_obd
,
260 OBD_NOTIFY_CONNECT
, (void *)&i
);
262 CERROR("%s error sending notify %d\n",
271 static int lov_disconnect_obd(struct obd_device
*obd
, struct lov_tgt_desc
*tgt
)
273 struct proc_dir_entry
*lov_proc_dir
;
274 struct lov_obd
*lov
= &obd
->u
.lov
;
275 struct obd_device
*osc_obd
;
278 osc_obd
= class_exp2obd(tgt
->ltd_exp
);
279 CDEBUG(D_CONFIG
, "%s: disconnecting target %s\n",
280 obd
->obd_name
, osc_obd
? osc_obd
->obd_name
: "NULL");
282 if (tgt
->ltd_active
) {
284 lov
->desc
.ld_active_tgt_count
--;
285 tgt
->ltd_exp
->exp_obd
->obd_inactive
= 1;
289 lov_proc_dir
= obd
->obd_proc_private
;
291 lprocfs_remove_proc_entry(osc_obd
->obd_name
, lov_proc_dir
);
293 /* Pass it on to our clients.
294 * XXX This should be an argument to disconnect,
295 * XXX not a back-door flag on the OBD. Ah well.
297 osc_obd
->obd_force
= obd
->obd_force
;
298 osc_obd
->obd_fail
= obd
->obd_fail
;
299 osc_obd
->obd_no_recov
= obd
->obd_no_recov
;
302 obd_register_observer(osc_obd
, NULL
);
304 rc
= obd_disconnect(tgt
->ltd_exp
);
306 CERROR("Target %s disconnect error %d\n",
307 tgt
->ltd_uuid
.uuid
, rc
);
315 static int lov_disconnect(struct obd_export
*exp
)
317 struct obd_device
*obd
= class_exp2obd(exp
);
318 struct lov_obd
*lov
= &obd
->u
.lov
;
324 /* Only disconnect the underlying layers on the final disconnect. */
326 if (lov
->lov_connects
!= 0) {
327 /* why should there be more than 1 connect? */
328 CERROR("disconnect #%d\n", lov
->lov_connects
);
332 /* Let's hold another reference so lov_del_obd doesn't spin through
336 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
337 if (lov
->lov_tgts
[i
] && lov
->lov_tgts
[i
]->ltd_exp
) {
338 /* Disconnection is the last we know about an obd */
339 lov_del_target(obd
, i
, NULL
, lov
->lov_tgts
[i
]->ltd_gen
);
345 rc
= class_disconnect(exp
); /* bz 9811 */
351 * -EINVAL : UUID can't be found in the LOV's target list
352 * -ENOTCONN: The UUID is found, but the target connection is bad (!)
353 * -EBADF : The UUID is found, but the OBD is the wrong type (!)
354 * any >= 0 : is log target index
356 static int lov_set_osc_active(struct obd_device
*obd
, struct obd_uuid
*uuid
,
357 enum obd_notify_event ev
)
359 struct lov_obd
*lov
= &obd
->u
.lov
;
360 struct lov_tgt_desc
*tgt
;
361 int index
, activate
, active
;
363 CDEBUG(D_INFO
, "Searching in lov %p for uuid %s event(%d)\n",
364 lov
, uuid
->uuid
, ev
);
367 for (index
= 0; index
< lov
->desc
.ld_tgt_count
; index
++) {
368 tgt
= lov
->lov_tgts
[index
];
372 * LU-642, initially inactive OSC could miss the obd_connect,
373 * we make up for it here.
375 if (ev
== OBD_NOTIFY_ACTIVATE
&& tgt
->ltd_exp
== NULL
&&
376 obd_uuid_equals(uuid
, &tgt
->ltd_uuid
)) {
377 struct obd_uuid lov_osc_uuid
= {"LOV_OSC_UUID"};
379 obd_connect(NULL
, &tgt
->ltd_exp
, tgt
->ltd_obd
,
380 &lov_osc_uuid
, &lov
->lov_ocd
, NULL
);
385 CDEBUG(D_INFO
, "lov idx %d is %s conn %#llx\n",
386 index
, obd_uuid2str(&tgt
->ltd_uuid
),
387 tgt
->ltd_exp
->exp_handle
.h_cookie
);
388 if (obd_uuid_equals(uuid
, &tgt
->ltd_uuid
))
392 if (index
== lov
->desc
.ld_tgt_count
)
393 GOTO(out
, index
= -EINVAL
);
395 if (ev
== OBD_NOTIFY_DEACTIVATE
|| ev
== OBD_NOTIFY_ACTIVATE
) {
396 activate
= (ev
== OBD_NOTIFY_ACTIVATE
) ? 1 : 0;
398 if (lov
->lov_tgts
[index
]->ltd_activate
== activate
) {
399 CDEBUG(D_INFO
, "OSC %s already %sactivate!\n",
400 uuid
->uuid
, activate
? "" : "de");
402 lov
->lov_tgts
[index
]->ltd_activate
= activate
;
403 CDEBUG(D_CONFIG
, "%sactivate OSC %s\n",
404 activate
? "" : "de", obd_uuid2str(uuid
));
407 } else if (ev
== OBD_NOTIFY_INACTIVE
|| ev
== OBD_NOTIFY_ACTIVE
) {
408 active
= (ev
== OBD_NOTIFY_ACTIVE
) ? 1 : 0;
410 if (lov
->lov_tgts
[index
]->ltd_active
== active
) {
411 CDEBUG(D_INFO
, "OSC %s already %sactive!\n",
412 uuid
->uuid
, active
? "" : "in");
415 CDEBUG(D_CONFIG
, "Marking OSC %s %sactive\n",
416 obd_uuid2str(uuid
), active
? "" : "in");
419 lov
->lov_tgts
[index
]->ltd_active
= active
;
421 lov
->desc
.ld_active_tgt_count
++;
422 lov
->lov_tgts
[index
]->ltd_exp
->exp_obd
->obd_inactive
= 0;
424 lov
->desc
.ld_active_tgt_count
--;
425 lov
->lov_tgts
[index
]->ltd_exp
->exp_obd
->obd_inactive
= 1;
428 CERROR("Unknown event(%d) for uuid %s", ev
, uuid
->uuid
);
436 static int lov_notify(struct obd_device
*obd
, struct obd_device
*watched
,
437 enum obd_notify_event ev
, void *data
)
440 struct lov_obd
*lov
= &obd
->u
.lov
;
442 down_read(&lov
->lov_notify_lock
);
443 if (!lov
->lov_connects
) {
444 up_read(&lov
->lov_notify_lock
);
448 if (ev
== OBD_NOTIFY_ACTIVE
|| ev
== OBD_NOTIFY_INACTIVE
||
449 ev
== OBD_NOTIFY_ACTIVATE
|| ev
== OBD_NOTIFY_DEACTIVATE
) {
450 struct obd_uuid
*uuid
;
454 if (strcmp(watched
->obd_type
->typ_name
, LUSTRE_OSC_NAME
)) {
455 up_read(&lov
->lov_notify_lock
);
456 CERROR("unexpected notification of %s %s!\n",
457 watched
->obd_type
->typ_name
,
461 uuid
= &watched
->u
.cli
.cl_target_uuid
;
463 /* Set OSC as active before notifying the observer, so the
464 * observer can use the OSC normally.
466 rc
= lov_set_osc_active(obd
, uuid
, ev
);
468 up_read(&lov
->lov_notify_lock
);
469 CERROR("event(%d) of %s failed: %d\n", ev
,
470 obd_uuid2str(uuid
), rc
);
473 /* active event should be pass lov target index as data */
477 /* Pass the notification up the chain. */
479 rc
= obd_notify_observer(obd
, watched
, ev
, data
);
481 /* NULL watched means all osc's in the lov (only for syncs) */
482 /* sync event should be send lov idx as data */
483 struct lov_obd
*lov
= &obd
->u
.lov
;
487 is_sync
= (ev
== OBD_NOTIFY_SYNC
) ||
488 (ev
== OBD_NOTIFY_SYNC_NONBLOCK
);
491 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
492 if (!lov
->lov_tgts
[i
])
495 /* don't send sync event if target not
496 * connected/activated */
497 if (is_sync
&& !lov
->lov_tgts
[i
]->ltd_active
)
500 rc
= obd_notify_observer(obd
, lov
->lov_tgts
[i
]->ltd_obd
,
503 CERROR("%s: notify %s of %s failed %d\n",
505 obd
->obd_observer
->obd_name
,
506 lov
->lov_tgts
[i
]->ltd_obd
->obd_name
,
513 up_read(&lov
->lov_notify_lock
);
517 static int lov_add_target(struct obd_device
*obd
, struct obd_uuid
*uuidp
,
518 __u32 index
, int gen
, int active
)
520 struct lov_obd
*lov
= &obd
->u
.lov
;
521 struct lov_tgt_desc
*tgt
;
522 struct obd_device
*tgt_obd
;
525 CDEBUG(D_CONFIG
, "uuid:%s idx:%d gen:%d active:%d\n",
526 uuidp
->uuid
, index
, gen
, active
);
529 CERROR("request to add OBD %s with invalid generation: %d\n",
534 tgt_obd
= class_find_client_obd(uuidp
, LUSTRE_OSC_NAME
,
539 mutex_lock(&lov
->lov_lock
);
541 if ((index
< lov
->lov_tgt_size
) && (lov
->lov_tgts
[index
] != NULL
)) {
542 tgt
= lov
->lov_tgts
[index
];
543 CERROR("UUID %s already assigned at LOV target index %d\n",
544 obd_uuid2str(&tgt
->ltd_uuid
), index
);
545 mutex_unlock(&lov
->lov_lock
);
549 if (index
>= lov
->lov_tgt_size
) {
550 /* We need to reallocate the lov target array. */
551 struct lov_tgt_desc
**newtgts
, **old
= NULL
;
552 __u32 newsize
, oldsize
= 0;
554 newsize
= max_t(__u32
, lov
->lov_tgt_size
, 2);
555 while (newsize
< index
+ 1)
556 newsize
= newsize
<< 1;
557 OBD_ALLOC(newtgts
, sizeof(*newtgts
) * newsize
);
558 if (newtgts
== NULL
) {
559 mutex_unlock(&lov
->lov_lock
);
563 if (lov
->lov_tgt_size
) {
564 memcpy(newtgts
, lov
->lov_tgts
, sizeof(*newtgts
) *
567 oldsize
= lov
->lov_tgt_size
;
570 lov
->lov_tgts
= newtgts
;
571 lov
->lov_tgt_size
= newsize
;
574 OBD_FREE(old
, sizeof(*old
) * oldsize
);
576 CDEBUG(D_CONFIG
, "tgts: %p size: %d\n",
577 lov
->lov_tgts
, lov
->lov_tgt_size
);
582 mutex_unlock(&lov
->lov_lock
);
586 rc
= lov_ost_pool_add(&lov
->lov_packed
, index
, lov
->lov_tgt_size
);
588 mutex_unlock(&lov
->lov_lock
);
593 tgt
->ltd_uuid
= *uuidp
;
594 tgt
->ltd_obd
= tgt_obd
;
595 /* XXX - add a sanity check on the generation number. */
597 tgt
->ltd_index
= index
;
598 tgt
->ltd_activate
= active
;
599 lov
->lov_tgts
[index
] = tgt
;
600 if (index
>= lov
->desc
.ld_tgt_count
)
601 lov
->desc
.ld_tgt_count
= index
+ 1;
603 mutex_unlock(&lov
->lov_lock
);
605 CDEBUG(D_CONFIG
, "idx=%d ltd_gen=%d ld_tgt_count=%d\n",
606 index
, tgt
->ltd_gen
, lov
->desc
.ld_tgt_count
);
608 rc
= obd_notify(obd
, tgt_obd
, OBD_NOTIFY_CREATE
, &index
);
610 if (lov
->lov_connects
== 0) {
611 /* lov_connect hasn't been called yet. We'll do the
612 lov_connect_obd on this target when that fn first runs,
613 because we don't know the connect flags yet. */
619 rc
= lov_connect_obd(obd
, index
, active
, &lov
->lov_ocd
);
623 /* connect to administrative disabled ost */
627 if (lov
->lov_cache
!= NULL
) {
628 rc
= obd_set_info_async(NULL
, tgt
->ltd_exp
,
629 sizeof(KEY_CACHE_SET
), KEY_CACHE_SET
,
630 sizeof(struct cl_client_cache
), lov
->lov_cache
,
636 rc
= lov_notify(obd
, tgt
->ltd_exp
->exp_obd
,
637 active
? OBD_NOTIFY_CONNECT
: OBD_NOTIFY_INACTIVE
,
642 CERROR("add failed (%d), deleting %s\n", rc
,
643 obd_uuid2str(&tgt
->ltd_uuid
));
644 lov_del_target(obd
, index
, NULL
, 0);
650 /* Schedule a target for deletion */
651 int lov_del_target(struct obd_device
*obd
, __u32 index
,
652 struct obd_uuid
*uuidp
, int gen
)
654 struct lov_obd
*lov
= &obd
->u
.lov
;
655 int count
= lov
->desc
.ld_tgt_count
;
658 if (index
>= count
) {
659 CERROR("LOV target index %d >= number of LOV OBDs %d.\n",
664 /* to make sure there's no ongoing lov_notify() now */
665 down_write(&lov
->lov_notify_lock
);
668 if (!lov
->lov_tgts
[index
]) {
669 CERROR("LOV target at index %d is not setup.\n", index
);
670 GOTO(out
, rc
= -EINVAL
);
673 if (uuidp
&& !obd_uuid_equals(uuidp
, &lov
->lov_tgts
[index
]->ltd_uuid
)) {
674 CERROR("LOV target UUID %s at index %d doesn't match %s.\n",
675 lov_uuid2str(lov
, index
), index
,
676 obd_uuid2str(uuidp
));
677 GOTO(out
, rc
= -EINVAL
);
680 CDEBUG(D_CONFIG
, "uuid: %s idx: %d gen: %d exp: %p active: %d\n",
681 lov_uuid2str(lov
, index
), index
,
682 lov
->lov_tgts
[index
]->ltd_gen
, lov
->lov_tgts
[index
]->ltd_exp
,
683 lov
->lov_tgts
[index
]->ltd_active
);
685 lov
->lov_tgts
[index
]->ltd_reap
= 1;
686 lov
->lov_death_row
++;
687 /* we really delete it from obd_putref */
690 up_write(&lov
->lov_notify_lock
);
695 static void __lov_del_obd(struct obd_device
*obd
, struct lov_tgt_desc
*tgt
)
697 struct obd_device
*osc_obd
;
700 LASSERT(tgt
->ltd_reap
);
702 osc_obd
= class_exp2obd(tgt
->ltd_exp
);
704 CDEBUG(D_CONFIG
, "Removing tgt %s : %s\n",
706 osc_obd
? osc_obd
->obd_name
: "<no obd>");
709 lov_disconnect_obd(obd
, tgt
);
713 /* Manual cleanup - no cleanup logs to clean up the osc's. We must
714 do it ourselves. And we can't do it from lov_cleanup,
715 because we just lost our only reference to it. */
717 class_manual_cleanup(osc_obd
);
720 void lov_fix_desc_stripe_size(__u64
*val
)
722 if (*val
< LOV_MIN_STRIPE_SIZE
) {
724 LCONSOLE_INFO("Increasing default stripe size to "
726 LOV_DESC_STRIPE_SIZE_DEFAULT
);
727 *val
= LOV_DESC_STRIPE_SIZE_DEFAULT
;
728 } else if (*val
& (LOV_MIN_STRIPE_SIZE
- 1)) {
729 *val
&= ~(LOV_MIN_STRIPE_SIZE
- 1);
730 LCONSOLE_WARN("Changing default stripe size to %llu (a multiple of %u)\n",
731 *val
, LOV_MIN_STRIPE_SIZE
);
735 void lov_fix_desc_stripe_count(__u32
*val
)
741 void lov_fix_desc_pattern(__u32
*val
)
743 /* from lov_setstripe */
744 if ((*val
!= 0) && (*val
!= LOV_PATTERN_RAID0
)) {
745 LCONSOLE_WARN("Unknown stripe pattern: %#x\n", *val
);
750 void lov_fix_desc_qos_maxage(__u32
*val
)
753 *val
= LOV_DESC_QOS_MAXAGE_DEFAULT
;
756 void lov_fix_desc(struct lov_desc
*desc
)
758 lov_fix_desc_stripe_size(&desc
->ld_default_stripe_size
);
759 lov_fix_desc_stripe_count(&desc
->ld_default_stripe_count
);
760 lov_fix_desc_pattern(&desc
->ld_pattern
);
761 lov_fix_desc_qos_maxage(&desc
->ld_qos_maxage
);
764 int lov_setup(struct obd_device
*obd
, struct lustre_cfg
*lcfg
)
766 struct lprocfs_static_vars lvars
= { NULL
};
767 struct lov_desc
*desc
;
768 struct lov_obd
*lov
= &obd
->u
.lov
;
771 if (LUSTRE_CFG_BUFLEN(lcfg
, 1) < 1) {
772 CERROR("LOV setup requires a descriptor\n");
776 desc
= (struct lov_desc
*)lustre_cfg_buf(lcfg
, 1);
778 if (sizeof(*desc
) > LUSTRE_CFG_BUFLEN(lcfg
, 1)) {
779 CERROR("descriptor size wrong: %d > %d\n",
780 (int)sizeof(*desc
), LUSTRE_CFG_BUFLEN(lcfg
, 1));
784 if (desc
->ld_magic
!= LOV_DESC_MAGIC
) {
785 if (desc
->ld_magic
== __swab32(LOV_DESC_MAGIC
)) {
786 CDEBUG(D_OTHER
, "%s: Swabbing lov desc %p\n",
787 obd
->obd_name
, desc
);
788 lustre_swab_lov_desc(desc
);
790 CERROR("%s: Bad lov desc magic: %#x\n",
791 obd
->obd_name
, desc
->ld_magic
);
798 desc
->ld_active_tgt_count
= 0;
800 lov
->lov_tgt_size
= 0;
802 mutex_init(&lov
->lov_lock
);
803 atomic_set(&lov
->lov_refcount
, 0);
804 lov
->lov_sp_me
= LUSTRE_SP_CLI
;
806 init_rwsem(&lov
->lov_notify_lock
);
808 lov
->lov_pools_hash_body
= cfs_hash_create("POOLS", HASH_POOLS_CUR_BITS
,
810 HASH_POOLS_BKT_BITS
, 0,
813 &pool_hash_operations
,
815 INIT_LIST_HEAD(&lov
->lov_pool_list
);
816 lov
->lov_pool_count
= 0;
817 rc
= lov_ost_pool_init(&lov
->lov_packed
, 0);
821 lprocfs_lov_init_vars(&lvars
);
822 lprocfs_obd_setup(obd
, lvars
.obd_vars
);
827 rc1
= lprocfs_seq_create(obd
->obd_proc_entry
, "target_obd",
828 0444, &lov_proc_target_fops
, obd
);
830 CWARN("Error adding the target_obd file\n");
833 lov
->lov_pool_proc_entry
= lprocfs_register("pools",
843 static int lov_precleanup(struct obd_device
*obd
, enum obd_cleanup_stage stage
)
846 struct lov_obd
*lov
= &obd
->u
.lov
;
849 case OBD_CLEANUP_EARLY
: {
851 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
852 if (!lov
->lov_tgts
[i
] || !lov
->lov_tgts
[i
]->ltd_active
)
854 obd_precleanup(class_exp2obd(lov
->lov_tgts
[i
]->ltd_exp
),
866 static int lov_cleanup(struct obd_device
*obd
)
868 struct lov_obd
*lov
= &obd
->u
.lov
;
869 struct list_head
*pos
, *tmp
;
870 struct pool_desc
*pool
;
872 list_for_each_safe(pos
, tmp
, &lov
->lov_pool_list
) {
873 pool
= list_entry(pos
, struct pool_desc
, pool_list
);
874 /* free pool structs */
875 CDEBUG(D_INFO
, "delete pool %p\n", pool
);
876 /* In the function below, .hs_keycmp resolves to
877 * pool_hashkey_keycmp() */
878 /* coverity[overrun-buffer-val] */
879 lov_pool_del(obd
, pool
->pool_name
);
881 cfs_hash_putref(lov
->lov_pools_hash_body
);
882 lov_ost_pool_free(&lov
->lov_packed
);
884 lprocfs_obd_cleanup(obd
);
888 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
889 if (!lov
->lov_tgts
[i
])
892 /* Inactive targets may never have connected */
893 if (lov
->lov_tgts
[i
]->ltd_active
||
894 atomic_read(&lov
->lov_refcount
))
895 /* We should never get here - these
896 should have been removed in the
898 CERROR("lov tgt %d not cleaned!"
899 " deathrow=%d, lovrc=%d\n",
900 i
, lov
->lov_death_row
,
901 atomic_read(&lov
->lov_refcount
));
902 lov_del_target(obd
, i
, 0, 0);
905 OBD_FREE(lov
->lov_tgts
, sizeof(*lov
->lov_tgts
) *
907 lov
->lov_tgt_size
= 0;
912 int lov_process_config_base(struct obd_device
*obd
, struct lustre_cfg
*lcfg
,
913 __u32
*indexp
, int *genp
)
915 struct obd_uuid obd_uuid
;
919 switch (cmd
= lcfg
->lcfg_command
) {
920 case LCFG_LOV_ADD_OBD
:
921 case LCFG_LOV_ADD_INA
:
922 case LCFG_LOV_DEL_OBD
: {
925 /* lov_modify_tgts add 0:lov_mdsA 1:ost1_UUID 2:0 3:1 */
926 if (LUSTRE_CFG_BUFLEN(lcfg
, 1) > sizeof(obd_uuid
.uuid
))
927 GOTO(out
, rc
= -EINVAL
);
929 obd_str2uuid(&obd_uuid
, lustre_cfg_buf(lcfg
, 1));
931 if (sscanf(lustre_cfg_buf(lcfg
, 2), "%d", indexp
) != 1)
932 GOTO(out
, rc
= -EINVAL
);
933 if (sscanf(lustre_cfg_buf(lcfg
, 3), "%d", genp
) != 1)
934 GOTO(out
, rc
= -EINVAL
);
937 if (cmd
== LCFG_LOV_ADD_OBD
)
938 rc
= lov_add_target(obd
, &obd_uuid
, index
, gen
, 1);
939 else if (cmd
== LCFG_LOV_ADD_INA
)
940 rc
= lov_add_target(obd
, &obd_uuid
, index
, gen
, 0);
942 rc
= lov_del_target(obd
, index
, &obd_uuid
, gen
);
946 struct lprocfs_static_vars lvars
= { 0 };
947 struct lov_desc
*desc
= &(obd
->u
.lov
.desc
);
950 GOTO(out
, rc
= -EINVAL
);
952 lprocfs_lov_init_vars(&lvars
);
954 rc
= class_process_proc_param(PARAM_LOV
, lvars
.obd_vars
,
967 CERROR("Unknown command: %d\n", lcfg
->lcfg_command
);
968 GOTO(out
, rc
= -EINVAL
);
976 static int lov_recreate(struct obd_export
*exp
, struct obdo
*src_oa
,
977 struct lov_stripe_md
**ea
, struct obd_trans_info
*oti
)
979 struct lov_stripe_md
*obj_mdp
, *lsm
;
980 struct lov_obd
*lov
= &exp
->exp_obd
->u
.lov
;
984 LASSERT(src_oa
->o_valid
& OBD_MD_FLFLAGS
&&
985 src_oa
->o_flags
& OBD_FL_RECREATE_OBJS
);
987 OBD_ALLOC(obj_mdp
, sizeof(*obj_mdp
));
991 ost_idx
= src_oa
->o_nlink
;
994 GOTO(out
, rc
= -EINVAL
);
995 if (ost_idx
>= lov
->desc
.ld_tgt_count
||
996 !lov
->lov_tgts
[ost_idx
])
997 GOTO(out
, rc
= -EINVAL
);
999 for (i
= 0; i
< lsm
->lsm_stripe_count
; i
++) {
1000 if (lsm
->lsm_oinfo
[i
]->loi_ost_idx
== ost_idx
) {
1001 if (ostid_id(&lsm
->lsm_oinfo
[i
]->loi_oi
) !=
1002 ostid_id(&src_oa
->o_oi
))
1003 GOTO(out
, rc
= -EINVAL
);
1007 if (i
== lsm
->lsm_stripe_count
)
1008 GOTO(out
, rc
= -EINVAL
);
1010 rc
= obd_create(NULL
, lov
->lov_tgts
[ost_idx
]->ltd_exp
,
1011 src_oa
, &obj_mdp
, oti
);
1013 OBD_FREE(obj_mdp
, sizeof(*obj_mdp
));
1017 /* the LOV expects oa->o_id to be set to the LOV object id */
1018 static int lov_create(const struct lu_env
*env
, struct obd_export
*exp
,
1019 struct obdo
*src_oa
, struct lov_stripe_md
**ea
,
1020 struct obd_trans_info
*oti
)
1022 struct lov_obd
*lov
;
1025 LASSERT(ea
!= NULL
);
1029 if ((src_oa
->o_valid
& OBD_MD_FLFLAGS
) &&
1030 src_oa
->o_flags
== OBD_FL_DELORPHAN
) {
1031 /* should be used with LOV anymore */
1035 lov
= &exp
->exp_obd
->u
.lov
;
1036 if (!lov
->desc
.ld_active_tgt_count
)
1039 obd_getref(exp
->exp_obd
);
1040 /* Recreate a specific object id at the given OST index */
1041 if ((src_oa
->o_valid
& OBD_MD_FLFLAGS
) &&
1042 (src_oa
->o_flags
& OBD_FL_RECREATE_OBJS
)) {
1043 rc
= lov_recreate(exp
, src_oa
, ea
, oti
);
1046 obd_putref(exp
->exp_obd
);
1050 #define ASSERT_LSM_MAGIC(lsmp) \
1052 LASSERT((lsmp) != NULL); \
1053 LASSERTF(((lsmp)->lsm_magic == LOV_MAGIC_V1 || \
1054 (lsmp)->lsm_magic == LOV_MAGIC_V3), \
1055 "%p->lsm_magic=%x\n", (lsmp), (lsmp)->lsm_magic); \
1058 static int lov_destroy(const struct lu_env
*env
, struct obd_export
*exp
,
1059 struct obdo
*oa
, struct lov_stripe_md
*lsm
,
1060 struct obd_trans_info
*oti
, struct obd_export
*md_exp
,
1063 struct lov_request_set
*set
;
1064 struct obd_info oinfo
;
1065 struct lov_request
*req
;
1066 struct list_head
*pos
;
1067 struct lov_obd
*lov
;
1068 int rc
= 0, err
= 0;
1070 ASSERT_LSM_MAGIC(lsm
);
1072 if (!exp
|| !exp
->exp_obd
)
1075 if (oa
->o_valid
& OBD_MD_FLCOOKIE
) {
1077 LASSERT(oti
->oti_logcookies
);
1080 lov
= &exp
->exp_obd
->u
.lov
;
1081 obd_getref(exp
->exp_obd
);
1082 rc
= lov_prep_destroy_set(exp
, &oinfo
, oa
, lsm
, oti
, &set
);
1086 list_for_each(pos
, &set
->set_list
) {
1087 req
= list_entry(pos
, struct lov_request
, rq_link
);
1089 if (oa
->o_valid
& OBD_MD_FLCOOKIE
)
1090 oti
->oti_logcookies
= set
->set_cookies
+ req
->rq_stripe
;
1092 err
= obd_destroy(env
, lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1093 req
->rq_oi
.oi_oa
, NULL
, oti
, NULL
, capa
);
1094 err
= lov_update_common_set(set
, req
, err
);
1096 CERROR("%s: destroying objid "DOSTID
" subobj "
1097 DOSTID
" on OST idx %d: rc = %d\n",
1098 exp
->exp_obd
->obd_name
, POSTID(&oa
->o_oi
),
1099 POSTID(&req
->rq_oi
.oi_oa
->o_oi
),
1107 LASSERT(lsm_op_find(lsm
->lsm_magic
) != NULL
);
1108 rc
= lsm_op_find(lsm
->lsm_magic
)->lsm_destroy(lsm
, oa
, md_exp
);
1110 err
= lov_fini_destroy_set(set
);
1112 obd_putref(exp
->exp_obd
);
1113 return rc
? rc
: err
;
1116 static int lov_getattr(const struct lu_env
*env
, struct obd_export
*exp
,
1117 struct obd_info
*oinfo
)
1119 struct lov_request_set
*set
;
1120 struct lov_request
*req
;
1121 struct list_head
*pos
;
1122 struct lov_obd
*lov
;
1123 int err
= 0, rc
= 0;
1126 ASSERT_LSM_MAGIC(oinfo
->oi_md
);
1128 if (!exp
|| !exp
->exp_obd
)
1131 lov
= &exp
->exp_obd
->u
.lov
;
1133 rc
= lov_prep_getattr_set(exp
, oinfo
, &set
);
1137 list_for_each(pos
, &set
->set_list
) {
1138 req
= list_entry(pos
, struct lov_request
, rq_link
);
1140 CDEBUG(D_INFO
, "objid "DOSTID
"[%d] has subobj "DOSTID
" at idx"
1141 " %u\n", POSTID(&oinfo
->oi_oa
->o_oi
), req
->rq_stripe
,
1142 POSTID(&req
->rq_oi
.oi_oa
->o_oi
), req
->rq_idx
);
1144 rc
= obd_getattr(env
, lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1146 err
= lov_update_common_set(set
, req
, rc
);
1148 CERROR("%s: getattr objid "DOSTID
" subobj "
1149 DOSTID
" on OST idx %d: rc = %d\n",
1150 exp
->exp_obd
->obd_name
,
1151 POSTID(&oinfo
->oi_oa
->o_oi
),
1152 POSTID(&req
->rq_oi
.oi_oa
->o_oi
),
1158 rc
= lov_fini_getattr_set(set
);
1164 static int lov_getattr_interpret(struct ptlrpc_request_set
*rqset
,
1167 struct lov_request_set
*lovset
= (struct lov_request_set
*)data
;
1170 /* don't do attribute merge if this async op failed */
1172 atomic_set(&lovset
->set_completes
, 0);
1173 err
= lov_fini_getattr_set(lovset
);
1174 return rc
? rc
: err
;
1177 static int lov_getattr_async(struct obd_export
*exp
, struct obd_info
*oinfo
,
1178 struct ptlrpc_request_set
*rqset
)
1180 struct lov_request_set
*lovset
;
1181 struct lov_obd
*lov
;
1182 struct list_head
*pos
;
1183 struct lov_request
*req
;
1187 ASSERT_LSM_MAGIC(oinfo
->oi_md
);
1189 if (!exp
|| !exp
->exp_obd
)
1192 lov
= &exp
->exp_obd
->u
.lov
;
1194 rc
= lov_prep_getattr_set(exp
, oinfo
, &lovset
);
1198 CDEBUG(D_INFO
, "objid "DOSTID
": %ux%u byte stripes\n",
1199 POSTID(&oinfo
->oi_md
->lsm_oi
), oinfo
->oi_md
->lsm_stripe_count
,
1200 oinfo
->oi_md
->lsm_stripe_size
);
1202 list_for_each(pos
, &lovset
->set_list
) {
1203 req
= list_entry(pos
, struct lov_request
, rq_link
);
1205 CDEBUG(D_INFO
, "objid "DOSTID
"[%d] has subobj "DOSTID
" at idx"
1206 "%u\n", POSTID(&oinfo
->oi_oa
->o_oi
), req
->rq_stripe
,
1207 POSTID(&req
->rq_oi
.oi_oa
->o_oi
), req
->rq_idx
);
1208 rc
= obd_getattr_async(lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1209 &req
->rq_oi
, rqset
);
1211 CERROR("%s: getattr objid "DOSTID
" subobj"
1212 DOSTID
" on OST idx %d: rc = %d\n",
1213 exp
->exp_obd
->obd_name
,
1214 POSTID(&oinfo
->oi_oa
->o_oi
),
1215 POSTID(&req
->rq_oi
.oi_oa
->o_oi
),
1221 if (!list_empty(&rqset
->set_requests
)) {
1223 LASSERT(rqset
->set_interpret
== NULL
);
1224 rqset
->set_interpret
= lov_getattr_interpret
;
1225 rqset
->set_arg
= (void *)lovset
;
1230 atomic_set(&lovset
->set_completes
, 0);
1231 err
= lov_fini_getattr_set(lovset
);
1232 return rc
? rc
: err
;
1235 static int lov_setattr(const struct lu_env
*env
, struct obd_export
*exp
,
1236 struct obd_info
*oinfo
, struct obd_trans_info
*oti
)
1238 struct lov_request_set
*set
;
1239 struct lov_obd
*lov
;
1240 struct list_head
*pos
;
1241 struct lov_request
*req
;
1242 int err
= 0, rc
= 0;
1245 ASSERT_LSM_MAGIC(oinfo
->oi_md
);
1247 if (!exp
|| !exp
->exp_obd
)
1250 /* for now, we only expect the following updates here */
1251 LASSERT(!(oinfo
->oi_oa
->o_valid
& ~(OBD_MD_FLID
| OBD_MD_FLTYPE
|
1252 OBD_MD_FLMODE
| OBD_MD_FLATIME
|
1253 OBD_MD_FLMTIME
| OBD_MD_FLCTIME
|
1254 OBD_MD_FLFLAGS
| OBD_MD_FLSIZE
|
1255 OBD_MD_FLGROUP
| OBD_MD_FLUID
|
1256 OBD_MD_FLGID
| OBD_MD_FLFID
|
1258 lov
= &exp
->exp_obd
->u
.lov
;
1259 rc
= lov_prep_setattr_set(exp
, oinfo
, oti
, &set
);
1263 list_for_each(pos
, &set
->set_list
) {
1264 req
= list_entry(pos
, struct lov_request
, rq_link
);
1266 rc
= obd_setattr(env
, lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1268 err
= lov_update_setattr_set(set
, req
, rc
);
1270 CERROR("%s: setattr objid "DOSTID
" subobj "
1271 DOSTID
" on OST idx %d: rc = %d\n",
1272 exp
->exp_obd
->obd_name
,
1273 POSTID(&set
->set_oi
->oi_oa
->o_oi
),
1274 POSTID(&req
->rq_oi
.oi_oa
->o_oi
), req
->rq_idx
,
1280 err
= lov_fini_setattr_set(set
);
1286 static int lov_setattr_interpret(struct ptlrpc_request_set
*rqset
,
1289 struct lov_request_set
*lovset
= (struct lov_request_set
*)data
;
1293 atomic_set(&lovset
->set_completes
, 0);
1294 err
= lov_fini_setattr_set(lovset
);
1295 return rc
? rc
: err
;
1298 /* If @oti is given, the request goes from MDS and responses from OSTs are not
1299 needed. Otherwise, a client is waiting for responses. */
1300 static int lov_setattr_async(struct obd_export
*exp
, struct obd_info
*oinfo
,
1301 struct obd_trans_info
*oti
,
1302 struct ptlrpc_request_set
*rqset
)
1304 struct lov_request_set
*set
;
1305 struct lov_request
*req
;
1306 struct list_head
*pos
;
1307 struct lov_obd
*lov
;
1311 ASSERT_LSM_MAGIC(oinfo
->oi_md
);
1312 if (oinfo
->oi_oa
->o_valid
& OBD_MD_FLCOOKIE
) {
1314 LASSERT(oti
->oti_logcookies
);
1317 if (!exp
|| !exp
->exp_obd
)
1320 lov
= &exp
->exp_obd
->u
.lov
;
1321 rc
= lov_prep_setattr_set(exp
, oinfo
, oti
, &set
);
1325 CDEBUG(D_INFO
, "objid "DOSTID
": %ux%u byte stripes\n",
1326 POSTID(&oinfo
->oi_md
->lsm_oi
),
1327 oinfo
->oi_md
->lsm_stripe_count
,
1328 oinfo
->oi_md
->lsm_stripe_size
);
1330 list_for_each(pos
, &set
->set_list
) {
1331 req
= list_entry(pos
, struct lov_request
, rq_link
);
1333 if (oinfo
->oi_oa
->o_valid
& OBD_MD_FLCOOKIE
)
1334 oti
->oti_logcookies
= set
->set_cookies
+ req
->rq_stripe
;
1336 CDEBUG(D_INFO
, "objid "DOSTID
"[%d] has subobj "DOSTID
" at idx"
1337 "%u\n", POSTID(&oinfo
->oi_oa
->o_oi
), req
->rq_stripe
,
1338 POSTID(&req
->rq_oi
.oi_oa
->o_oi
), req
->rq_idx
);
1340 rc
= obd_setattr_async(lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1341 &req
->rq_oi
, oti
, rqset
);
1343 CERROR("error: setattr objid "DOSTID
" subobj"
1344 DOSTID
" on OST idx %d: rc = %d\n",
1345 POSTID(&set
->set_oi
->oi_oa
->o_oi
),
1346 POSTID(&req
->rq_oi
.oi_oa
->o_oi
),
1352 /* If we are not waiting for responses on async requests, return. */
1353 if (rc
|| !rqset
|| list_empty(&rqset
->set_requests
)) {
1356 atomic_set(&set
->set_completes
, 0);
1357 err
= lov_fini_setattr_set(set
);
1358 return rc
? rc
: err
;
1361 LASSERT(rqset
->set_interpret
== NULL
);
1362 rqset
->set_interpret
= lov_setattr_interpret
;
1363 rqset
->set_arg
= (void *)set
;
1368 static int lov_punch_interpret(struct ptlrpc_request_set
*rqset
,
1371 struct lov_request_set
*lovset
= (struct lov_request_set
*)data
;
1375 atomic_set(&lovset
->set_completes
, 0);
1376 err
= lov_fini_punch_set(lovset
);
1377 return rc
? rc
: err
;
1380 /* FIXME: maybe we'll just make one node the authoritative attribute node, then
1381 * we can send this 'punch' to just the authoritative node and the nodes
1382 * that the punch will affect. */
1383 static int lov_punch(const struct lu_env
*env
, struct obd_export
*exp
,
1384 struct obd_info
*oinfo
, struct obd_trans_info
*oti
,
1385 struct ptlrpc_request_set
*rqset
)
1387 struct lov_request_set
*set
;
1388 struct lov_obd
*lov
;
1389 struct list_head
*pos
;
1390 struct lov_request
*req
;
1394 ASSERT_LSM_MAGIC(oinfo
->oi_md
);
1396 if (!exp
|| !exp
->exp_obd
)
1399 lov
= &exp
->exp_obd
->u
.lov
;
1400 rc
= lov_prep_punch_set(exp
, oinfo
, oti
, &set
);
1404 list_for_each(pos
, &set
->set_list
) {
1405 req
= list_entry(pos
, struct lov_request
, rq_link
);
1407 rc
= obd_punch(env
, lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1408 &req
->rq_oi
, NULL
, rqset
);
1410 CERROR("%s: punch objid "DOSTID
" subobj "DOSTID
1411 " on OST idx %d: rc = %d\n",
1412 exp
->exp_obd
->obd_name
,
1413 POSTID(&set
->set_oi
->oi_oa
->o_oi
),
1414 POSTID(&req
->rq_oi
.oi_oa
->o_oi
), req
->rq_idx
, rc
);
1419 if (rc
|| list_empty(&rqset
->set_requests
)) {
1421 err
= lov_fini_punch_set(set
);
1422 return rc
? rc
: err
;
1425 LASSERT(rqset
->set_interpret
== NULL
);
1426 rqset
->set_interpret
= lov_punch_interpret
;
1427 rqset
->set_arg
= (void *)set
;
1432 static int lov_sync_interpret(struct ptlrpc_request_set
*rqset
,
1435 struct lov_request_set
*lovset
= data
;
1439 atomic_set(&lovset
->set_completes
, 0);
1440 err
= lov_fini_sync_set(lovset
);
1444 static int lov_sync(const struct lu_env
*env
, struct obd_export
*exp
,
1445 struct obd_info
*oinfo
, obd_off start
, obd_off end
,
1446 struct ptlrpc_request_set
*rqset
)
1448 struct lov_request_set
*set
= NULL
;
1449 struct lov_obd
*lov
;
1450 struct list_head
*pos
;
1451 struct lov_request
*req
;
1454 ASSERT_LSM_MAGIC(oinfo
->oi_md
);
1455 LASSERT(rqset
!= NULL
);
1460 lov
= &exp
->exp_obd
->u
.lov
;
1461 rc
= lov_prep_sync_set(exp
, oinfo
, start
, end
, &set
);
1465 CDEBUG(D_INFO
, "fsync objid "DOSTID
" [%#llx, %#llx]\n",
1466 POSTID(&set
->set_oi
->oi_oa
->o_oi
), start
, end
);
1468 list_for_each(pos
, &set
->set_list
) {
1469 req
= list_entry(pos
, struct lov_request
, rq_link
);
1471 rc
= obd_sync(env
, lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1472 &req
->rq_oi
, req
->rq_oi
.oi_policy
.l_extent
.start
,
1473 req
->rq_oi
.oi_policy
.l_extent
.end
, rqset
);
1475 CERROR("%s: fsync objid "DOSTID
" subobj "DOSTID
1476 " on OST idx %d: rc = %d\n",
1477 exp
->exp_obd
->obd_name
,
1478 POSTID(&set
->set_oi
->oi_oa
->o_oi
),
1479 POSTID(&req
->rq_oi
.oi_oa
->o_oi
), req
->rq_idx
,
1485 /* If we are not waiting for responses on async requests, return. */
1486 if (rc
|| list_empty(&rqset
->set_requests
)) {
1487 int err
= lov_fini_sync_set(set
);
1492 LASSERT(rqset
->set_interpret
== NULL
);
1493 rqset
->set_interpret
= lov_sync_interpret
;
1494 rqset
->set_arg
= (void *)set
;
1499 static int lov_brw_check(struct lov_obd
*lov
, struct obd_info
*lov_oinfo
,
1500 obd_count oa_bufs
, struct brw_page
*pga
)
1502 struct obd_info oinfo
= { { { 0 } } };
1505 oinfo
.oi_oa
= lov_oinfo
->oi_oa
;
1507 /* The caller just wants to know if there's a chance that this
1508 * I/O can succeed */
1509 for (i
= 0; i
< oa_bufs
; i
++) {
1510 int stripe
= lov_stripe_number(lov_oinfo
->oi_md
, pga
[i
].off
);
1511 int ost
= lov_oinfo
->oi_md
->lsm_oinfo
[stripe
]->loi_ost_idx
;
1514 if (!lov_stripe_intersects(lov_oinfo
->oi_md
, i
, pga
[i
].off
,
1515 pga
[i
].off
+ pga
[i
].count
- 1,
1519 if (!lov
->lov_tgts
[ost
] || !lov
->lov_tgts
[ost
]->ltd_active
) {
1520 CDEBUG(D_HA
, "lov idx %d inactive\n", ost
);
1524 rc
= obd_brw(OBD_BRW_CHECK
, lov
->lov_tgts
[ost
]->ltd_exp
, &oinfo
,
1532 static int lov_brw(int cmd
, struct obd_export
*exp
, struct obd_info
*oinfo
,
1533 obd_count oa_bufs
, struct brw_page
*pga
,
1534 struct obd_trans_info
*oti
)
1536 struct lov_request_set
*set
;
1537 struct lov_request
*req
;
1538 struct list_head
*pos
;
1539 struct lov_obd
*lov
= &exp
->exp_obd
->u
.lov
;
1542 ASSERT_LSM_MAGIC(oinfo
->oi_md
);
1544 if (cmd
== OBD_BRW_CHECK
) {
1545 rc
= lov_brw_check(lov
, oinfo
, oa_bufs
, pga
);
1549 rc
= lov_prep_brw_set(exp
, oinfo
, oa_bufs
, pga
, oti
, &set
);
1553 list_for_each(pos
, &set
->set_list
) {
1554 struct obd_export
*sub_exp
;
1555 struct brw_page
*sub_pga
;
1556 req
= list_entry(pos
, struct lov_request
, rq_link
);
1558 sub_exp
= lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
;
1559 sub_pga
= set
->set_pga
+ req
->rq_pgaidx
;
1560 rc
= obd_brw(cmd
, sub_exp
, &req
->rq_oi
, req
->rq_oabufs
,
1564 lov_update_common_set(set
, req
, rc
);
1567 err
= lov_fini_brw_set(set
);
1573 static int lov_enqueue_interpret(struct ptlrpc_request_set
*rqset
,
1576 struct lov_request_set
*lovset
= (struct lov_request_set
*)data
;
1578 rc
= lov_fini_enqueue_set(lovset
, lovset
->set_ei
->ei_mode
, rc
, rqset
);
1582 static int lov_enqueue(struct obd_export
*exp
, struct obd_info
*oinfo
,
1583 struct ldlm_enqueue_info
*einfo
,
1584 struct ptlrpc_request_set
*rqset
)
1586 ldlm_mode_t mode
= einfo
->ei_mode
;
1587 struct lov_request_set
*set
;
1588 struct lov_request
*req
;
1589 struct list_head
*pos
;
1590 struct lov_obd
*lov
;
1594 ASSERT_LSM_MAGIC(oinfo
->oi_md
);
1595 LASSERT(mode
== (mode
& -mode
));
1597 /* we should never be asked to replay a lock this way. */
1598 LASSERT((oinfo
->oi_flags
& LDLM_FL_REPLAY
) == 0);
1600 if (!exp
|| !exp
->exp_obd
)
1603 lov
= &exp
->exp_obd
->u
.lov
;
1604 rc
= lov_prep_enqueue_set(exp
, oinfo
, einfo
, &set
);
1608 list_for_each(pos
, &set
->set_list
) {
1609 req
= list_entry(pos
, struct lov_request
, rq_link
);
1611 rc
= obd_enqueue(lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1612 &req
->rq_oi
, einfo
, rqset
);
1617 if (rqset
&& !list_empty(&rqset
->set_requests
)) {
1619 LASSERT(rqset
->set_interpret
== NULL
);
1620 rqset
->set_interpret
= lov_enqueue_interpret
;
1621 rqset
->set_arg
= (void *)set
;
1625 rc
= lov_fini_enqueue_set(set
, mode
, rc
, rqset
);
1629 static int lov_change_cbdata(struct obd_export
*exp
,
1630 struct lov_stripe_md
*lsm
, ldlm_iterator_t it
,
1633 struct lov_obd
*lov
;
1636 ASSERT_LSM_MAGIC(lsm
);
1638 if (!exp
|| !exp
->exp_obd
)
1641 lov
= &exp
->exp_obd
->u
.lov
;
1642 for (i
= 0; i
< lsm
->lsm_stripe_count
; i
++) {
1643 struct lov_stripe_md submd
;
1644 struct lov_oinfo
*loi
= lsm
->lsm_oinfo
[i
];
1646 if (!lov
->lov_tgts
[loi
->loi_ost_idx
]) {
1647 CDEBUG(D_HA
, "lov idx %d NULL \n", loi
->loi_ost_idx
);
1651 submd
.lsm_oi
= loi
->loi_oi
;
1652 submd
.lsm_stripe_count
= 0;
1653 rc
= obd_change_cbdata(lov
->lov_tgts
[loi
->loi_ost_idx
]->ltd_exp
,
1659 /* find any ldlm lock of the inode in lov
1663 static int lov_find_cbdata(struct obd_export
*exp
,
1664 struct lov_stripe_md
*lsm
, ldlm_iterator_t it
,
1667 struct lov_obd
*lov
;
1670 ASSERT_LSM_MAGIC(lsm
);
1672 if (!exp
|| !exp
->exp_obd
)
1675 lov
= &exp
->exp_obd
->u
.lov
;
1676 for (i
= 0; i
< lsm
->lsm_stripe_count
; i
++) {
1677 struct lov_stripe_md submd
;
1678 struct lov_oinfo
*loi
= lsm
->lsm_oinfo
[i
];
1680 if (!lov
->lov_tgts
[loi
->loi_ost_idx
]) {
1681 CDEBUG(D_HA
, "lov idx %d NULL \n", loi
->loi_ost_idx
);
1684 submd
.lsm_oi
= loi
->loi_oi
;
1685 submd
.lsm_stripe_count
= 0;
1686 rc
= obd_find_cbdata(lov
->lov_tgts
[loi
->loi_ost_idx
]->ltd_exp
,
1694 static int lov_cancel(struct obd_export
*exp
, struct lov_stripe_md
*lsm
,
1695 __u32 mode
, struct lustre_handle
*lockh
)
1697 struct lov_request_set
*set
;
1698 struct obd_info oinfo
;
1699 struct lov_request
*req
;
1700 struct list_head
*pos
;
1701 struct lov_obd
*lov
;
1702 struct lustre_handle
*lov_lockhp
;
1703 int err
= 0, rc
= 0;
1705 ASSERT_LSM_MAGIC(lsm
);
1707 if (!exp
|| !exp
->exp_obd
)
1711 lov
= &exp
->exp_obd
->u
.lov
;
1712 rc
= lov_prep_cancel_set(exp
, &oinfo
, lsm
, mode
, lockh
, &set
);
1716 list_for_each(pos
, &set
->set_list
) {
1717 req
= list_entry(pos
, struct lov_request
, rq_link
);
1718 lov_lockhp
= set
->set_lockh
->llh_handles
+ req
->rq_stripe
;
1720 rc
= obd_cancel(lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1721 req
->rq_oi
.oi_md
, mode
, lov_lockhp
);
1722 rc
= lov_update_common_set(set
, req
, rc
);
1724 CERROR("%s: cancel objid "DOSTID
" subobj "
1725 DOSTID
" on OST idx %d: rc = %d\n",
1726 exp
->exp_obd
->obd_name
, POSTID(&lsm
->lsm_oi
),
1727 POSTID(&req
->rq_oi
.oi_md
->lsm_oi
),
1733 lov_fini_cancel_set(set
);
1737 static int lov_cancel_unused(struct obd_export
*exp
,
1738 struct lov_stripe_md
*lsm
,
1739 ldlm_cancel_flags_t flags
, void *opaque
)
1741 struct lov_obd
*lov
;
1744 if (!exp
|| !exp
->exp_obd
)
1747 lov
= &exp
->exp_obd
->u
.lov
;
1749 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
1751 if (!lov
->lov_tgts
[i
] || !lov
->lov_tgts
[i
]->ltd_exp
)
1754 err
= obd_cancel_unused(lov
->lov_tgts
[i
]->ltd_exp
, NULL
,
1762 ASSERT_LSM_MAGIC(lsm
);
1764 for (i
= 0; i
< lsm
->lsm_stripe_count
; i
++) {
1765 struct lov_stripe_md submd
;
1766 struct lov_oinfo
*loi
= lsm
->lsm_oinfo
[i
];
1767 int idx
= loi
->loi_ost_idx
;
1770 if (!lov
->lov_tgts
[idx
]) {
1771 CDEBUG(D_HA
, "lov idx %d NULL\n", idx
);
1775 if (!lov
->lov_tgts
[idx
]->ltd_active
)
1776 CDEBUG(D_HA
, "lov idx %d inactive\n", idx
);
1778 submd
.lsm_oi
= loi
->loi_oi
;
1779 submd
.lsm_stripe_count
= 0;
1780 err
= obd_cancel_unused(lov
->lov_tgts
[idx
]->ltd_exp
,
1781 &submd
, flags
, opaque
);
1782 if (err
&& lov
->lov_tgts
[idx
]->ltd_active
) {
1783 CERROR("%s: cancel unused objid "DOSTID
1784 " subobj "DOSTID
" on OST idx %d: rc = %d\n",
1785 exp
->exp_obd
->obd_name
, POSTID(&lsm
->lsm_oi
),
1786 POSTID(&loi
->loi_oi
), idx
, err
);
1794 int lov_statfs_interpret(struct ptlrpc_request_set
*rqset
, void *data
, int rc
)
1796 struct lov_request_set
*lovset
= (struct lov_request_set
*)data
;
1800 atomic_set(&lovset
->set_completes
, 0);
1802 err
= lov_fini_statfs_set(lovset
);
1803 return rc
? rc
: err
;
1806 static int lov_statfs_async(struct obd_export
*exp
, struct obd_info
*oinfo
,
1807 __u64 max_age
, struct ptlrpc_request_set
*rqset
)
1809 struct obd_device
*obd
= class_exp2obd(exp
);
1810 struct lov_request_set
*set
;
1811 struct lov_request
*req
;
1812 struct list_head
*pos
;
1813 struct lov_obd
*lov
;
1816 LASSERT(oinfo
!= NULL
);
1817 LASSERT(oinfo
->oi_osfs
!= NULL
);
1820 rc
= lov_prep_statfs_set(obd
, oinfo
, &set
);
1824 list_for_each(pos
, &set
->set_list
) {
1825 req
= list_entry(pos
, struct lov_request
, rq_link
);
1826 rc
= obd_statfs_async(lov
->lov_tgts
[req
->rq_idx
]->ltd_exp
,
1827 &req
->rq_oi
, max_age
, rqset
);
1832 if (rc
|| list_empty(&rqset
->set_requests
)) {
1835 atomic_set(&set
->set_completes
, 0);
1836 err
= lov_fini_statfs_set(set
);
1837 return rc
? rc
: err
;
1840 LASSERT(rqset
->set_interpret
== NULL
);
1841 rqset
->set_interpret
= lov_statfs_interpret
;
1842 rqset
->set_arg
= (void *)set
;
1846 static int lov_statfs(const struct lu_env
*env
, struct obd_export
*exp
,
1847 struct obd_statfs
*osfs
, __u64 max_age
, __u32 flags
)
1849 struct ptlrpc_request_set
*set
= NULL
;
1850 struct obd_info oinfo
= { { { 0 } } };
1853 /* for obdclass we forbid using obd_statfs_rqset, but prefer using async
1854 * statfs requests */
1855 set
= ptlrpc_prep_set();
1859 oinfo
.oi_osfs
= osfs
;
1860 oinfo
.oi_flags
= flags
;
1861 rc
= lov_statfs_async(exp
, &oinfo
, max_age
, set
);
1863 rc
= ptlrpc_set_wait(set
);
1864 ptlrpc_set_destroy(set
);
1869 static int lov_iocontrol(unsigned int cmd
, struct obd_export
*exp
, int len
,
1870 void *karg
, void *uarg
)
1872 struct obd_device
*obddev
= class_exp2obd(exp
);
1873 struct lov_obd
*lov
= &obddev
->u
.lov
;
1874 int i
= 0, rc
= 0, count
= lov
->desc
.ld_tgt_count
;
1875 struct obd_uuid
*uuidp
;
1878 case IOC_OBD_STATFS
: {
1879 struct obd_ioctl_data
*data
= karg
;
1880 struct obd_device
*osc_obd
;
1881 struct obd_statfs stat_buf
= {0};
1885 memcpy(&index
, data
->ioc_inlbuf2
, sizeof(__u32
));
1886 if ((index
>= count
))
1889 if (!lov
->lov_tgts
[index
])
1890 /* Try again with the next index */
1892 if (!lov
->lov_tgts
[index
]->ltd_active
)
1895 osc_obd
= class_exp2obd(lov
->lov_tgts
[index
]->ltd_exp
);
1900 if (copy_to_user(data
->ioc_pbuf2
, obd2cli_tgt(osc_obd
),
1901 min((int) data
->ioc_plen2
,
1902 (int) sizeof(struct obd_uuid
))))
1905 flags
= uarg
? *(__u32
*)uarg
: 0;
1906 /* got statfs data */
1907 rc
= obd_statfs(NULL
, lov
->lov_tgts
[index
]->ltd_exp
, &stat_buf
,
1908 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS
),
1912 if (copy_to_user(data
->ioc_pbuf1
, &stat_buf
,
1913 min((int) data
->ioc_plen1
,
1914 (int) sizeof(stat_buf
))))
1918 case OBD_IOC_LOV_GET_CONFIG
: {
1919 struct obd_ioctl_data
*data
;
1920 struct lov_desc
*desc
;
1925 if (obd_ioctl_getdata(&buf
, &len
, (void *)uarg
))
1928 data
= (struct obd_ioctl_data
*)buf
;
1930 if (sizeof(*desc
) > data
->ioc_inllen1
) {
1931 obd_ioctl_freedata(buf
, len
);
1935 if (sizeof(uuidp
->uuid
) * count
> data
->ioc_inllen2
) {
1936 obd_ioctl_freedata(buf
, len
);
1940 if (sizeof(__u32
) * count
> data
->ioc_inllen3
) {
1941 obd_ioctl_freedata(buf
, len
);
1945 desc
= (struct lov_desc
*)data
->ioc_inlbuf1
;
1946 memcpy(desc
, &(lov
->desc
), sizeof(*desc
));
1948 uuidp
= (struct obd_uuid
*)data
->ioc_inlbuf2
;
1949 genp
= (__u32
*)data
->ioc_inlbuf3
;
1950 /* the uuid will be empty for deleted OSTs */
1951 for (i
= 0; i
< count
; i
++, uuidp
++, genp
++) {
1952 if (!lov
->lov_tgts
[i
])
1954 *uuidp
= lov
->lov_tgts
[i
]->ltd_uuid
;
1955 *genp
= lov
->lov_tgts
[i
]->ltd_gen
;
1958 if (copy_to_user((void *)uarg
, buf
, len
))
1960 obd_ioctl_freedata(buf
, len
);
1963 case LL_IOC_LOV_SETSTRIPE
:
1964 rc
= lov_setstripe(exp
, len
, karg
, uarg
);
1966 case LL_IOC_LOV_GETSTRIPE
:
1967 rc
= lov_getstripe(exp
, karg
, uarg
);
1969 case LL_IOC_LOV_SETEA
:
1970 rc
= lov_setea(exp
, karg
, uarg
);
1972 case OBD_IOC_QUOTACTL
: {
1973 struct if_quotactl
*qctl
= karg
;
1974 struct lov_tgt_desc
*tgt
= NULL
;
1975 struct obd_quotactl
*oqctl
;
1977 if (qctl
->qc_valid
== QC_OSTIDX
) {
1978 if (qctl
->qc_idx
< 0 || count
<= qctl
->qc_idx
)
1981 tgt
= lov
->lov_tgts
[qctl
->qc_idx
];
1982 if (!tgt
|| !tgt
->ltd_exp
)
1984 } else if (qctl
->qc_valid
== QC_UUID
) {
1985 for (i
= 0; i
< count
; i
++) {
1986 tgt
= lov
->lov_tgts
[i
];
1988 !obd_uuid_equals(&tgt
->ltd_uuid
,
1992 if (tgt
->ltd_exp
== NULL
)
2004 LASSERT(tgt
&& tgt
->ltd_exp
);
2005 OBD_ALLOC_PTR(oqctl
);
2009 QCTL_COPY(oqctl
, qctl
);
2010 rc
= obd_quotactl(tgt
->ltd_exp
, oqctl
);
2012 QCTL_COPY(qctl
, oqctl
);
2013 qctl
->qc_valid
= QC_OSTIDX
;
2014 qctl
->obd_uuid
= tgt
->ltd_uuid
;
2016 OBD_FREE_PTR(oqctl
);
2025 for (i
= 0; i
< count
; i
++) {
2027 struct obd_device
*osc_obd
;
2029 /* OST was disconnected */
2030 if (!lov
->lov_tgts
[i
] || !lov
->lov_tgts
[i
]->ltd_exp
)
2033 /* ll_umount_begin() sets force flag but for lov, not
2034 * osc. Let's pass it through */
2035 osc_obd
= class_exp2obd(lov
->lov_tgts
[i
]->ltd_exp
);
2036 osc_obd
->obd_force
= obddev
->obd_force
;
2037 err
= obd_iocontrol(cmd
, lov
->lov_tgts
[i
]->ltd_exp
,
2039 if (err
== -ENODATA
&& cmd
== OBD_IOC_POLL_QUOTACHECK
) {
2042 if (lov
->lov_tgts
[i
]->ltd_active
) {
2043 CDEBUG(err
== -ENOTTY
?
2044 D_IOCTL
: D_WARNING
,
2045 "iocontrol OSC %s on OST "
2046 "idx %d cmd %x: err = %d\n",
2047 lov_uuid2str(lov
, i
),
2064 #define FIEMAP_BUFFER_SIZE 4096
2067 * Non-zero fe_logical indicates that this is a continuation FIEMAP
2068 * call. The local end offset and the device are sent in the first
2069 * fm_extent. This function calculates the stripe number from the index.
2070 * This function returns a stripe_no on which mapping is to be restarted.
2072 * This function returns fm_end_offset which is the in-OST offset at which
2073 * mapping should be restarted. If fm_end_offset=0 is returned then caller
2074 * will re-calculate proper offset in next stripe.
2075 * Note that the first extent is passed to lov_get_info via the value field.
2077 * \param fiemap fiemap request header
2078 * \param lsm striping information for the file
2079 * \param fm_start logical start of mapping
2080 * \param fm_end logical end of mapping
2081 * \param start_stripe starting stripe will be returned in this
2083 obd_size
fiemap_calc_fm_end_offset(struct ll_user_fiemap
*fiemap
,
2084 struct lov_stripe_md
*lsm
, obd_size fm_start
,
2085 obd_size fm_end
, int *start_stripe
)
2087 obd_size local_end
= fiemap
->fm_extents
[0].fe_logical
;
2088 obd_off lun_start
, lun_end
;
2089 obd_size fm_end_offset
;
2090 int stripe_no
= -1, i
;
2092 if (fiemap
->fm_extent_count
== 0 ||
2093 fiemap
->fm_extents
[0].fe_logical
== 0)
2096 /* Find out stripe_no from ost_index saved in the fe_device */
2097 for (i
= 0; i
< lsm
->lsm_stripe_count
; i
++) {
2098 if (lsm
->lsm_oinfo
[i
]->loi_ost_idx
==
2099 fiemap
->fm_extents
[0].fe_device
) {
2104 if (stripe_no
== -1)
2107 /* If we have finished mapping on previous device, shift logical
2108 * offset to start of next device */
2109 if ((lov_stripe_intersects(lsm
, stripe_no
, fm_start
, fm_end
,
2110 &lun_start
, &lun_end
)) != 0 &&
2111 local_end
< lun_end
) {
2112 fm_end_offset
= local_end
;
2113 *start_stripe
= stripe_no
;
2115 /* This is a special value to indicate that caller should
2116 * calculate offset in next stripe. */
2118 *start_stripe
= (stripe_no
+ 1) % lsm
->lsm_stripe_count
;
2121 return fm_end_offset
;
2125 * We calculate on which OST the mapping will end. If the length of mapping
2126 * is greater than (stripe_size * stripe_count) then the last_stripe will
2127 * will be one just before start_stripe. Else we check if the mapping
2128 * intersects each OST and find last_stripe.
2129 * This function returns the last_stripe and also sets the stripe_count
2130 * over which the mapping is spread
2132 * \param lsm striping information for the file
2133 * \param fm_start logical start of mapping
2134 * \param fm_end logical end of mapping
2135 * \param start_stripe starting stripe of the mapping
2136 * \param stripe_count the number of stripes across which to map is returned
2138 * \retval last_stripe return the last stripe of the mapping
2140 int fiemap_calc_last_stripe(struct lov_stripe_md
*lsm
, obd_size fm_start
,
2141 obd_size fm_end
, int start_stripe
,
2145 obd_off obd_start
, obd_end
;
2148 if (fm_end
- fm_start
> lsm
->lsm_stripe_size
* lsm
->lsm_stripe_count
) {
2149 last_stripe
= (start_stripe
< 1 ? lsm
->lsm_stripe_count
- 1 :
2151 *stripe_count
= lsm
->lsm_stripe_count
;
2153 for (j
= 0, i
= start_stripe
; j
< lsm
->lsm_stripe_count
;
2154 i
= (i
+ 1) % lsm
->lsm_stripe_count
, j
++) {
2155 if ((lov_stripe_intersects(lsm
, i
, fm_start
, fm_end
,
2156 &obd_start
, &obd_end
)) == 0)
2160 last_stripe
= (start_stripe
+ j
- 1) %lsm
->lsm_stripe_count
;
2167 * Set fe_device and copy extents from local buffer into main return buffer.
2169 * \param fiemap fiemap request header
2170 * \param lcl_fm_ext array of local fiemap extents to be copied
2171 * \param ost_index OST index to be written into the fm_device field for each
2173 * \param ext_count number of extents to be copied
2174 * \param current_extent where to start copying in main extent array
2176 void fiemap_prepare_and_copy_exts(struct ll_user_fiemap
*fiemap
,
2177 struct ll_fiemap_extent
*lcl_fm_ext
,
2178 int ost_index
, unsigned int ext_count
,
2184 for (ext
= 0; ext
< ext_count
; ext
++) {
2185 lcl_fm_ext
[ext
].fe_device
= ost_index
;
2186 lcl_fm_ext
[ext
].fe_flags
|= FIEMAP_EXTENT_NET
;
2189 /* Copy fm_extent's from fm_local to return buffer */
2190 to
= (char *)fiemap
+ fiemap_count_to_size(current_extent
);
2191 memcpy(to
, lcl_fm_ext
, ext_count
* sizeof(struct ll_fiemap_extent
));
2195 * Break down the FIEMAP request and send appropriate calls to individual OSTs.
2196 * This also handles the restarting of FIEMAP calls in case mapping overflows
2197 * the available number of extents in single call.
2199 static int lov_fiemap(struct lov_obd
*lov
, __u32 keylen
, void *key
,
2200 __u32
*vallen
, void *val
, struct lov_stripe_md
*lsm
)
2202 struct ll_fiemap_info_key
*fm_key
= key
;
2203 struct ll_user_fiemap
*fiemap
= val
;
2204 struct ll_user_fiemap
*fm_local
= NULL
;
2205 struct ll_fiemap_extent
*lcl_fm_ext
;
2207 unsigned int get_num_extents
= 0;
2208 int ost_index
= 0, actual_start_stripe
, start_stripe
;
2209 obd_size fm_start
, fm_end
, fm_length
, fm_end_offset
;
2211 int current_extent
= 0, rc
= 0, i
;
2212 int ost_eof
= 0; /* EOF for object */
2213 int ost_done
= 0; /* done with required mapping for this OST? */
2215 int cur_stripe
= 0, cur_stripe_wrap
= 0, stripe_count
;
2216 unsigned int buffer_size
= FIEMAP_BUFFER_SIZE
;
2218 if (!lsm_has_objects(lsm
))
2221 if (fiemap_count_to_size(fm_key
->fiemap
.fm_extent_count
) < buffer_size
)
2222 buffer_size
= fiemap_count_to_size(fm_key
->fiemap
.fm_extent_count
);
2224 OBD_ALLOC_LARGE(fm_local
, buffer_size
);
2225 if (fm_local
== NULL
)
2226 GOTO(out
, rc
= -ENOMEM
);
2227 lcl_fm_ext
= &fm_local
->fm_extents
[0];
2229 count_local
= fiemap_size_to_count(buffer_size
);
2231 memcpy(fiemap
, &fm_key
->fiemap
, sizeof(*fiemap
));
2232 fm_start
= fiemap
->fm_start
;
2233 fm_length
= fiemap
->fm_length
;
2234 /* Calculate start stripe, last stripe and length of mapping */
2235 actual_start_stripe
= start_stripe
= lov_stripe_number(lsm
, fm_start
);
2236 fm_end
= (fm_length
== ~0ULL ? fm_key
->oa
.o_size
:
2237 fm_start
+ fm_length
- 1);
2238 /* If fm_length != ~0ULL but fm_start+fm_length-1 exceeds file size */
2239 if (fm_end
> fm_key
->oa
.o_size
)
2240 fm_end
= fm_key
->oa
.o_size
;
2242 last_stripe
= fiemap_calc_last_stripe(lsm
, fm_start
, fm_end
,
2243 actual_start_stripe
, &stripe_count
);
2245 fm_end_offset
= fiemap_calc_fm_end_offset(fiemap
, lsm
, fm_start
,
2246 fm_end
, &start_stripe
);
2247 if (fm_end_offset
== -EINVAL
)
2248 GOTO(out
, rc
= -EINVAL
);
2250 if (fiemap_count_to_size(fiemap
->fm_extent_count
) > *vallen
)
2251 fiemap
->fm_extent_count
= fiemap_size_to_count(*vallen
);
2252 if (fiemap
->fm_extent_count
== 0) {
2253 get_num_extents
= 1;
2256 /* Check each stripe */
2257 for (cur_stripe
= start_stripe
, i
= 0; i
< stripe_count
;
2258 i
++, cur_stripe
= (cur_stripe
+ 1) % lsm
->lsm_stripe_count
) {
2259 obd_size req_fm_len
; /* Stores length of required mapping */
2260 obd_size len_mapped_single_call
;
2261 obd_off lun_start
, lun_end
, obd_object_end
;
2262 unsigned int ext_count
;
2264 cur_stripe_wrap
= cur_stripe
;
2266 /* Find out range of mapping on this stripe */
2267 if ((lov_stripe_intersects(lsm
, cur_stripe
, fm_start
, fm_end
,
2268 &lun_start
, &obd_object_end
)) == 0)
2271 /* If this is a continuation FIEMAP call and we are on
2272 * starting stripe then lun_start needs to be set to
2274 if (fm_end_offset
!= 0 && cur_stripe
== start_stripe
)
2275 lun_start
= fm_end_offset
;
2277 if (fm_length
!= ~0ULL) {
2278 /* Handle fm_start + fm_length overflow */
2279 if (fm_start
+ fm_length
< fm_start
)
2280 fm_length
= ~0ULL - fm_start
;
2281 lun_end
= lov_size_to_stripe(lsm
, fm_start
+ fm_length
,
2287 if (lun_start
== lun_end
)
2290 req_fm_len
= obd_object_end
- lun_start
;
2291 fm_local
->fm_length
= 0;
2292 len_mapped_single_call
= 0;
2294 /* If the output buffer is very large and the objects have many
2295 * extents we may need to loop on a single OST repeatedly */
2299 if (get_num_extents
== 0) {
2300 /* Don't get too many extents. */
2301 if (current_extent
+ count_local
>
2302 fiemap
->fm_extent_count
)
2303 count_local
= fiemap
->fm_extent_count
-
2307 lun_start
+= len_mapped_single_call
;
2308 fm_local
->fm_length
= req_fm_len
- len_mapped_single_call
;
2309 req_fm_len
= fm_local
->fm_length
;
2310 fm_local
->fm_extent_count
= count_local
;
2311 fm_local
->fm_mapped_extents
= 0;
2312 fm_local
->fm_flags
= fiemap
->fm_flags
;
2314 fm_key
->oa
.o_oi
= lsm
->lsm_oinfo
[cur_stripe
]->loi_oi
;
2315 ost_index
= lsm
->lsm_oinfo
[cur_stripe
]->loi_ost_idx
;
2317 if (ost_index
< 0 || ost_index
>=lov
->desc
.ld_tgt_count
)
2318 GOTO(out
, rc
= -EINVAL
);
2320 /* If OST is inactive, return extent with UNKNOWN flag */
2321 if (!lov
->lov_tgts
[ost_index
]->ltd_active
) {
2322 fm_local
->fm_flags
|= FIEMAP_EXTENT_LAST
;
2323 fm_local
->fm_mapped_extents
= 1;
2325 lcl_fm_ext
[0].fe_logical
= lun_start
;
2326 lcl_fm_ext
[0].fe_length
= obd_object_end
-
2328 lcl_fm_ext
[0].fe_flags
|= FIEMAP_EXTENT_UNKNOWN
;
2333 fm_local
->fm_start
= lun_start
;
2334 fm_local
->fm_flags
&= ~FIEMAP_FLAG_DEVICE_ORDER
;
2335 memcpy(&fm_key
->fiemap
, fm_local
, sizeof(*fm_local
));
2336 *vallen
=fiemap_count_to_size(fm_local
->fm_extent_count
);
2337 rc
= obd_get_info(NULL
,
2338 lov
->lov_tgts
[ost_index
]->ltd_exp
,
2339 keylen
, key
, vallen
, fm_local
, lsm
);
2344 ext_count
= fm_local
->fm_mapped_extents
;
2345 if (ext_count
== 0) {
2347 /* If last stripe has hole at the end,
2348 * then we need to return */
2349 if (cur_stripe_wrap
== last_stripe
) {
2350 fiemap
->fm_mapped_extents
= 0;
2356 /* If we just need num of extents then go to next device */
2357 if (get_num_extents
) {
2358 current_extent
+= ext_count
;
2362 len_mapped_single_call
= lcl_fm_ext
[ext_count
-1].fe_logical
-
2363 lun_start
+ lcl_fm_ext
[ext_count
- 1].fe_length
;
2365 /* Have we finished mapping on this device? */
2366 if (req_fm_len
<= len_mapped_single_call
)
2369 /* Clear the EXTENT_LAST flag which can be present on
2371 if (lcl_fm_ext
[ext_count
-1].fe_flags
& FIEMAP_EXTENT_LAST
)
2372 lcl_fm_ext
[ext_count
- 1].fe_flags
&=
2373 ~FIEMAP_EXTENT_LAST
;
2375 curr_loc
= lov_stripe_size(lsm
,
2376 lcl_fm_ext
[ext_count
- 1].fe_logical
+
2377 lcl_fm_ext
[ext_count
- 1].fe_length
,
2379 if (curr_loc
>= fm_key
->oa
.o_size
)
2382 fiemap_prepare_and_copy_exts(fiemap
, lcl_fm_ext
,
2383 ost_index
, ext_count
,
2386 current_extent
+= ext_count
;
2388 /* Ran out of available extents? */
2389 if (current_extent
>= fiemap
->fm_extent_count
)
2391 } while (ost_done
== 0 && ost_eof
== 0);
2393 if (cur_stripe_wrap
== last_stripe
)
2398 /* Indicate that we are returning device offsets unless file just has
2400 if (lsm
->lsm_stripe_count
> 1)
2401 fiemap
->fm_flags
|= FIEMAP_FLAG_DEVICE_ORDER
;
2403 if (get_num_extents
)
2404 goto skip_last_device_calc
;
2406 /* Check if we have reached the last stripe and whether mapping for that
2407 * stripe is done. */
2408 if (cur_stripe_wrap
== last_stripe
) {
2409 if (ost_done
|| ost_eof
)
2410 fiemap
->fm_extents
[current_extent
- 1].fe_flags
|=
2414 skip_last_device_calc
:
2415 fiemap
->fm_mapped_extents
= current_extent
;
2418 OBD_FREE_LARGE(fm_local
, buffer_size
);
2422 static int lov_get_info(const struct lu_env
*env
, struct obd_export
*exp
,
2423 __u32 keylen
, void *key
, __u32
*vallen
, void *val
,
2424 struct lov_stripe_md
*lsm
)
2426 struct obd_device
*obddev
= class_exp2obd(exp
);
2427 struct lov_obd
*lov
= &obddev
->u
.lov
;
2430 if (!vallen
|| !val
)
2435 if (KEY_IS(KEY_LOCK_TO_STRIPE
)) {
2438 struct ldlm_lock
*lock
;
2440 struct ldlm_res_id
*res_id
= &data
->lock
->l_resource
->lr_name
;
2441 struct lov_oinfo
*loi
;
2442 __u32
*stripe
= val
;
2444 if (*vallen
< sizeof(*stripe
))
2445 GOTO(out
, rc
= -EFAULT
);
2446 *vallen
= sizeof(*stripe
);
2448 /* XXX This is another one of those bits that will need to
2449 * change if we ever actually support nested LOVs. It uses
2450 * the lock's export to find out which stripe it is. */
2451 /* XXX - it's assumed all the locks for deleted OSTs have
2452 * been cancelled. Also, the export for deleted OSTs will
2453 * be NULL and won't match the lock's export. */
2454 for (i
= 0; i
< lsm
->lsm_stripe_count
; i
++) {
2455 loi
= lsm
->lsm_oinfo
[i
];
2456 if (!lov
->lov_tgts
[loi
->loi_ost_idx
])
2458 if (lov
->lov_tgts
[loi
->loi_ost_idx
]->ltd_exp
==
2459 data
->lock
->l_conn_export
&&
2460 ostid_res_name_eq(&loi
->loi_oi
, res_id
)) {
2465 LDLM_ERROR(data
->lock
, "lock on inode without such object");
2466 dump_lsm(D_ERROR
, lsm
);
2467 GOTO(out
, rc
= -ENXIO
);
2468 } else if (KEY_IS(KEY_LAST_ID
)) {
2469 struct obd_id_info
*info
= val
;
2470 __u32 size
= sizeof(obd_id
);
2471 struct lov_tgt_desc
*tgt
;
2473 LASSERT(*vallen
== sizeof(struct obd_id_info
));
2474 tgt
= lov
->lov_tgts
[info
->idx
];
2476 if (!tgt
|| !tgt
->ltd_active
)
2477 GOTO(out
, rc
= -ESRCH
);
2479 rc
= obd_get_info(env
, tgt
->ltd_exp
, keylen
, key
,
2480 &size
, info
->data
, NULL
);
2482 } else if (KEY_IS(KEY_LOVDESC
)) {
2483 struct lov_desc
*desc_ret
= val
;
2484 *desc_ret
= lov
->desc
;
2487 } else if (KEY_IS(KEY_FIEMAP
)) {
2488 rc
= lov_fiemap(lov
, keylen
, key
, vallen
, val
, lsm
);
2490 } else if (KEY_IS(KEY_CONNECT_FLAG
)) {
2491 struct lov_tgt_desc
*tgt
;
2492 __u64 ost_idx
= *((__u64
*)val
);
2494 LASSERT(*vallen
== sizeof(__u64
));
2495 LASSERT(ost_idx
< lov
->desc
.ld_tgt_count
);
2496 tgt
= lov
->lov_tgts
[ost_idx
];
2498 if (!tgt
|| !tgt
->ltd_exp
)
2499 GOTO(out
, rc
= -ESRCH
);
2501 *((__u64
*)val
) = exp_connect_flags(tgt
->ltd_exp
);
2503 } else if (KEY_IS(KEY_TGT_COUNT
)) {
2504 *((int *)val
) = lov
->desc
.ld_tgt_count
;
2515 static int lov_set_info_async(const struct lu_env
*env
, struct obd_export
*exp
,
2516 obd_count keylen
, void *key
, obd_count vallen
,
2517 void *val
, struct ptlrpc_request_set
*set
)
2519 struct obd_device
*obddev
= class_exp2obd(exp
);
2520 struct lov_obd
*lov
= &obddev
->u
.lov
;
2523 struct lov_tgt_desc
*tgt
;
2524 unsigned incr
, check_uuid
,
2525 do_inactive
, no_set
;
2526 unsigned next_id
= 0, mds_con
= 0, capa
= 0;
2528 incr
= check_uuid
= do_inactive
= no_set
= 0;
2531 set
= ptlrpc_prep_set();
2537 count
= lov
->desc
.ld_tgt_count
;
2539 if (KEY_IS(KEY_NEXT_ID
)) {
2540 count
= vallen
/ sizeof(struct obd_id_info
);
2541 vallen
= sizeof(obd_id
);
2542 incr
= sizeof(struct obd_id_info
);
2545 } else if (KEY_IS(KEY_CHECKSUM
)) {
2547 } else if (KEY_IS(KEY_EVICT_BY_NID
)) {
2548 /* use defaults: do_inactive = incr = 0; */
2549 } else if (KEY_IS(KEY_MDS_CONN
)) {
2551 } else if (KEY_IS(KEY_CAPA_KEY
)) {
2553 } else if (KEY_IS(KEY_CACHE_SET
)) {
2554 LASSERT(lov
->lov_cache
== NULL
);
2555 lov
->lov_cache
= val
;
2559 for (i
= 0; i
< count
; i
++, val
= (char *)val
+ incr
) {
2561 tgt
= lov
->lov_tgts
[((struct obd_id_info
*)val
)->idx
];
2563 tgt
= lov
->lov_tgts
[i
];
2565 /* OST was disconnected */
2566 if (!tgt
|| !tgt
->ltd_exp
)
2569 /* OST is inactive and we don't want inactive OSCs */
2570 if (!tgt
->ltd_active
&& !do_inactive
)
2574 struct mds_group_info
*mgi
;
2576 LASSERT(vallen
== sizeof(*mgi
));
2577 mgi
= (struct mds_group_info
*)val
;
2579 /* Only want a specific OSC */
2580 if (mgi
->uuid
&& !obd_uuid_equals(mgi
->uuid
,
2584 err
= obd_set_info_async(env
, tgt
->ltd_exp
,
2585 keylen
, key
, sizeof(int),
2587 } else if (next_id
) {
2588 err
= obd_set_info_async(env
, tgt
->ltd_exp
,
2589 keylen
, key
, vallen
,
2590 ((struct obd_id_info
*)val
)->data
, set
);
2592 struct mds_capa_info
*info
= (struct mds_capa_info
*)val
;
2594 LASSERT(vallen
== sizeof(*info
));
2596 /* Only want a specific OSC */
2598 !obd_uuid_equals(info
->uuid
, &tgt
->ltd_uuid
))
2601 err
= obd_set_info_async(env
, tgt
->ltd_exp
, keylen
,
2602 key
, sizeof(*info
->capa
),
2605 /* Only want a specific OSC */
2607 !obd_uuid_equals(val
, &tgt
->ltd_uuid
))
2610 err
= obd_set_info_async(env
, tgt
->ltd_exp
,
2611 keylen
, key
, vallen
, val
, set
);
2620 err
= ptlrpc_set_wait(set
);
2623 ptlrpc_set_destroy(set
);
2628 static int lov_extent_calc(struct obd_export
*exp
, struct lov_stripe_md
*lsm
,
2629 int cmd
, __u64
*offset
)
2631 __u32 ssize
= lsm
->lsm_stripe_size
;
2635 lov_do_div64(start
, ssize
);
2636 start
= start
* ssize
;
2638 CDEBUG(D_DLMTRACE
, "offset %llu, stripe %u, start %llu, end %llu\n",
2639 *offset
, ssize
, start
, start
+ ssize
- 1);
2640 if (cmd
== OBD_CALC_STRIPE_END
) {
2641 *offset
= start
+ ssize
- 1;
2642 } else if (cmd
== OBD_CALC_STRIPE_START
) {
2651 void lov_stripe_lock(struct lov_stripe_md
*md
)
2653 LASSERT(md
->lsm_lock_owner
!= current_pid());
2654 spin_lock(&md
->lsm_lock
);
2655 LASSERT(md
->lsm_lock_owner
== 0);
2656 md
->lsm_lock_owner
= current_pid();
2658 EXPORT_SYMBOL(lov_stripe_lock
);
2660 void lov_stripe_unlock(struct lov_stripe_md
*md
)
2662 LASSERT(md
->lsm_lock_owner
== current_pid());
2663 md
->lsm_lock_owner
= 0;
2664 spin_unlock(&md
->lsm_lock
);
2666 EXPORT_SYMBOL(lov_stripe_unlock
);
2668 static int lov_quotactl(struct obd_device
*obd
, struct obd_export
*exp
,
2669 struct obd_quotactl
*oqctl
)
2671 struct lov_obd
*lov
= &obd
->u
.lov
;
2672 struct lov_tgt_desc
*tgt
;
2674 __u64 bhardlimit
= 0;
2677 if (oqctl
->qc_cmd
!= LUSTRE_Q_QUOTAON
&&
2678 oqctl
->qc_cmd
!= LUSTRE_Q_QUOTAOFF
&&
2679 oqctl
->qc_cmd
!= Q_GETOQUOTA
&&
2680 oqctl
->qc_cmd
!= Q_INITQUOTA
&&
2681 oqctl
->qc_cmd
!= LUSTRE_Q_SETQUOTA
&&
2682 oqctl
->qc_cmd
!= Q_FINVALIDATE
) {
2683 CERROR("bad quota opc %x for lov obd", oqctl
->qc_cmd
);
2689 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
2692 tgt
= lov
->lov_tgts
[i
];
2697 if (!tgt
->ltd_active
|| tgt
->ltd_reap
) {
2698 if (oqctl
->qc_cmd
== Q_GETOQUOTA
&&
2699 lov
->lov_tgts
[i
]->ltd_activate
) {
2701 CERROR("ost %d is inactive\n", i
);
2703 CDEBUG(D_HA
, "ost %d is inactive\n", i
);
2708 err
= obd_quotactl(tgt
->ltd_exp
, oqctl
);
2710 if (tgt
->ltd_active
&& !rc
)
2715 if (oqctl
->qc_cmd
== Q_GETOQUOTA
) {
2716 curspace
+= oqctl
->qc_dqblk
.dqb_curspace
;
2717 bhardlimit
+= oqctl
->qc_dqblk
.dqb_bhardlimit
;
2722 if (oqctl
->qc_cmd
== Q_GETOQUOTA
) {
2723 oqctl
->qc_dqblk
.dqb_curspace
= curspace
;
2724 oqctl
->qc_dqblk
.dqb_bhardlimit
= bhardlimit
;
2729 static int lov_quotacheck(struct obd_device
*obd
, struct obd_export
*exp
,
2730 struct obd_quotactl
*oqctl
)
2732 struct lov_obd
*lov
= &obd
->u
.lov
;
2737 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
2738 if (!lov
->lov_tgts
[i
])
2741 /* Skip quota check on the administratively disabled OSTs. */
2742 if (!lov
->lov_tgts
[i
]->ltd_activate
) {
2743 CWARN("lov idx %d was administratively disabled, "
2744 "skip quotacheck on it.\n", i
);
2748 if (!lov
->lov_tgts
[i
]->ltd_active
) {
2749 CERROR("lov idx %d inactive\n", i
);
2755 for (i
= 0; i
< lov
->desc
.ld_tgt_count
; i
++) {
2758 if (!lov
->lov_tgts
[i
] || !lov
->lov_tgts
[i
]->ltd_activate
)
2761 err
= obd_quotacheck(lov
->lov_tgts
[i
]->ltd_exp
, oqctl
);
2772 struct obd_ops lov_obd_ops
= {
2773 .o_owner
= THIS_MODULE
,
2774 .o_setup
= lov_setup
,
2775 .o_precleanup
= lov_precleanup
,
2776 .o_cleanup
= lov_cleanup
,
2777 /*.o_process_config = lov_process_config,*/
2778 .o_connect
= lov_connect
,
2779 .o_disconnect
= lov_disconnect
,
2780 .o_statfs
= lov_statfs
,
2781 .o_statfs_async
= lov_statfs_async
,
2782 .o_packmd
= lov_packmd
,
2783 .o_unpackmd
= lov_unpackmd
,
2784 .o_create
= lov_create
,
2785 .o_destroy
= lov_destroy
,
2786 .o_getattr
= lov_getattr
,
2787 .o_getattr_async
= lov_getattr_async
,
2788 .o_setattr
= lov_setattr
,
2789 .o_setattr_async
= lov_setattr_async
,
2791 .o_merge_lvb
= lov_merge_lvb
,
2792 .o_adjust_kms
= lov_adjust_kms
,
2793 .o_punch
= lov_punch
,
2795 .o_enqueue
= lov_enqueue
,
2796 .o_change_cbdata
= lov_change_cbdata
,
2797 .o_find_cbdata
= lov_find_cbdata
,
2798 .o_cancel
= lov_cancel
,
2799 .o_cancel_unused
= lov_cancel_unused
,
2800 .o_iocontrol
= lov_iocontrol
,
2801 .o_get_info
= lov_get_info
,
2802 .o_set_info_async
= lov_set_info_async
,
2803 .o_extent_calc
= lov_extent_calc
,
2804 .o_notify
= lov_notify
,
2805 .o_pool_new
= lov_pool_new
,
2806 .o_pool_rem
= lov_pool_remove
,
2807 .o_pool_add
= lov_pool_add
,
2808 .o_pool_del
= lov_pool_del
,
2809 .o_getref
= lov_getref
,
2810 .o_putref
= lov_putref
,
2811 .o_quotactl
= lov_quotactl
,
2812 .o_quotacheck
= lov_quotacheck
,
2815 struct kmem_cache
*lov_oinfo_slab
;
2817 int __init
lov_init(void)
2819 struct lprocfs_static_vars lvars
= { 0 };
2822 /* print an address of _any_ initialized kernel symbol from this
2823 * module, to allow debugging with gdb that doesn't support data
2824 * symbols from modules.*/
2825 CDEBUG(D_INFO
, "Lustre LOV module (%p).\n", &lov_caches
);
2827 rc
= lu_kmem_init(lov_caches
);
2831 lov_oinfo_slab
= kmem_cache_create("lov_oinfo",
2832 sizeof(struct lov_oinfo
),
2833 0, SLAB_HWCACHE_ALIGN
, NULL
);
2834 if (lov_oinfo_slab
== NULL
) {
2835 lu_kmem_fini(lov_caches
);
2838 lprocfs_lov_init_vars(&lvars
);
2840 rc
= class_register_type(&lov_obd_ops
, NULL
, lvars
.module_vars
,
2841 LUSTRE_LOV_NAME
, &lov_device_type
);
2844 kmem_cache_destroy(lov_oinfo_slab
);
2845 lu_kmem_fini(lov_caches
);
2851 static void /*__exit*/ lov_exit(void)
2853 class_unregister_type(LUSTRE_LOV_NAME
);
2854 kmem_cache_destroy(lov_oinfo_slab
);
2856 lu_kmem_fini(lov_caches
);
2859 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
2860 MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver");
2861 MODULE_LICENSE("GPL");
2862 MODULE_VERSION(LUSTRE_VERSION_STRING
);
2864 module_init(lov_init
);
2865 module_exit(lov_exit
);