1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002, 2003 Cluster File Systems, Inc.
5 * Author: Phil Schwan <phil@clusterfs.com>
6 * Peter Braam <braam@clusterfs.com>
7 * Mike Shaver <shaver@clusterfs.com>
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define DEBUG_SUBSYSTEM S_LOV
28 #include <linux/slab.h>
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/random.h>
32 #include <linux/slab.h>
33 #include <asm/div64.h>
35 #include <liblustre.h>
38 #include <linux/obd_support.h>
39 #include <linux/lustre_lib.h>
40 #include <linux/lustre_net.h>
41 #include <linux/lustre_idl.h>
42 #include <linux/lustre_lite.h> /* for LL_IOC_LOV_[GS]ETSTRIPE */
43 #include <linux/lustre_mds.h>
44 #include <linux/obd_class.h>
45 #include <linux/obd_lov.h>
46 #include <linux/lprocfs_status.h>
48 static kmem_cache_t *lov_file_cache;
50 struct lov_file_handles {
51 struct list_head lfh_list;
54 char *lfh_data; /* an array of opaque data saved on behalf of
55 * each osc, FD_OSTDATA_SIZE bytes for each */
58 struct lov_lock_handles {
60 struct lustre_handle llh_handles[0];
63 extern int lov_packmd(struct lustre_handle *conn, struct lov_mds_md **lmm,
64 struct lov_stripe_md *lsm);
65 extern int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsm,
66 struct lov_mds_md *lmm);
67 extern int lov_setstripe(struct lustre_handle *conn,
68 struct lov_stripe_md **lsmp, struct lov_mds_md *lmmu);
69 extern int lov_getstripe(struct lustre_handle *conn, struct lov_mds_md *lmmu,
70 struct lov_stripe_md *lsm);
73 int lov_attach(struct obd_device *dev, obd_count len, void *data)
75 struct lprocfs_static_vars lvars;
77 lprocfs_init_vars(&lvars);
78 return lprocfs_obd_attach(dev, lvars.obd_vars);
81 int lov_detach(struct obd_device *dev)
83 return lprocfs_obd_detach(dev);
86 static int lov_connect(struct lustre_handle *conn, struct obd_device *obd,
87 struct obd_uuid *cluuid, struct recovd_obd *recovd,
88 ptlrpc_recovery_cb_t recover)
90 struct ptlrpc_request *req = NULL;
91 struct lov_obd *lov = &obd->u.lov;
92 struct client_obd *mdc = &lov->mdcobd->u.cli;
93 struct lov_desc *desc = &lov->desc;
94 struct lov_tgt_desc *tgts;
95 struct obd_export *exp;
96 struct lustre_handle mdc_conn;
97 struct obd_uuid lov_mds_uuid = {"LOV_MDS_UUID"};
102 rc = class_connect(conn, obd, cluuid);
106 /* We don't want to actually do the underlying connections more than
107 * once, so keep track. */
109 if (lov->refcount > 1)
112 exp = class_conn2export(conn);
113 spin_lock_init(&exp->exp_lov_data.led_lock);
114 INIT_LIST_HEAD(&exp->exp_lov_data.led_open_head);
116 /* retrieve LOV metadata from MDS */
117 rc = obd_connect(&mdc_conn, lov->mdcobd, &lov_mds_uuid, recovd,recover);
119 CERROR("cannot connect to mdc: rc = %d\n", rc);
123 rc = mdc_getlovinfo(obd, &mdc_conn, &req);
124 rc2 = obd_disconnect(&mdc_conn);
126 CERROR("cannot get lov info %d\n", rc);
131 CERROR("error disconnecting from MDS %d\n", rc2);
132 GOTO(out_conn, rc = rc2);
136 if (req->rq_repmsg->bufcount < 2 ||
137 req->rq_repmsg->buflens[0] < sizeof(*desc)) {
138 CERROR("LOV desc: invalid descriptor returned\n");
139 GOTO(out_conn, rc = -EINVAL);
142 memcpy(desc, lustre_msg_buf(req->rq_repmsg, 0), sizeof(*desc));
143 lov_unpackdesc(desc);
145 if (req->rq_repmsg->buflens[1] <
146 sizeof(desc->ld_uuid.uuid) * desc->ld_tgt_count){
147 CERROR("LOV desc: invalid uuid array returned\n");
148 GOTO(out_conn, rc = -EINVAL);
151 if (memcmp(obd->obd_uuid.uuid, desc->ld_uuid.uuid,
152 sizeof(desc->ld_uuid.uuid))) {
153 CERROR("LOV desc: uuid %s not on mds device (%s)\n",
154 obd->obd_uuid.uuid, desc->ld_uuid.uuid);
155 GOTO(out_conn, rc = -EINVAL);
158 if (desc->ld_tgt_count > 1000) {
159 CERROR("LOV desc: target count > 1000 (%d)\n",
161 GOTO(out_conn, rc = -EINVAL);
164 /* Because of 64-bit divide/mod operations only work with a 32-bit
165 * divisor in a 32-bit kernel, we cannot support a stripe width
166 * of 4GB or larger on 32-bit CPUs.
168 if ((desc->ld_default_stripe_count ?
169 desc->ld_default_stripe_count : desc->ld_tgt_count) *
170 desc->ld_default_stripe_size > ~0UL) {
171 CERROR("LOV: stripe width "LPU64"x%u > %lu on 32-bit system\n",
172 desc->ld_default_stripe_size,
173 desc->ld_default_stripe_count ?
174 desc->ld_default_stripe_count : desc->ld_tgt_count,~0UL);
175 GOTO(out_conn, rc = -EINVAL);
178 lov->bufsize = sizeof(struct lov_tgt_desc) * desc->ld_tgt_count;
179 OBD_ALLOC(lov->tgts, lov->bufsize);
181 CERROR("Out of memory\n");
182 GOTO(out_conn, rc = -ENOMEM);
185 tmp = lustre_msg_buf(req->rq_repmsg, 1);
186 for (i = 0, tgts = lov->tgts; i < desc->ld_tgt_count; i++, tgts++) {
187 struct obd_uuid *uuid = &tgts->uuid;
188 struct obd_device *tgt_obd;
189 struct obd_uuid lov_osc_uuid = { "LOV_OSC_UUID" };
191 obd_str2uuid(uuid, tmp);
192 tgt_obd = client_tgtuuid2obd(uuid);
193 tmp += sizeof(uuid->uuid);
196 CERROR("Target %s not attached\n", uuid->uuid);
197 GOTO(out_disc, rc = -EINVAL);
200 if (!(tgt_obd->obd_flags & OBD_SET_UP)) {
201 CERROR("Target %s not set up\n", uuid->uuid);
202 GOTO(out_disc, rc = -EINVAL);
205 rc = obd_connect(&tgts->conn, tgt_obd, &lov_osc_uuid, recovd,
209 CERROR("Target %s connect error %d\n", uuid->uuid, rc);
213 rc = obd_iocontrol(IOC_OSC_REGISTER_LOV, &tgts->conn,
214 sizeof(struct obd_device *), obd, NULL);
216 CERROR("Target %s REGISTER_LOV error %d\n",
218 obd_disconnect(&tgts->conn);
222 desc->ld_active_tgt_count++;
226 mdc->cl_max_mds_easize = obd_size_wiremd(conn, NULL);
229 ptlrpc_req_finished(req);
234 struct obd_uuid uuid;
236 --desc->ld_active_tgt_count;
238 obd_str2uuid(&uuid, tgts->uuid.uuid);
239 rc2 = obd_disconnect(&tgts->conn);
241 CERROR("error: LOV target %s disconnect on OST idx %d: "
242 "rc = %d\n", uuid.uuid, i, rc2);
244 OBD_FREE(lov->tgts, lov->bufsize);
246 class_disconnect(conn);
250 static int lov_disconnect(struct lustre_handle *conn)
252 struct obd_device *obd = class_conn2obd(conn);
253 struct lov_obd *lov = &obd->u.lov;
254 struct obd_export *exp;
255 struct list_head *p, *n;
261 /* Only disconnect the underlying layers on the final disconnect. */
263 if (lov->refcount != 0)
266 for (i = 0; i < lov->desc.ld_tgt_count; i++) {
267 rc = obd_disconnect(&lov->tgts[i].conn);
269 if (lov->tgts[i].active) {
270 CERROR("Target %s disconnect error %d\n",
271 lov->tgts[i].uuid.uuid, rc);
275 if (lov->tgts[i].active) {
276 lov->desc.ld_active_tgt_count--;
277 lov->tgts[i].active = 0;
280 OBD_FREE(lov->tgts, lov->bufsize);
284 exp = class_conn2export(conn);
285 spin_lock(&exp->exp_lov_data.led_lock);
286 list_for_each_safe(p, n, &exp->exp_lov_data.led_open_head) {
287 /* XXX close these, instead of just discarding them? */
288 struct lov_file_handles *lfh;
289 lfh = list_entry(p, typeof(*lfh), lfh_list);
290 CERROR("discarding open LOV handle %p:"LPX64"\n",
291 lfh, lfh->lfh_cookie);
292 list_del(&lfh->lfh_list);
293 OBD_FREE(lfh->lfh_data, lfh->lfh_count * FD_OSTDATA_SIZE);
294 PORTAL_SLAB_FREE(lfh, lov_file_cache, sizeof(*lfh));
296 spin_unlock(&exp->exp_lov_data.led_lock);
299 rc = class_disconnect(conn);
305 * -EINVAL : UUID can't be found in the LOV's target list
306 * -ENOTCONN: The UUID is found, but the target connection is bad (!)
307 * -EBADF : The UUID is found, but the OBD is the wrong type (!)
308 * -EALREADY: The OSC is already marked (in)active
310 static int lov_set_osc_active(struct lov_obd *lov, struct obd_uuid *uuid,
313 struct obd_device *obd;
314 struct lov_tgt_desc *tgt;
318 CDEBUG(D_INFO, "Searching in lov %p for uuid %s (activate=%d)\n",
319 lov, uuid->uuid, activate);
321 spin_lock(&lov->lov_lock);
322 for (i = 0, tgt = lov->tgts; i < lov->desc.ld_tgt_count; i++, tgt++) {
323 CDEBUG(D_INFO, "lov idx %d is %s conn "LPX64"\n",
324 i, tgt->uuid.uuid, tgt->conn.addr);
325 if (strncmp(uuid->uuid, tgt->uuid.uuid, sizeof(uuid->uuid)) == 0)
329 if (i == lov->desc.ld_tgt_count)
330 GOTO(out, rc = -EINVAL);
332 obd = class_conn2obd(&tgt->conn);
335 GOTO(out, rc = -ENOTCONN);
338 CDEBUG(D_INFO, "Found OBD %s=%s device %d (%p) type %s at LOV idx %d\n",
339 obd->obd_name, obd->obd_uuid.uuid, obd->obd_minor, obd,
340 obd->obd_type->typ_name, i);
341 if (strcmp(obd->obd_type->typ_name, "osc") != 0) {
343 GOTO(out, rc = -EBADF);
346 if (tgt->active == activate) {
347 CDEBUG(D_INFO, "OBD %p already %sactive!\n", obd,
348 activate ? "" : "in");
349 GOTO(out, rc = -EALREADY);
352 CDEBUG(D_INFO, "Marking OBD %p %sactive\n", obd, activate ? "" : "in");
354 tgt->active = activate;
359 * if (file_handle uses this_osc)
360 * if (has_no_filehandle)
361 * open(file_handle, this_osc);
364 lov->desc.ld_active_tgt_count++;
367 * Should I invalidate filehandles that refer to this OSC, so
368 * that I reopen them during reactivation?
370 /* XXX disconnect from OSC? */
371 lov->desc.ld_active_tgt_count--;
374 #warning "FIXME: walk open files list for objects that need opening"
377 spin_unlock(&lov->lov_lock);
381 static int lov_setup(struct obd_device *obd, obd_count len, void *buf)
383 struct obd_ioctl_data *data = buf;
384 struct lov_obd *lov = &obd->u.lov;
385 struct obd_uuid uuid;
389 if (data->ioc_inllen1 < 1) {
390 CERROR("LOV setup requires an MDC UUID\n");
394 if (data->ioc_inllen1 > 37) {
395 CERROR("mdc UUID must be 36 characters or less\n");
399 spin_lock_init(&lov->lov_lock);
400 obd_str2uuid(&uuid, data->ioc_inlbuf1);
401 lov->mdcobd = class_uuid2obd(&uuid);
403 CERROR("LOV %s cannot locate MDC %s\n", obd->obd_uuid.uuid,
410 static struct lov_file_handles *lov_handle2lfh(struct lustre_handle *handle)
412 struct lov_file_handles *lfh = NULL;
414 if (!handle || !handle->addr)
417 lfh = (struct lov_file_handles *)(unsigned long)(handle->addr);
418 if (!kmem_cache_validate(lov_file_cache, lfh))
421 if (lfh->lfh_cookie != handle->cookie)
427 /* the LOV expects oa->o_id to be set to the LOV object id */
428 static int lov_create(struct lustre_handle *conn, struct obdo *oa,
429 struct lov_stripe_md **ea, struct obd_trans_info *oti)
431 struct obd_export *export = class_conn2export(conn);
433 struct lov_stripe_md *lsm;
434 struct lov_oinfo *loi;
436 int ost_count, ost_idx;
437 int first = 1, obj_alloc = 0;
446 lov = &export->exp_obd->u.lov;
448 if (!lov->desc.ld_active_tgt_count)
458 rc = obd_alloc_memmd(conn, &lsm);
463 lsm->lsm_magic = LOV_MAGIC;
466 ost_count = lov->desc.ld_tgt_count;
468 LASSERT(oa->o_valid & OBD_MD_FLID);
469 lsm->lsm_object_id = oa->o_id;
470 if (!lsm->lsm_stripe_size)
471 lsm->lsm_stripe_size = lov->desc.ld_default_stripe_size;
473 if (!*ea || lsm->lsm_stripe_offset >= ost_count) {
474 int mult = lsm->lsm_object_id * lsm->lsm_stripe_count;
475 int stripe_offset = mult % ost_count;
476 int sub_offset = (mult / ost_count);
478 ost_idx = (stripe_offset + sub_offset) % ost_count;
480 ost_idx = lsm->lsm_stripe_offset;
482 CDEBUG(D_INODE, "allocating %d subobjs for objid "LPX64" at idx %d\n",
483 lsm->lsm_stripe_count, lsm->lsm_object_id, ost_idx);
485 loi = lsm->lsm_oinfo;
486 for (i = 0; i < ost_count; i++, ost_idx = (ost_idx + 1) % ost_count) {
487 struct lov_stripe_md obj_md;
488 struct lov_stripe_md *obj_mdp = &obj_md;
491 if (lov->tgts[ost_idx].active == 0) {
492 CDEBUG(D_HA, "lov idx %d inactive\n", ost_idx);
496 /* create data objects with "parent" OA */
497 memcpy(tmp, oa, sizeof(*tmp));
498 /* XXX: LOV STACKING: use real "obj_mdp" sub-data */
499 err = obd_create(&lov->tgts[ost_idx].conn, tmp, &obj_mdp, oti);
501 if (lov->tgts[ost_idx].active) {
502 CERROR("error creating objid "LPX64" sub-object"
503 " on OST idx %d/%d: rc = %d\n", oa->o_id,
504 ost_idx, lsm->lsm_stripe_count, err);
506 CERROR("obd_create returned invalid "
515 loi->loi_id = tmp->o_id;
516 loi->loi_ost_idx = ost_idx;
517 CDEBUG(D_INODE, "objid "LPX64" has subobj "LPX64" at idx %d\n",
518 lsm->lsm_object_id, loi->loi_id, ost_idx);
521 lsm->lsm_stripe_offset = ost_idx;
528 /* If we have allocated enough objects, we are OK */
529 if (obj_alloc == lsm->lsm_stripe_count) {
536 GOTO(out_cleanup, rc);
538 struct lov_stripe_md *lsm_new;
539 /* XXX LOV STACKING call into osc for sizes */
540 int size = lov_stripe_md_size(obj_alloc);
542 OBD_ALLOC(lsm_new, size);
544 GOTO(out_cleanup, rc = -ENOMEM);
545 memcpy(lsm_new, lsm, size);
546 lsm_new->lsm_stripe_count = obj_alloc;
548 /* XXX LOV STACKING call into osc for sizes */
549 OBD_FREE(lsm, lov_stripe_md_size(lsm->lsm_stripe_count));
560 while (obj_alloc-- > 0) {
564 /* destroy already created objects here */
565 memcpy(tmp, oa, sizeof(*tmp));
566 tmp->o_id = loi->loi_id;
567 err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL, NULL);
569 CERROR("Failed to uncreate objid "LPX64" subobj "
570 LPX64" on OST idx %d: rc = %d\n",
571 oa->o_id, loi->loi_id, loi->loi_ost_idx,
575 obd_free_memmd(conn, &lsm);
579 static int lov_destroy(struct lustre_handle *conn, struct obdo *oa,
580 struct lov_stripe_md *lsm, struct obd_trans_info *oti)
583 struct obd_export *export = class_conn2export(conn);
585 struct lov_oinfo *loi;
586 struct lov_file_handles *lfh = NULL;
591 CERROR("LOV requires striping ea for destruction\n");
595 if (lsm->lsm_magic != LOV_MAGIC) {
596 CERROR("LOV striping magic bad %#x != %#x\n",
597 lsm->lsm_magic, LOV_MAGIC);
601 if (!export || !export->exp_obd)
604 if (oa->o_valid & OBD_MD_FLHANDLE)
605 lfh = lov_handle2lfh(obdo_handle(oa));
607 lov = &export->exp_obd->u.lov;
608 for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
610 if (lov->tgts[loi->loi_ost_idx].active == 0) {
611 CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
612 /* Orphan clean up will (someday) fix this up. */
616 memcpy(&tmp, oa, sizeof(tmp));
617 tmp.o_id = loi->loi_id;
619 memcpy(obdo_handle(&tmp),
620 lfh->lfh_data + i * FD_OSTDATA_SIZE,
623 tmp.o_valid &= ~OBD_MD_FLHANDLE;
624 err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, &tmp,
626 if (err && lov->tgts[loi->loi_ost_idx].active) {
627 CERROR("error: destroying objid "LPX64" subobj "
628 LPX64" on OST idx %d\n: rc = %d",
629 oa->o_id, loi->loi_id, loi->loi_ost_idx, err);
637 /* compute object size given "stripeno" and the ost size */
638 static obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size,
641 unsigned long ssize = lsm->lsm_stripe_size;
642 unsigned long swidth = ssize * lsm->lsm_stripe_count;
643 unsigned long stripe_size;
649 /* do_div(a, b) returns a % b, and a = a / b */
650 stripe_size = do_div(ost_size, ssize);
653 lov_size = ost_size * swidth + stripeno * ssize + stripe_size;
655 lov_size = (ost_size - 1) * swidth + (stripeno + 1) * ssize;
660 static void lov_merge_attrs(struct obdo *tgt, struct obdo *src, obd_flag valid,
661 struct lov_stripe_md *lsm, int stripeno, int *set)
664 if (valid & OBD_MD_FLSIZE) {
665 /* this handles sparse files properly */
668 lov_size = lov_stripe_size(lsm, src->o_size, stripeno);
669 if (lov_size > tgt->o_size)
670 tgt->o_size = lov_size;
672 if (valid & OBD_MD_FLBLOCKS)
673 tgt->o_blocks += src->o_blocks;
674 if (valid & OBD_MD_FLCTIME && tgt->o_ctime < src->o_ctime)
675 tgt->o_ctime = src->o_ctime;
676 if (valid & OBD_MD_FLMTIME && tgt->o_mtime < src->o_mtime)
677 tgt->o_mtime = src->o_mtime;
679 obdo_cpy_md(tgt, src, valid);
680 if (valid & OBD_MD_FLSIZE)
681 tgt->o_size = lov_stripe_size(lsm,src->o_size,stripeno);
686 static int lov_getattr(struct lustre_handle *conn, struct obdo *oa,
687 struct lov_stripe_md *lsm)
690 struct obd_export *export = class_conn2export(conn);
692 struct lov_oinfo *loi;
693 struct lov_file_handles *lfh = NULL;
699 CERROR("LOV requires striping ea\n");
703 if (lsm->lsm_magic != LOV_MAGIC) {
704 CERROR("LOV striping magic bad %#x != %#x\n",
705 lsm->lsm_magic, LOV_MAGIC);
709 if (!export || !export->exp_obd)
712 lov = &export->exp_obd->u.lov;
714 if (oa->o_valid & OBD_MD_FLHANDLE)
715 lfh = lov_handle2lfh(obdo_handle(oa));
717 CDEBUG(D_INFO, "objid "LPX64": %ux%u byte stripes\n",
718 lsm->lsm_object_id, lsm->lsm_stripe_count, lsm->lsm_stripe_size);
719 for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
722 if (lov->tgts[loi->loi_ost_idx].active == 0) {
723 CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
727 CDEBUG(D_INFO, "objid "LPX64"[%d] has subobj "LPX64" at idx "
728 "%u\n", oa->o_id, i, loi->loi_id, loi->loi_ost_idx);
729 /* create data objects with "parent" OA */
730 memcpy(&tmp, oa, sizeof(tmp));
731 tmp.o_id = loi->loi_id;
733 memcpy(obdo_handle(&tmp),
734 lfh->lfh_data + i * FD_OSTDATA_SIZE,
737 tmp.o_valid &= ~OBD_MD_FLHANDLE;
739 err = obd_getattr(&lov->tgts[loi->loi_ost_idx].conn, &tmp,NULL);
741 if (lov->tgts[loi->loi_ost_idx].active) {
742 CERROR("error: getattr objid "LPX64" subobj "
743 LPX64" on OST idx %d: rc = %d\n",
744 oa->o_id, loi->loi_id, loi->loi_ost_idx,
749 lov_merge_attrs(oa, &tmp, tmp.o_valid, lsm, i, &set);
753 RETURN(set ? 0 : -EIO);
756 static int lov_setattr(struct lustre_handle *conn, struct obdo *oa,
757 struct lov_stripe_md *lsm, struct obd_trans_info *oti)
760 struct obd_export *export = class_conn2export(conn);
762 struct lov_oinfo *loi;
763 struct lov_file_handles *lfh = NULL;
764 int rc = 0, i, set = 0;
768 CERROR("LOV requires striping ea\n");
772 if (lsm->lsm_magic != LOV_MAGIC) {
773 CERROR("LOV striping magic bad %#x != %#x\n",
774 lsm->lsm_magic, LOV_MAGIC);
778 if (!export || !export->exp_obd)
781 /* size changes should go through punch and not setattr */
782 LASSERT(!(oa->o_valid & OBD_MD_FLSIZE));
784 /* for now, we only expect mtime updates here */
785 LASSERT(!(oa->o_valid & ~(OBD_MD_FLID |OBD_MD_FLTYPE |OBD_MD_FLMTIME)));
791 if (oa->o_valid & OBD_MD_FLHANDLE)
792 lfh = lov_handle2lfh(obdo_handle(oa));
794 lov = &export->exp_obd->u.lov;
795 for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
798 if (lov->tgts[loi->loi_ost_idx].active == 0) {
799 CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
803 obdo_cpy_md(tmp, oa, oa->o_valid);
806 memcpy(obdo_handle(tmp),
807 lfh->lfh_data + i * FD_OSTDATA_SIZE,
810 tmp->o_valid &= ~OBD_MD_FLHANDLE;
812 tmp->o_id = loi->loi_id;
814 err = obd_setattr(&lov->tgts[loi->loi_ost_idx].conn, tmp,
817 if (lov->tgts[loi->loi_ost_idx].active) {
818 CERROR("error: setattr objid "LPX64" subobj "
819 LPX64" on OST idx %d: rc = %d\n",
820 oa->o_id, loi->loi_id, loi->loi_ost_idx,
834 static int lov_open(struct lustre_handle *conn, struct obdo *oa,
835 struct lov_stripe_md *lsm, struct obd_trans_info *oti)
837 struct obdo *tmp; /* on the heap here, on the stack in lov_close? */
838 struct obd_export *export = class_conn2export(conn);
840 struct lov_oinfo *loi;
841 struct lov_file_handles *lfh = NULL;
842 struct lustre_handle *handle;
848 CERROR("LOV requires striping ea for opening\n");
852 if (lsm->lsm_magic != LOV_MAGIC) {
853 CERROR("LOV striping magic bad %#x != %#x\n",
854 lsm->lsm_magic, LOV_MAGIC);
858 if (!export || !export->exp_obd)
865 PORTAL_SLAB_ALLOC(lfh, lov_file_cache, sizeof(*lfh));
867 GOTO(out_tmp, rc = -ENOMEM);
868 OBD_ALLOC(lfh->lfh_data, lsm->lsm_stripe_count * FD_OSTDATA_SIZE);
870 GOTO(out_lfh, rc = -ENOMEM);
872 lov = &export->exp_obd->u.lov;
875 for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
876 if (lov->tgts[loi->loi_ost_idx].active == 0) {
877 CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
881 /* create data objects with "parent" OA */
882 memcpy(tmp, oa, sizeof(*tmp));
883 tmp->o_id = loi->loi_id;
885 rc = obd_open(&lov->tgts[loi->loi_ost_idx].conn, tmp,
888 if (!lov->tgts[loi->loi_ost_idx].active)
890 CERROR("error: open objid "LPX64" subobj "LPX64
891 " on OST idx %d: rc = %d\n",
892 oa->o_id, lsm->lsm_oinfo[i].loi_id,
893 loi->loi_ost_idx, rc);
897 lov_merge_attrs(oa, tmp, tmp->o_valid, lsm, i, &set);
899 if (tmp->o_valid & OBD_MD_FLHANDLE)
900 memcpy(lfh->lfh_data + i * FD_OSTDATA_SIZE,
901 obdo_handle(tmp), FD_OSTDATA_SIZE);
904 handle = obdo_handle(oa);
906 lfh->lfh_count = lsm->lsm_stripe_count;
907 get_random_bytes(&lfh->lfh_cookie, sizeof(lfh->lfh_cookie));
909 handle->addr = (__u64)(unsigned long)lfh;
910 handle->cookie = lfh->lfh_cookie;
911 oa->o_valid |= OBD_MD_FLHANDLE;
912 spin_lock(&export->exp_lov_data.led_lock);
913 list_add(&lfh->lfh_list, &export->exp_lov_data.led_open_head);
914 spin_unlock(&export->exp_lov_data.led_lock);
923 for (i--, loi = &lsm->lsm_oinfo[i]; i >= 0; i--, loi--) {
926 if (lov->tgts[loi->loi_ost_idx].active == 0)
929 memcpy(tmp, oa, sizeof(*tmp));
930 tmp->o_id = loi->loi_id;
931 memcpy(obdo_handle(tmp), lfh->lfh_data + i * FD_OSTDATA_SIZE,
934 err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, tmp,
936 if (err && lov->tgts[loi->loi_ost_idx].active) {
937 CERROR("error: closing objid "LPX64" subobj "LPX64
938 " on OST idx %d after open error: rc=%d\n",
939 oa->o_id, loi->loi_id, loi->loi_ost_idx, err);
943 OBD_FREE(lfh->lfh_data, lsm->lsm_stripe_count * FD_OSTDATA_SIZE);
945 PORTAL_SLAB_FREE(lfh, lov_file_cache, sizeof(*lfh));
949 static int lov_close(struct lustre_handle *conn, struct obdo *oa,
950 struct lov_stripe_md *lsm, struct obd_trans_info *oti)
953 struct obd_export *export = class_conn2export(conn);
955 struct lov_oinfo *loi;
956 struct lov_file_handles *lfh = NULL;
961 CERROR("LOV requires striping ea\n");
965 if (lsm->lsm_magic != LOV_MAGIC) {
966 CERROR("LOV striping magic bad %#x != %#x\n",
967 lsm->lsm_magic, LOV_MAGIC);
971 if (!export || !export->exp_obd)
974 if (oa->o_valid & OBD_MD_FLHANDLE)
975 lfh = lov_handle2lfh(obdo_handle(oa));
977 lov = &export->exp_obd->u.lov;
978 for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
981 if (lov->tgts[loi->loi_ost_idx].active == 0) {
982 CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
986 /* create data objects with "parent" OA */
987 memcpy(&tmp, oa, sizeof(tmp));
988 tmp.o_id = loi->loi_id;
990 memcpy(obdo_handle(&tmp),
991 lfh->lfh_data + i * FD_OSTDATA_SIZE,
994 tmp.o_valid &= ~OBD_MD_FLHANDLE;
996 err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, &tmp,
999 if (lov->tgts[loi->loi_ost_idx].active) {
1000 CERROR("error: close objid "LPX64" subobj "LPX64
1001 " on OST idx %d: rc = %d\n", oa->o_id,
1002 loi->loi_id, loi->loi_ost_idx, err);
1009 spin_lock(&export->exp_lov_data.led_lock);
1010 list_del(&lfh->lfh_list);
1011 spin_unlock(&export->exp_lov_data.led_lock);
1013 OBD_FREE(lfh->lfh_data, lsm->lsm_stripe_count*FD_OSTDATA_SIZE);
1014 PORTAL_SLAB_FREE(lfh, lov_file_cache, sizeof(*lfh));
1021 #define log2(n) ffz(~(n))
1024 #warning FIXME: merge these two functions now that they are nearly the same
1026 /* compute ost offset in stripe "stripeno" corresponding to offset "lov_off" */
1027 static obd_off lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off,
1030 unsigned long ssize = lsm->lsm_stripe_size;
1031 unsigned long swidth = ssize * lsm->lsm_stripe_count;
1032 unsigned long stripe_off, this_stripe;
1034 if (lov_off == OBD_OBJECT_EOF || lov_off == 0)
1037 /* do_div(a, b) returns a % b, and a = a / b */
1038 stripe_off = do_div(lov_off, swidth);
1040 this_stripe = stripeno * ssize;
1041 if (stripe_off <= this_stripe)
1044 stripe_off -= this_stripe;
1046 if (stripe_off > ssize)
1051 return lov_off * ssize + stripe_off;
1054 /* compute which stripe number "lov_off" will be written into */
1055 static int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off)
1057 unsigned long ssize = lsm->lsm_stripe_size;
1058 unsigned long swidth = ssize * lsm->lsm_stripe_count;
1059 unsigned long stripe_off;
1061 stripe_off = do_div(lov_off, swidth);
1063 return stripe_off / ssize;
1067 /* FIXME: maybe we'll just make one node the authoritative attribute node, then
1068 * we can send this 'punch' to just the authoritative node and the nodes
1069 * that the punch will affect. */
1070 static int lov_punch(struct lustre_handle *conn, struct obdo *oa,
1071 struct lov_stripe_md *lsm,
1072 obd_off start, obd_off end, struct obd_trans_info *oti)
1075 struct obd_export *export = class_conn2export(conn);
1076 struct lov_obd *lov;
1077 struct lov_oinfo *loi;
1078 struct lov_file_handles *lfh = NULL;
1083 CERROR("LOV requires striping ea\n");
1087 if (lsm->lsm_magic != LOV_MAGIC) {
1088 CERROR("LOV striping magic bad %#x != %#x\n",
1089 lsm->lsm_magic, LOV_MAGIC);
1093 if (!export || !export->exp_obd)
1096 if (oa->o_valid & OBD_MD_FLHANDLE)
1097 lfh = lov_handle2lfh(obdo_handle(oa));
1099 lov = &export->exp_obd->u.lov;
1100 for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
1101 obd_off starti = lov_stripe_offset(lsm, start, i);
1102 obd_off endi = lov_stripe_offset(lsm, end, i);
1108 /* create data objects with "parent" OA */
1109 memcpy(&tmp, oa, sizeof(tmp));
1110 tmp.o_id = loi->loi_id;
1112 memcpy(obdo_handle(&tmp),
1113 lfh->lfh_data + i * FD_OSTDATA_SIZE,
1116 tmp.o_valid &= ~OBD_MD_FLHANDLE;
1118 err = obd_punch(&lov->tgts[loi->loi_ost_idx].conn, &tmp, NULL,
1119 starti, endi, NULL);
1121 if (lov->tgts[loi->loi_ost_idx].active) {
1122 CERROR("error: punch objid "LPX64" subobj "LPX64
1123 " on OST idx %d: rc = %d\n", oa->o_id,
1124 loi->loi_id, loi->loi_ost_idx, err);
1133 static inline int lov_brw(int cmd, struct lustre_handle *conn,
1134 struct lov_stripe_md *lsm, obd_count oa_bufs,
1135 struct brw_page *pga, struct obd_brw_set *set,
1136 struct obd_trans_info *oti)
1142 struct lov_stripe_md lsm;
1144 } *stripeinfo, *si, *si_last;
1145 struct obd_export *export = class_conn2export(conn);
1146 struct lov_obd *lov;
1147 struct brw_page *ioarr;
1148 struct lov_oinfo *loi;
1149 int rc = 0, i, *where, stripe_count = lsm->lsm_stripe_count;
1153 CERROR("LOV requires striping ea\n");
1157 if (lsm->lsm_magic != LOV_MAGIC) {
1158 CERROR("LOV striping magic bad %#x != %#x\n",
1159 lsm->lsm_magic, LOV_MAGIC);
1163 lov = &export->exp_obd->u.lov;
1165 OBD_ALLOC(stripeinfo, stripe_count * sizeof(*stripeinfo));
1167 GOTO(out_cbdata, rc = -ENOMEM);
1169 OBD_ALLOC(where, sizeof(*where) * oa_bufs);
1171 GOTO(out_sinfo, rc = -ENOMEM);
1173 OBD_ALLOC(ioarr, sizeof(*ioarr) * oa_bufs);
1175 GOTO(out_where, rc = -ENOMEM);
1177 for (i = 0; i < oa_bufs; i++) {
1178 where[i] = lov_stripe_number(lsm, pga[i].off);
1179 stripeinfo[where[i]].bufct++;
1182 for (i = 0, loi = lsm->lsm_oinfo, si_last = si = stripeinfo;
1183 i < stripe_count; i++, loi++, si_last = si, si++) {
1185 si->index = si_last->index + si_last->bufct;
1186 si->lsm.lsm_object_id = loi->loi_id;
1187 si->ost_idx = loi->loi_ost_idx;
1190 for (i = 0; i < oa_bufs; i++) {
1191 int which = where[i];
1194 shift = stripeinfo[which].index + stripeinfo[which].subcount;
1195 LASSERT(shift < oa_bufs);
1196 ioarr[shift] = pga[i];
1197 ioarr[shift].off = lov_stripe_offset(lsm, pga[i].off, which);
1198 stripeinfo[which].subcount++;
1201 for (i = 0, si = stripeinfo; i < stripe_count; i++, si++) {
1202 int shift = si->index;
1205 LASSERT(shift < oa_bufs);
1206 rc = obd_brw(cmd, &lov->tgts[si->ost_idx].conn,
1207 &si->lsm, si->bufct, &ioarr[shift],
1210 GOTO(out_ioarr, rc);
1215 OBD_FREE(ioarr, sizeof(*ioarr) * oa_bufs);
1217 OBD_FREE(where, sizeof(*where) * oa_bufs);
1219 OBD_FREE(stripeinfo, stripe_count * sizeof(*stripeinfo));
1224 static struct lov_lock_handles *lov_newlockh(struct lov_stripe_md *lsm)
1226 struct lov_lock_handles *lov_lockh;
1228 OBD_ALLOC(lov_lockh, sizeof(*lov_lockh) +
1229 sizeof(*lov_lockh->llh_handles) * lsm->lsm_stripe_count);
1233 get_random_bytes(&lov_lockh->llh_cookie, sizeof(lov_lockh->llh_cookie));
1238 /* We are only ever passed local lock handles here, so we do not need to
1239 * validate (and we can't really because these structs are variable sized
1240 * and therefore alloced, and not from a private slab).
1242 * We just check because we can...
1244 static struct lov_lock_handles *lov_h2lovlockh(struct lustre_handle *handle)
1246 struct lov_lock_handles *lov_lockh = NULL;
1248 if (!handle || !handle->addr)
1251 lov_lockh = (struct lov_lock_handles *)(unsigned long)(handle->addr);
1252 if (lov_lockh->llh_cookie != handle->cookie)
1258 static int lov_enqueue(struct lustre_handle *conn, struct lov_stripe_md *lsm,
1259 struct lustre_handle *parent_lock,
1260 __u32 type, void *cookie, int cookielen, __u32 mode,
1261 int *flags, void *cb, void *data, int datalen,
1262 struct lustre_handle *lockh)
1264 struct obd_export *export = class_conn2export(conn);
1265 struct lov_lock_handles *lov_lockh = NULL;
1266 struct lustre_handle *lov_lockhp;
1267 struct lov_obd *lov;
1268 struct lov_oinfo *loi;
1269 struct lov_stripe_md submd;
1270 ldlm_error_t rc = ELDLM_LOCK_MATCHED, err;
1275 CERROR("LOV requires striping ea\n");
1279 if (lsm->lsm_magic != LOV_MAGIC) {
1280 CERROR("LOV striping magic bad %#x != %#x\n",
1281 lsm->lsm_magic, LOV_MAGIC);
1285 /* we should never be asked to replay a lock. */
1287 LASSERT((*flags & LDLM_FL_REPLAY) == 0);
1289 if (!export || !export->exp_obd)
1292 if (lsm->lsm_stripe_count > 1) {
1293 lov_lockh = lov_newlockh(lsm);
1297 lockh->addr = (__u64)(unsigned long)lov_lockh;
1298 lockh->cookie = lov_lockh->llh_cookie;
1299 lov_lockhp = lov_lockh->llh_handles;
1304 lov = &export->exp_obd->u.lov;
1305 for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count;
1306 i++, loi++, lov_lockhp++) {
1307 struct ldlm_extent *extent = (struct ldlm_extent *)cookie;
1308 struct ldlm_extent sub_ext;
1310 if (lov->tgts[loi->loi_ost_idx].active == 0) {
1311 CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
1316 sub_ext.start = lov_stripe_offset(lsm, extent->start, i);
1317 sub_ext.end = lov_stripe_offset(lsm, extent->end, i);
1318 if (sub_ext.start == sub_ext.end /* || !active */)
1321 /* XXX LOV STACKING: submd should be from the subobj */
1322 submd.lsm_object_id = loi->loi_id;
1323 submd.lsm_stripe_count = 0;
1324 /* XXX submd is not fully initialized here */
1326 err = obd_enqueue(&(lov->tgts[loi->loi_ost_idx].conn), &submd,
1327 parent_lock, type, &sub_ext, sizeof(sub_ext),
1328 mode, flags, cb, data, datalen, lov_lockhp);
1330 // XXX add a lock debug statement here
1331 /* return _MATCHED only when all locks matched.. */
1332 if (err == ELDLM_OK) {
1334 } else if (err != ELDLM_LOCK_MATCHED) {
1336 memset(lov_lockhp, 0, sizeof(*lov_lockhp));
1337 if (lov->tgts[loi->loi_ost_idx].active) {
1338 CERROR("error: enqueue objid "LPX64" subobj "
1339 LPX64" on OST idx %d: rc = %d\n",
1340 lsm->lsm_object_id, loi->loi_id,
1341 loi->loi_ost_idx, rc);
1349 while (loi--, lov_lockhp--, i-- > 0) {
1350 struct lov_stripe_md submd;
1353 if (lov_lockhp->cookie == 0 ||
1354 lov->tgts[loi->loi_ost_idx].active == 0)
1357 /* XXX LOV STACKING: submd should be from the subobj */
1358 submd.lsm_object_id = loi->loi_id;
1359 submd.lsm_stripe_count = 0;
1360 err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd,
1362 if (err && lov->tgts[loi->loi_ost_idx].active) {
1363 CERROR("error: cancelling objid "LPX64" on OST "
1364 "idx %d after enqueue error: rc = %d\n",
1365 loi->loi_id, loi->loi_ost_idx, err);
1369 if (lsm->lsm_stripe_count > 1) {
1370 lov_lockh->llh_cookie = DEAD_HANDLE_MAGIC;
1371 OBD_FREE(lov_lockh, sizeof(*lov_lockh) +
1372 sizeof(*lov_lockh->llh_handles) *
1373 lsm->lsm_stripe_count);
1375 lockh->cookie = DEAD_HANDLE_MAGIC;
1380 static int lov_cancel(struct lustre_handle *conn, struct lov_stripe_md *lsm,
1381 __u32 mode, struct lustre_handle *lockh)
1383 struct obd_export *export = class_conn2export(conn);
1384 struct lov_lock_handles *lov_lockh = NULL;
1385 struct lustre_handle *lov_lockhp;
1386 struct lov_obd *lov;
1387 struct lov_oinfo *loi;
1392 CERROR("LOV requires striping ea\n");
1396 if (lsm->lsm_magic != LOV_MAGIC) {
1397 CERROR("LOV striping magic bad %#x != %#x\n",
1398 lsm->lsm_magic, LOV_MAGIC);
1402 if (!export || !export->exp_obd)
1406 if (lsm->lsm_stripe_count > 1) {
1407 lov_lockh = lov_h2lovlockh(lockh);
1409 CERROR("LOV: invalid lov lock handle %p\n", lockh);
1413 lov_lockhp = lov_lockh->llh_handles;
1417 lov = &export->exp_obd->u.lov;
1418 for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count;
1419 i++, loi++, lov_lockhp++) {
1420 struct lov_stripe_md submd;
1423 if (lov_lockhp->cookie == 0) {
1424 CDEBUG(D_HA, "lov idx %d no lock?\n", loi->loi_ost_idx);
1428 /* XXX LOV STACKING: submd should be from the subobj */
1429 submd.lsm_object_id = loi->loi_id;
1430 submd.lsm_stripe_count = 0;
1431 err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd,
1434 if (lov->tgts[loi->loi_ost_idx].active) {
1435 CERROR("error: cancel objid "LPX64" subobj "
1436 LPX64" on OST idx %d: rc = %d\n",
1438 loi->loi_id, loi->loi_ost_idx, err);
1445 if (lsm->lsm_stripe_count > 1) {
1446 lov_lockh->llh_cookie = DEAD_HANDLE_MAGIC;
1447 OBD_FREE(lov_lockh, sizeof(*lov_lockh) +
1448 sizeof(*lov_lockh->llh_handles) *
1449 lsm->lsm_stripe_count);
1451 lockh->cookie = DEAD_HANDLE_MAGIC;
1456 static int lov_cancel_unused(struct lustre_handle *conn,
1457 struct lov_stripe_md *lsm, int flags)
1459 struct obd_export *export = class_conn2export(conn);
1460 struct lov_obd *lov;
1461 struct lov_oinfo *loi;
1466 CERROR("LOV requires striping ea for lock cancellation\n");
1470 if (!export || !export->exp_obd)
1473 lov = &export->exp_obd->u.lov;
1474 for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
1475 struct lov_stripe_md submd;
1478 submd.lsm_object_id = loi->loi_id;
1479 submd.lsm_stripe_count = 0;
1480 err = obd_cancel_unused(&lov->tgts[loi->loi_ost_idx].conn,
1482 if (err && lov->tgts[loi->loi_ost_idx].active) {
1483 CERROR("error: cancel unused objid "LPX64" subobj "LPX64
1484 " on OST idx %d: rc = %d\n", lsm->lsm_object_id,
1485 loi->loi_id, loi->loi_ost_idx, err);
1494 static int lov_statfs(struct lustre_handle *conn, struct obd_statfs *osfs)
1496 struct obd_export *export = class_conn2export(conn);
1497 struct lov_obd *lov;
1498 struct obd_statfs lov_sfs;
1504 if (!export || !export->exp_obd)
1507 lov = &export->exp_obd->u.lov;
1509 /* We only get block data from the OBD */
1510 for (i = 0; i < lov->desc.ld_tgt_count; i++) {
1513 if (!lov->tgts[i].active) {
1514 CDEBUG(D_HA, "lov idx %d inactive\n", i);
1518 err = obd_statfs(&lov->tgts[i].conn, &lov_sfs);
1520 if (lov->tgts[i].active) {
1521 CERROR("error: statfs OSC %s on OST idx %d: "
1523 lov->tgts[i].uuid.uuid, i, err);
1530 memcpy(osfs, &lov_sfs, sizeof(lov_sfs));
1533 osfs->os_bfree += lov_sfs.os_bfree;
1534 osfs->os_bavail += lov_sfs.os_bavail;
1535 osfs->os_blocks += lov_sfs.os_blocks;
1536 /* XXX not sure about this one - depends on policy.
1537 * - could be minimum if we always stripe on all OBDs
1538 * (but that would be wrong for any other policy,
1539 * if one of the OBDs has no more objects left)
1540 * - could be sum if we stripe whole objects
1541 * - could be average, just to give a nice number
1542 * - we just pick first OST and hope it is enough
1543 sfs->f_ffree += lov_sfs.f_ffree;
1552 static int lov_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
1553 void *karg, void *uarg)
1555 struct obd_device *obddev = class_conn2obd(conn);
1556 struct lov_obd *lov = &obddev->u.lov;
1557 int i, count = lov->desc.ld_tgt_count;
1558 struct obd_uuid *uuidp;
1564 case IOC_LOV_SET_OSC_ACTIVE: {
1565 struct obd_ioctl_data *data = karg;
1566 uuidp = (struct obd_uuid *)data->ioc_inlbuf1;
1567 rc = lov_set_osc_active(lov, uuidp, data->ioc_offset);
1570 case OBD_IOC_LOV_GET_CONFIG: {
1571 struct obd_ioctl_data *data = karg;
1572 struct lov_tgt_desc *tgtdesc;
1573 struct lov_desc *desc;
1578 if (obd_ioctl_getdata(&buf, &len, (void *)uarg))
1581 data = (struct obd_ioctl_data *)buf;
1583 if (sizeof(*desc) > data->ioc_inllen1) {
1588 if (sizeof(uuidp->uuid) * count > data->ioc_inllen2) {
1593 desc = (struct lov_desc *)data->ioc_inlbuf1;
1594 memcpy(desc, &(lov->desc), sizeof(*desc));
1596 uuidp = (struct obd_uuid *)data->ioc_inlbuf2;
1597 tgtdesc = lov->tgts;
1598 for (i = 0; i < count; i++, uuidp++, tgtdesc++)
1599 obd_str2uuid(uuidp, tgtdesc->uuid.uuid);
1601 rc = copy_to_user((void *)uarg, buf, len);
1607 case LL_IOC_LOV_SETSTRIPE:
1608 rc = lov_setstripe(conn, karg, uarg);
1610 case LL_IOC_LOV_GETSTRIPE:
1611 rc = lov_getstripe(conn, karg, uarg);
1618 for (i = 0; i < count; i++) {
1621 err = obd_iocontrol(cmd, &lov->tgts[i].conn,
1624 if (lov->tgts[i].active) {
1625 CERROR("error: iocontrol OSC %s on OST"
1626 "idx %d: err = %d\n",
1627 lov->tgts[i].uuid.uuid, i, err);
1642 struct obd_ops lov_obd_ops = {
1643 o_owner: THIS_MODULE,
1644 o_attach: lov_attach,
1645 o_detach: lov_detach,
1647 o_connect: lov_connect,
1648 o_disconnect: lov_disconnect,
1649 o_statfs: lov_statfs,
1650 o_packmd: lov_packmd,
1651 o_unpackmd: lov_unpackmd,
1652 o_create: lov_create,
1653 o_destroy: lov_destroy,
1654 o_getattr: lov_getattr,
1655 o_setattr: lov_setattr,
1660 o_enqueue: lov_enqueue,
1661 o_cancel: lov_cancel,
1662 o_cancel_unused: lov_cancel_unused,
1663 o_iocontrol: lov_iocontrol
1666 int __init lov_init(void)
1668 struct lprocfs_static_vars lvars;
1671 printk(KERN_INFO "Lustre Logical Object Volume driver; "
1672 "info@clusterfs.com\n");
1673 lov_file_cache = kmem_cache_create("ll_lov_file_data",
1674 sizeof(struct lov_file_handles),
1676 if (!lov_file_cache)
1679 lprocfs_init_vars(&lvars);
1680 rc = class_register_type(&lov_obd_ops, lvars.module_vars,
1681 OBD_LOV_DEVICENAME);
1685 static void __exit lov_exit(void)
1687 if (kmem_cache_destroy(lov_file_cache))
1688 CERROR("couldn't free LOV open cache\n");
1689 class_unregister_type(OBD_LOV_DEVICENAME);
1693 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
1694 MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver");
1695 MODULE_LICENSE("GPL");
1697 module_init(lov_init);
1698 module_exit(lov_exit);