X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Flov%2Flov_obd.c;h=61fdb7b6b0a7e747ebac72360624852c1a8c7b52;hp=92a32b7f7ca0e4cabd7c72f47867160b81f564ae;hb=8ea6a840e00e40220ab769ec329e10f0ad190c09;hpb=0dd19e4fcdcdf435840bdb182b112f02658af32d diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 92a32b7..61fdb7b 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -26,7 +26,7 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. */ /* @@ -75,9 +75,9 @@ static void lov_getref(struct obd_device *obd) struct lov_obd *lov = &obd->u.lov; /* nobody gets through here until lov_putref is done */ - mutex_down(&lov->lov_lock); - atomic_inc(&lov->lov_refcount); - mutex_up(&lov->lov_lock); + cfs_mutex_down(&lov->lov_lock); + cfs_atomic_inc(&lov->lov_refcount); + cfs_mutex_up(&lov->lov_lock); return; } @@ -87,9 +87,9 @@ static void lov_putref(struct obd_device *obd) { struct lov_obd *lov = &obd->u.lov; - mutex_down(&lov->lov_lock); + cfs_mutex_down(&lov->lov_lock); /* ok to dec to 0 more than once -- ltd_exp's will be null */ - if (atomic_dec_and_test(&lov->lov_refcount) && lov->lov_death_row) { + if (cfs_atomic_dec_and_test(&lov->lov_refcount) && lov->lov_death_row) { CFS_LIST_HEAD(kill); int i; struct lov_tgt_desc *tgt, *n; @@ -100,7 +100,7 @@ static void lov_putref(struct obd_device *obd) if (!tgt || !tgt->ltd_reap) continue; - list_add(&tgt->ltd_kill, &kill); + cfs_list_add(&tgt->ltd_kill, &kill); /* XXX - right now there is a dependency on ld_tgt_count * being the maximum tgt index for computing the * mds_max_easize. So we can't shrink it. */ @@ -108,20 +108,20 @@ static void lov_putref(struct obd_device *obd) lov->lov_tgts[i] = NULL; lov->lov_death_row--; } - mutex_up(&lov->lov_lock); + cfs_mutex_up(&lov->lov_lock); - list_for_each_entry_safe(tgt, n, &kill, ltd_kill) { - list_del(&tgt->ltd_kill); + cfs_list_for_each_entry_safe(tgt, n, &kill, ltd_kill) { + cfs_list_del(&tgt->ltd_kill); /* Disconnect */ __lov_del_obd(obd, tgt); } } else { - mutex_up(&lov->lov_lock); + cfs_mutex_up(&lov->lov_lock); } } static int lov_set_osc_active(struct obd_device *obd, struct obd_uuid *uuid, - int activate); + enum obd_notify_event ev); static int lov_notify(struct obd_device *obd, struct obd_device *watched, enum obd_notify_event ev, void *data); @@ -131,11 +131,10 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, struct obd_connect_data *data) { struct lov_obd *lov = &obd->u.lov; - struct obd_uuid tgt_uuid; + struct obd_uuid *tgt_uuid; struct obd_device *tgt_obd; static struct obd_uuid lov_osc_uuid = { "LOV_OSC_UUID" }; struct obd_import *imp; - #ifdef __KERNEL__ cfs_proc_dir_entry_t *lov_proc_dir; #endif @@ -145,11 +144,11 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, if (!lov->lov_tgts[index]) RETURN(-EINVAL); - tgt_uuid = lov->lov_tgts[index]->ltd_uuid; + tgt_uuid = &lov->lov_tgts[index]->ltd_uuid; tgt_obd = lov->lov_tgts[index]->ltd_obd; if (!tgt_obd->obd_set_up) { - CERROR("Target %s not set up\n", obd_uuid2str(&tgt_uuid)); + CERROR("Target %s not set up\n", obd_uuid2str(tgt_uuid)); RETURN(-EINVAL); } @@ -174,14 +173,14 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, rc = obd_register_observer(tgt_obd, obd); if (rc) { CERROR("Target %s register_observer error %d\n", - obd_uuid2str(&tgt_uuid), rc); + obd_uuid2str(tgt_uuid), rc); RETURN(rc); } if (imp->imp_invalid) { CERROR("not connecting OSC %s; administratively " - "disabled\n", obd_uuid2str(&tgt_uuid)); + "disabled\n", obd_uuid2str(tgt_uuid)); RETURN(0); } @@ -189,35 +188,35 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, &lov_osc_uuid, data, NULL); if (rc || !lov->lov_tgts[index]->ltd_exp) { CERROR("Target %s connect error %d\n", - obd_uuid2str(&tgt_uuid), rc); + obd_uuid2str(tgt_uuid), rc); RETURN(-ENODEV); } lov->lov_tgts[index]->ltd_reap = 0; CDEBUG(D_CONFIG, "Connected tgt idx %d %s (%s) %sactive\n", index, - obd_uuid2str(&tgt_uuid), tgt_obd->obd_name, activate ? "":"in"); + obd_uuid2str(tgt_uuid), tgt_obd->obd_name, activate ? "":"in"); #ifdef __KERNEL__ lov_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds"); if (lov_proc_dir) { struct obd_device *osc_obd = lov->lov_tgts[index]->ltd_exp->exp_obd; cfs_proc_dir_entry_t *osc_symlink; - char name[MAX_STRING_SIZE]; LASSERT(osc_obd != NULL); LASSERT(osc_obd->obd_magic == OBD_DEVICE_MAGIC); LASSERT(osc_obd->obd_type->typ_name != NULL); - snprintf(name, MAX_STRING_SIZE, "../../../%s/%s", - osc_obd->obd_type->typ_name, - osc_obd->obd_name); - osc_symlink = lprocfs_add_symlink(osc_obd->obd_name, lov_proc_dir, - name); + + osc_symlink = lprocfs_add_symlink(osc_obd->obd_name, + lov_proc_dir, + "../../../%s/%s", + osc_obd->obd_type->typ_name, + osc_obd->obd_name); if (osc_symlink == NULL) { CERROR("could not register LOV target " - "/proc/fs/lustre/%s/%s/target_obds/%s.", - obd->obd_type->typ_name, obd->obd_name, - osc_obd->obd_name); + "/proc/fs/lustre/%s/%s/target_obds/%s.", + obd->obd_type->typ_name, obd->obd_name, + osc_obd->obd_name); lprocfs_remove(&lov_proc_dir); } } @@ -385,15 +384,15 @@ out: * any >= 0 : is log target index */ static int lov_set_osc_active(struct obd_device *obd, struct obd_uuid *uuid, - int activate) + enum obd_notify_event ev) { struct lov_obd *lov = &obd->u.lov; struct lov_tgt_desc *tgt; - int index; + int index, activate, active; ENTRY; - CDEBUG(D_INFO, "Searching in lov %p for uuid %s (activate=%d)\n", - lov, uuid->uuid, activate); + CDEBUG(D_INFO, "Searching in lov %p for uuid %s event(%d)\n", + lov, uuid->uuid, ev); obd_getref(obd); for (index = 0; index < lov->desc.ld_tgt_count; index++) { @@ -411,26 +410,43 @@ static int lov_set_osc_active(struct obd_device *obd, struct obd_uuid *uuid, if (index == lov->desc.ld_tgt_count) GOTO(out, index = -EINVAL); - if (lov->lov_tgts[index]->ltd_active == activate) { - CDEBUG(D_INFO, "OSC %s already %sactive!\n", uuid->uuid, - activate ? "" : "in"); - GOTO(out, index); - } + if (ev == OBD_NOTIFY_DEACTIVATE || ev == OBD_NOTIFY_ACTIVATE) { + activate = (ev == OBD_NOTIFY_ACTIVATE) ? 1 : 0; - CDEBUG(D_CONFIG, "Marking OSC %s %sactive\n", obd_uuid2str(uuid), - activate ? "" : "in"); + if (lov->lov_tgts[index]->ltd_activate == activate) { + CDEBUG(D_INFO, "OSC %s already %sactivate!\n", + uuid->uuid, activate ? "" : "de"); + } else { + lov->lov_tgts[index]->ltd_activate = activate; + CDEBUG(D_CONFIG, "%sactivate OSC %s\n", + activate ? "" : "de", obd_uuid2str(uuid)); + } - lov->lov_tgts[index]->ltd_active = activate; + } else if (ev == OBD_NOTIFY_INACTIVE || ev == OBD_NOTIFY_ACTIVE) { + active = (ev == OBD_NOTIFY_ACTIVE) ? 1 : 0; - if (activate) { - lov->desc.ld_active_tgt_count++; - lov->lov_tgts[index]->ltd_exp->exp_obd->obd_inactive = 0; + if (lov->lov_tgts[index]->ltd_active == active) { + CDEBUG(D_INFO, "OSC %s already %sactive!\n", + uuid->uuid, active ? "" : "in"); + GOTO(out, index); + } else { + CDEBUG(D_CONFIG, "Marking OSC %s %sactive\n", + obd_uuid2str(uuid), active ? "" : "in"); + } + + lov->lov_tgts[index]->ltd_active = active; + if (active) { + lov->desc.ld_active_tgt_count++; + lov->lov_tgts[index]->ltd_exp->exp_obd->obd_inactive = 0; + } else { + lov->desc.ld_active_tgt_count--; + lov->lov_tgts[index]->ltd_exp->exp_obd->obd_inactive = 1; + } + /* remove any old qos penalty */ + lov->lov_tgts[index]->ltd_qos.ltq_penalty = 0; } else { - lov->desc.ld_active_tgt_count--; - lov->lov_tgts[index]->ltd_exp->exp_obd->obd_inactive = 1; + CERROR("Unknown event(%d) for uuid %s", ev, uuid->uuid); } - /* remove any old qos penalty */ - lov->lov_tgts[index]->ltd_qos.ltq_penalty = 0; out: obd_putref(obd); @@ -443,7 +459,8 @@ static int lov_notify(struct obd_device *obd, struct obd_device *watched, int rc = 0; ENTRY; - if (ev == OBD_NOTIFY_ACTIVE || ev == OBD_NOTIFY_INACTIVE) { + if (ev == OBD_NOTIFY_ACTIVE || ev == OBD_NOTIFY_INACTIVE || + ev == OBD_NOTIFY_ACTIVATE || ev == OBD_NOTIFY_DEACTIVATE) { struct obd_uuid *uuid; LASSERT(watched); @@ -459,10 +476,9 @@ static int lov_notify(struct obd_device *obd, struct obd_device *watched, /* Set OSC as active before notifying the observer, so the * observer can use the OSC normally. */ - rc = lov_set_osc_active(obd, uuid, ev == OBD_NOTIFY_ACTIVE); + rc = lov_set_osc_active(obd, uuid, ev); if (rc < 0) { - CERROR("%sactivation of %s failed: %d\n", - (ev == OBD_NOTIFY_ACTIVE) ? "" : "de", + CERROR("event(%d) of %s failed: %d\n", ev, obd_uuid2str(uuid), rc); RETURN(rc); } @@ -477,29 +493,30 @@ static int lov_notify(struct obd_device *obd, struct obd_device *watched, /* NULL watched means all osc's in the lov (only for syncs) */ /* sync event should be send lov idx as data */ struct lov_obd *lov = &obd->u.lov; - struct obd_device *tgt_obd; - int i; + int i, is_sync; + + data = &i; + is_sync = (ev == OBD_NOTIFY_SYNC) || + (ev == OBD_NOTIFY_SYNC_NONBLOCK); + obd_getref(obd); for (i = 0; i < lov->desc.ld_tgt_count; i++) { + if (!lov->lov_tgts[i]) + continue; + /* don't send sync event if target not * connected/activated */ - if (!lov->lov_tgts[i] || - !lov->lov_tgts[i]->ltd_active) - continue; - - if ((ev == OBD_NOTIFY_SYNC) || - (ev == OBD_NOTIFY_SYNC_NONBLOCK)) - data = &i; - - tgt_obd = class_exp2obd(lov->lov_tgts[i]->ltd_exp); + if (is_sync && !lov->lov_tgts[i]->ltd_active) + continue; - rc = obd_notify_observer(obd, tgt_obd, ev, data); + rc = obd_notify_observer(obd, lov->lov_tgts[i]->ltd_obd, + ev, data); if (rc) { CERROR("%s: notify %s of %s failed %d\n", obd->obd_name, obd->obd_observer->obd_name, - tgt_obd->obd_name, rc); - break; + lov->lov_tgts[i]->ltd_obd->obd_name, + rc); } } obd_putref(obd); @@ -508,8 +525,8 @@ static int lov_notify(struct obd_device *obd, struct obd_device *watched, RETURN(rc); } -int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, - __u32 index, int gen, int active) +static int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, + __u32 index, int gen, int active) { struct lov_obd *lov = &obd->u.lov; struct lov_tgt_desc *tgt; @@ -531,13 +548,13 @@ int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, if (tgt_obd == NULL) RETURN(-EINVAL); - mutex_down(&lov->lov_lock); + cfs_mutex_down(&lov->lov_lock); if ((index < lov->lov_tgt_size) && (lov->lov_tgts[index] != NULL)) { tgt = lov->lov_tgts[index]; CERROR("UUID %s already assigned at LOV target index %d\n", obd_uuid2str(&tgt->ltd_uuid), index); - mutex_up(&lov->lov_lock); + cfs_mutex_up(&lov->lov_lock); RETURN(-EEXIST); } @@ -551,7 +568,7 @@ int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, newsize = newsize << 1; OBD_ALLOC(newtgts, sizeof(*newtgts) * newsize); if (newtgts == NULL) { - mutex_up(&lov->lov_lock); + cfs_mutex_up(&lov->lov_lock); RETURN(-ENOMEM); } @@ -576,18 +593,17 @@ int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, OBD_ALLOC_PTR(tgt); if (!tgt) { - mutex_up(&lov->lov_lock); + cfs_mutex_up(&lov->lov_lock); RETURN(-ENOMEM); } rc = lov_ost_pool_add(&lov->lov_packed, index, lov->lov_tgt_size); if (rc) { - mutex_up(&lov->lov_lock); + cfs_mutex_up(&lov->lov_lock); OBD_FREE_PTR(tgt); RETURN(rc); } - memset(tgt, 0, sizeof(*tgt)); tgt->ltd_uuid = *uuidp; tgt->ltd_obd = tgt_obd; /* XXX - add a sanity check on the generation number. */ @@ -598,11 +614,13 @@ int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, if (index >= lov->desc.ld_tgt_count) lov->desc.ld_tgt_count = index + 1; - mutex_up(&lov->lov_lock); + cfs_mutex_up(&lov->lov_lock); CDEBUG(D_CONFIG, "idx=%d ltd_gen=%d ld_tgt_count=%d\n", index, tgt->ltd_gen, lov->desc.ld_tgt_count); + rc = obd_notify(obd, tgt_obd, OBD_NOTIFY_CREATE, &index); + if (lov->lov_connects == 0) { /* lov_connect hasn't been called yet. We'll do the lov_connect_obd on this target when that fn first runs, @@ -785,10 +803,10 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg) lov->desc = *desc; lov->lov_tgt_size = 0; - sema_init(&lov->lov_lock, 1); - atomic_set(&lov->lov_refcount, 0); + cfs_sema_init(&lov->lov_lock, 1); + cfs_atomic_set(&lov->lov_refcount, 0); CFS_INIT_LIST_HEAD(&lov->lov_qos.lq_oss_list); - init_rwsem(&lov->lov_qos.lq_rw_sem); + cfs_init_rwsem(&lov->lov_qos.lq_rw_sem); lov->lov_sp_me = LUSTRE_SP_CLI; lov->lov_qos.lq_dirty = 1; lov->lov_qos.lq_rr.lqr_dirty = 1; @@ -803,20 +821,21 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg) RETURN(-ENOMEM); cfs_waitq_init(&lov->lov_qos.lq_statfs_waitq); - lov->lov_pools_hash_body = lustre_hash_init("POOLS", - HASH_POOLS_CUR_BITS, - HASH_POOLS_MAX_BITS, - &pool_hash_operations, 0); + lov->lov_pools_hash_body = cfs_hash_create("POOLS", HASH_POOLS_CUR_BITS, + HASH_POOLS_MAX_BITS, + HASH_POOLS_BKT_BITS, 0, + CFS_HASH_MIN_THETA, + CFS_HASH_MAX_THETA, + &pool_hash_operations, + CFS_HASH_DEFAULT); CFS_INIT_LIST_HEAD(&lov->lov_pool_list); lov->lov_pool_count = 0; rc = lov_ost_pool_init(&lov->lov_packed, 0); if (rc) - RETURN(rc); + GOTO(out_free_statfs, rc); rc = lov_ost_pool_init(&lov->lov_qos.lq_rr.lqr_pool, 0); - if (rc) { - lov_ost_pool_free(&lov->lov_packed); - RETURN(rc); - } + if (rc) + GOTO(out_free_lov_packed, rc); lprocfs_lov_init_vars(&lvars); lprocfs_obd_setup(obd, lvars.obd_vars); @@ -835,6 +854,12 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg) NULL, NULL); RETURN(0); + +out_free_lov_packed: + lov_ost_pool_free(&lov->lov_packed); +out_free_statfs: + OBD_FREE_PTR(lov->lov_qos.lq_statfs_data); + return rc; } static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) @@ -867,16 +892,16 @@ static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) static int lov_cleanup(struct obd_device *obd) { struct lov_obd *lov = &obd->u.lov; - struct list_head *pos, *tmp; + cfs_list_t *pos, *tmp; struct pool_desc *pool; - list_for_each_safe(pos, tmp, &lov->lov_pool_list) { - pool = list_entry(pos, struct pool_desc, pool_list); + cfs_list_for_each_safe(pos, tmp, &lov->lov_pool_list) { + pool = cfs_list_entry(pos, struct pool_desc, pool_list); /* free pool structs */ CDEBUG(D_INFO, "delete pool %p\n", pool); lov_pool_del(obd, pool->pool_name); } - lustre_hash_exit(lov->lov_pools_hash_body); + cfs_hash_putref(lov->lov_pools_hash_body); lov_ost_pool_free(&(lov->lov_qos.lq_rr.lqr_pool)); lov_ost_pool_free(&lov->lov_packed); @@ -889,14 +914,14 @@ static int lov_cleanup(struct obd_device *obd) /* Inactive targets may never have connected */ if (lov->lov_tgts[i]->ltd_active || - atomic_read(&lov->lov_refcount)) + cfs_atomic_read(&lov->lov_refcount)) /* We should never get here - these should have been removed in the disconnect. */ CERROR("lov tgt %d not cleaned!" " deathrow=%d, lovrc=%d\n", i, lov->lov_death_row, - atomic_read(&lov->lov_refcount)); + cfs_atomic_read(&lov->lov_refcount)); lov_del_target(obd, i, 0, 0); } obd_putref(obd); @@ -978,7 +1003,7 @@ out: } #ifndef log2 -#define log2(n) ffz(~(n)) +#define log2(n) cfs_ffz(~(n)) #endif static int lov_clear_orphans(struct obd_export *export, struct obdo *src_oa, @@ -1101,6 +1126,7 @@ static int lov_create(struct obd_export *exp, struct obdo *src_oa, struct obd_info oinfo; struct lov_request_set *set = NULL; struct lov_request *req; + struct l_wait_info lwi = { 0 }; int rc = 0; ENTRY; @@ -1130,18 +1156,28 @@ static int lov_create(struct obd_export *exp, struct obdo *src_oa, * later in alloc_qos(), we will wait for those rpcs to complete if * the osfs age is older than 2 * qos_maxage */ qos_statfs_update(exp->exp_obd, - cfs_time_shift_64(-lov->desc.ld_qos_maxage) + HZ, 0); + cfs_time_shift_64(-lov->desc.ld_qos_maxage + + OBD_STATFS_CACHE_SECONDS), + 0); rc = lov_prep_create_set(exp, &oinfo, ea, src_oa, oti, &set); if (rc) GOTO(out, rc); - list_for_each_entry(req, &set->set_list, rq_link) { + cfs_list_for_each_entry(req, &set->set_list, rq_link) { /* XXX: LOV STACKING: use real "obj_mdp" sub-data */ - rc = obd_create(lov->lov_tgts[req->rq_idx]->ltd_exp, - req->rq_oi.oi_oa, &req->rq_oi.oi_md, oti); - lov_update_create_set(set, req, rc); + rc = obd_create_async(lov->lov_tgts[req->rq_idx]->ltd_exp, + &req->rq_oi, &req->rq_oi.oi_md, oti); } + + /* osc_create have timeout equ obd_timeout/2 so waiting don't be + * longer then this */ + l_wait_event(set->set_waitq, lov_finished_set(set), &lwi); + + /* we not have ptlrpc set for assign set->interpret and should + * be call interpret function himself. calling from cb_create_update + * not permited because lov_fini_create_set can sleep for long time, + * but we must avoid sleeping in ptlrpcd interpret function. */ rc = lov_fini_create_set(set, ea); out: obd_putref(exp->exp_obd); @@ -1152,9 +1188,8 @@ out: do { \ LASSERT((lsmp) != NULL); \ LASSERTF(((lsmp)->lsm_magic == LOV_MAGIC_V1 || \ - (lsmp)->lsm_magic == LOV_MAGIC_V3 || \ - (lsmp)->lsm_magic == LOV_MAGIC_JOIN), "%p->lsm_magic=%x\n", \ - (lsmp), (lsmp)->lsm_magic); \ + (lsmp)->lsm_magic == LOV_MAGIC_V3), \ + "%p->lsm_magic=%x\n", (lsmp), (lsmp)->lsm_magic); \ } while (0) static int lov_destroy(struct obd_export *exp, struct obdo *oa, @@ -1164,7 +1199,7 @@ static int lov_destroy(struct obd_export *exp, struct obdo *oa, struct lov_request_set *set; struct obd_info oinfo; struct lov_request *req; - struct list_head *pos; + cfs_list_t *pos; struct lov_obd *lov; int rc = 0, err = 0; ENTRY; @@ -1185,8 +1220,8 @@ static int lov_destroy(struct obd_export *exp, struct obdo *oa, if (rc) GOTO(out, rc); - list_for_each (pos, &set->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + cfs_list_for_each (pos, &set->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); if (oa->o_valid & OBD_MD_FLCOOKIE) oti->oti_logcookies = set->set_cookies + req->rq_stripe; @@ -1218,7 +1253,7 @@ static int lov_getattr(struct obd_export *exp, struct obd_info *oinfo) { struct lov_request_set *set; struct lov_request *req; - struct list_head *pos; + cfs_list_t *pos; struct lov_obd *lov; int err = 0, rc = 0; ENTRY; @@ -1235,8 +1270,8 @@ static int lov_getattr(struct obd_export *exp, struct obd_info *oinfo) if (rc) RETURN(rc); - list_for_each (pos, &set->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + cfs_list_for_each (pos, &set->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); CDEBUG(D_INFO, "objid "LPX64"[%d] has subobj "LPX64" at idx " "%u\n", oinfo->oi_oa->o_id, req->rq_stripe, @@ -1279,7 +1314,7 @@ static int lov_getattr_async(struct obd_export *exp, struct obd_info *oinfo, { struct lov_request_set *lovset; struct lov_obd *lov; - struct list_head *pos; + cfs_list_t *pos; struct lov_request *req; int rc = 0, err; ENTRY; @@ -1300,8 +1335,8 @@ static int lov_getattr_async(struct obd_export *exp, struct obd_info *oinfo, oinfo->oi_md->lsm_object_id, oinfo->oi_md->lsm_stripe_count, oinfo->oi_md->lsm_stripe_size); - list_for_each (pos, &lovset->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + cfs_list_for_each (pos, &lovset->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); CDEBUG(D_INFO, "objid "LPX64"[%d] has subobj "LPX64" at idx " "%u\n", oinfo->oi_oa->o_id, req->rq_stripe, @@ -1317,7 +1352,7 @@ static int lov_getattr_async(struct obd_export *exp, struct obd_info *oinfo, } } - if (!list_empty(&rqset->set_requests)) { + if (!cfs_list_empty(&rqset->set_requests)) { LASSERT(rc == 0); LASSERT (rqset->set_interpret == NULL); rqset->set_interpret = lov_getattr_interpret; @@ -1336,7 +1371,7 @@ static int lov_setattr(struct obd_export *exp, struct obd_info *oinfo, { struct lov_request_set *set; struct lov_obd *lov; - struct list_head *pos; + cfs_list_t *pos; struct lov_request *req; int err = 0, rc = 0; ENTRY; @@ -1360,8 +1395,8 @@ static int lov_setattr(struct obd_export *exp, struct obd_info *oinfo, if (rc) RETURN(rc); - list_for_each (pos, &set->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + cfs_list_for_each (pos, &set->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); rc = obd_setattr(lov->lov_tgts[req->rq_idx]->ltd_exp, &req->rq_oi, NULL); @@ -1402,7 +1437,7 @@ static int lov_setattr_async(struct obd_export *exp, struct obd_info *oinfo, { struct lov_request_set *set; struct lov_request *req; - struct list_head *pos; + cfs_list_t *pos; struct lov_obd *lov; int rc = 0; ENTRY; @@ -1426,8 +1461,8 @@ static int lov_setattr_async(struct obd_export *exp, struct obd_info *oinfo, oinfo->oi_md->lsm_object_id, oinfo->oi_md->lsm_stripe_count, oinfo->oi_md->lsm_stripe_size); - list_for_each (pos, &set->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + cfs_list_for_each (pos, &set->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); if (oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE) oti->oti_logcookies = set->set_cookies + req->rq_stripe; @@ -1449,7 +1484,7 @@ static int lov_setattr_async(struct obd_export *exp, struct obd_info *oinfo, } /* If we are not waiting for responses on async requests, return. */ - if (rc || !rqset || list_empty(&rqset->set_requests)) { + if (rc || !rqset || cfs_list_empty(&rqset->set_requests)) { int err; if (rc) set->set_completes = 0; @@ -1486,7 +1521,7 @@ static int lov_punch(struct obd_export *exp, struct obd_info *oinfo, { struct lov_request_set *set; struct lov_obd *lov; - struct list_head *pos; + cfs_list_t *pos; struct lov_request *req; int rc = 0; ENTRY; @@ -1502,8 +1537,8 @@ static int lov_punch(struct obd_export *exp, struct obd_info *oinfo, if (rc) RETURN(rc); - list_for_each (pos, &set->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + cfs_list_for_each (pos, &set->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); rc = obd_punch(lov->lov_tgts[req->rq_idx]->ltd_exp, &req->rq_oi, NULL, rqset); @@ -1516,7 +1551,7 @@ static int lov_punch(struct obd_export *exp, struct obd_info *oinfo, } } - if (rc || list_empty(&rqset->set_requests)) { + if (rc || cfs_list_empty(&rqset->set_requests)) { int err; err = lov_fini_punch_set(set); RETURN(rc ? rc : err); @@ -1529,49 +1564,71 @@ static int lov_punch(struct obd_export *exp, struct obd_info *oinfo, RETURN(0); } -static int lov_sync(struct obd_export *exp, struct obdo *oa, - struct lov_stripe_md *lsm, obd_off start, obd_off end, - void *capa) +static int lov_sync_interpret(struct ptlrpc_request_set *rqset, + void *data, int rc) { - struct lov_request_set *set; - struct obd_info oinfo; + struct lov_request_set *lovset = data; + int err; + ENTRY; + + if (rc) + lovset->set_completes = 0; + err = lov_fini_sync_set(lovset); + RETURN(rc ?: err); +} + +static int lov_sync(struct obd_export *exp, struct obd_info *oinfo, + obd_off start, obd_off end, + struct ptlrpc_request_set *rqset) +{ + struct lov_request_set *set = NULL; struct lov_obd *lov; - struct list_head *pos; + cfs_list_t *pos; struct lov_request *req; - int err = 0, rc = 0; + int rc = 0; ENTRY; - ASSERT_LSM_MAGIC(lsm); + ASSERT_LSM_MAGIC(oinfo->oi_md); + LASSERT(rqset != NULL); if (!exp->exp_obd) RETURN(-ENODEV); lov = &exp->exp_obd->u.lov; - rc = lov_prep_sync_set(exp, &oinfo, oa, lsm, start, end, &set); + rc = lov_prep_sync_set(exp, oinfo, start, end, &set); if (rc) RETURN(rc); - list_for_each (pos, &set->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + CDEBUG(D_INFO, "fsync objid "LPX64" ["LPX64", "LPX64"]\n", + set->set_oi->oi_oa->o_id, start, end); + + cfs_list_for_each (pos, &set->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); - rc = obd_sync(lov->lov_tgts[req->rq_idx]->ltd_exp, - req->rq_oi.oi_oa, NULL, + rc = obd_sync(lov->lov_tgts[req->rq_idx]->ltd_exp, &req->rq_oi, req->rq_oi.oi_policy.l_extent.start, - req->rq_oi.oi_policy.l_extent.end, capa); - err = lov_update_common_set(set, req, rc); - if (err) { + req->rq_oi.oi_policy.l_extent.end, rqset); + if (rc) { CERROR("error: fsync objid "LPX64" subobj "LPX64 " on OST idx %d: rc = %d\n", set->set_oi->oi_oa->o_id, req->rq_oi.oi_oa->o_id, req->rq_idx, rc); - if (!rc) - rc = err; + break; } } - err = lov_fini_sync_set(set); - if (!rc) - rc = err; - RETURN(rc); + + /* If we are not waiting for responses on async requests, return. */ + if (rc || cfs_list_empty(&rqset->set_requests)) { + int err = lov_fini_sync_set(set); + + RETURN(rc ?: err); + } + + LASSERT(rqset->set_interpret == NULL); + rqset->set_interpret = lov_sync_interpret; + rqset->set_arg = (void *)set; + + RETURN(0); } static int lov_brw_check(struct lov_obd *lov, struct obd_info *lov_oinfo, @@ -1613,7 +1670,7 @@ static int lov_brw(int cmd, struct obd_export *exp, struct obd_info *oinfo, { struct lov_request_set *set; struct lov_request *req; - struct list_head *pos; + cfs_list_t *pos; struct lov_obd *lov = &exp->exp_obd->u.lov; int err, rc = 0; ENTRY; @@ -1629,10 +1686,10 @@ static int lov_brw(int cmd, struct obd_export *exp, struct obd_info *oinfo, if (rc) RETURN(rc); - list_for_each (pos, &set->set_list) { + cfs_list_for_each (pos, &set->set_list) { struct obd_export *sub_exp; struct brw_page *sub_pga; - req = list_entry(pos, struct lov_request, rq_link); + req = cfs_list_entry(pos, struct lov_request, rq_link); sub_exp = lov->lov_tgts[req->rq_idx]->ltd_exp; sub_pga = set->set_pga + req->rq_pgaidx; @@ -1665,7 +1722,7 @@ static int lov_enqueue(struct obd_export *exp, struct obd_info *oinfo, ldlm_mode_t mode = einfo->ei_mode; struct lov_request_set *set; struct lov_request *req; - struct list_head *pos; + cfs_list_t *pos; struct lov_obd *lov; ldlm_error_t rc; ENTRY; @@ -1685,8 +1742,8 @@ static int lov_enqueue(struct obd_export *exp, struct obd_info *oinfo, if (rc) RETURN(rc); - list_for_each (pos, &set->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + cfs_list_for_each (pos, &set->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); rc = obd_enqueue(lov->lov_tgts[req->rq_idx]->ltd_exp, &req->rq_oi, einfo, rqset); @@ -1694,7 +1751,7 @@ static int lov_enqueue(struct obd_export *exp, struct obd_info *oinfo, GOTO(out, rc); } - if (rqset && !list_empty(&rqset->set_requests)) { + if (rqset && !cfs_list_empty(&rqset->set_requests)) { LASSERT(rc == 0); LASSERT(rqset->set_interpret == NULL); rqset->set_interpret = lov_enqueue_interpret; @@ -1719,8 +1776,6 @@ static int lov_change_cbdata(struct obd_export *exp, if (!exp || !exp->exp_obd) RETURN(-ENODEV); - LASSERT_MDS_GROUP(lsm->lsm_object_gr); - lov = &exp->exp_obd->u.lov; for (i = 0; i < lsm->lsm_stripe_count; i++) { struct lov_stripe_md submd; @@ -1731,8 +1786,9 @@ static int lov_change_cbdata(struct obd_export *exp, continue; } + LASSERT_SEQ_IS_MDT(loi->loi_seq); submd.lsm_object_id = loi->loi_id; - submd.lsm_object_gr = lsm->lsm_object_gr; + submd.lsm_object_seq = loi->loi_seq; submd.lsm_stripe_count = 0; rc = obd_change_cbdata(lov->lov_tgts[loi->loi_ost_idx]->ltd_exp, &submd, it, data); @@ -1740,13 +1796,52 @@ static int lov_change_cbdata(struct obd_export *exp, RETURN(rc); } +/* find any ldlm lock of the inode in lov + * return 0 not find + * 1 find one + * < 0 error */ +static int lov_find_cbdata(struct obd_export *exp, + struct lov_stripe_md *lsm, ldlm_iterator_t it, + void *data) +{ + struct lov_obd *lov; + int rc = 0, i; + ENTRY; + + ASSERT_LSM_MAGIC(lsm); + + if (!exp || !exp->exp_obd) + RETURN(-ENODEV); + + lov = &exp->exp_obd->u.lov; + for (i = 0; i < lsm->lsm_stripe_count; i++) { + struct lov_stripe_md submd; + struct lov_oinfo *loi = lsm->lsm_oinfo[i]; + + if (!lov->lov_tgts[loi->loi_ost_idx]) { + CDEBUG(D_HA, "lov idx %d NULL \n", loi->loi_ost_idx); + continue; + } + + LASSERT_SEQ_IS_MDT(loi->loi_seq); + submd.lsm_object_id = loi->loi_id; + submd.lsm_object_seq = loi->loi_seq; + submd.lsm_stripe_count = 0; + rc = obd_find_cbdata(lov->lov_tgts[loi->loi_ost_idx]->ltd_exp, + &submd, it, data); + if (rc != 0) + RETURN(rc); + } + RETURN(rc); +} + static int lov_cancel(struct obd_export *exp, struct lov_stripe_md *lsm, __u32 mode, struct lustre_handle *lockh) { struct lov_request_set *set; struct obd_info oinfo; struct lov_request *req; - struct list_head *pos; + cfs_list_t *pos; struct lov_obd *lov; struct lustre_handle *lov_lockhp; int err = 0, rc = 0; @@ -1757,15 +1852,15 @@ static int lov_cancel(struct obd_export *exp, struct lov_stripe_md *lsm, if (!exp || !exp->exp_obd) RETURN(-ENODEV); - LASSERT_MDS_GROUP(lsm->lsm_object_gr); + LASSERT_SEQ_IS_MDT(lsm->lsm_object_seq); LASSERT(lockh); lov = &exp->exp_obd->u.lov; rc = lov_prep_cancel_set(exp, &oinfo, lsm, mode, lockh, &set); if (rc) RETURN(rc); - list_for_each (pos, &set->set_list) { - req = list_entry(pos, struct lov_request, rq_link); + cfs_list_for_each (pos, &set->set_list) { + req = cfs_list_entry(pos, struct lov_request, rq_link); lov_lockhp = set->set_lockh->llh_handles + req->rq_stripe; rc = obd_cancel(lov->lov_tgts[req->rq_idx]->ltd_exp, @@ -1787,7 +1882,7 @@ static int lov_cancel(struct obd_export *exp, struct lov_stripe_md *lsm, static int lov_cancel_unused(struct obd_export *exp, struct lov_stripe_md *lsm, - int flags, void *opaque) + ldlm_cancel_flags_t flags, void *opaque) { struct lov_obd *lov; int rc = 0, i; @@ -1813,7 +1908,7 @@ static int lov_cancel_unused(struct obd_export *exp, ASSERT_LSM_MAGIC(lsm); - LASSERT_MDS_GROUP(lsm->lsm_object_gr); + LASSERT_SEQ_IS_MDT(lsm->lsm_object_seq); for (i = 0; i < lsm->lsm_stripe_count; i++) { struct lov_stripe_md submd; struct lov_oinfo *loi = lsm->lsm_oinfo[i]; @@ -1828,7 +1923,7 @@ static int lov_cancel_unused(struct obd_export *exp, CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx); submd.lsm_object_id = loi->loi_id; - submd.lsm_object_gr = lsm->lsm_object_gr; + submd.lsm_object_seq = loi->loi_seq; submd.lsm_stripe_count = 0; err = obd_cancel_unused(lov->lov_tgts[loi->loi_ost_idx]->ltd_exp, &submd, flags, opaque); @@ -1861,7 +1956,7 @@ static int lov_statfs_async(struct obd_device *obd, struct obd_info *oinfo, { struct lov_request_set *set; struct lov_request *req; - struct list_head *pos; + cfs_list_t *pos; struct lov_obd *lov; int rc = 0; ENTRY; @@ -1874,10 +1969,10 @@ static int lov_statfs_async(struct obd_device *obd, struct obd_info *oinfo, if (rc) RETURN(rc); - list_for_each (pos, &set->set_list) { + cfs_list_for_each (pos, &set->set_list) { struct obd_device *osc_obd; - req = list_entry(pos, struct lov_request, rq_link); + req = cfs_list_entry(pos, struct lov_request, rq_link); osc_obd = class_exp2obd(lov->lov_tgts[req->rq_idx]->ltd_exp); rc = obd_statfs_async(osc_obd, &req->rq_oi, max_age, rqset); @@ -1885,7 +1980,7 @@ static int lov_statfs_async(struct obd_device *obd, struct obd_info *oinfo, break; } - if (rc || list_empty(&rqset->set_requests)) { + if (rc || cfs_list_empty(&rqset->set_requests)) { int err; if (rc) set->set_completes = 0; @@ -1941,8 +2036,6 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, __u32 index; memcpy(&index, data->ioc_inlbuf2, sizeof(__u32)); - LASSERT(data->ioc_plen1 == sizeof(struct obd_statfs)); - if ((index >= count)) RETURN(-ENODEV); @@ -1956,16 +2049,21 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, if (!osc_obd) RETURN(-EINVAL); + /* copy UUID */ + if (cfs_copy_to_user(data->ioc_pbuf2, obd2cli_tgt(osc_obd), + min((int) data->ioc_plen2, + (int) sizeof(struct obd_uuid)))) + RETURN(-EFAULT); + /* got statfs data */ rc = obd_statfs(osc_obd, &stat_buf, - cfs_time_current_64() - HZ, 0); + cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), + 0); if (rc) RETURN(rc); - if (copy_to_user(data->ioc_pbuf1, &stat_buf, data->ioc_plen1)) - RETURN(-EFAULT); - /* copy UUID */ - if (copy_to_user(data->ioc_pbuf2, obd2cli_tgt(osc_obd), - data->ioc_plen2)) + if (cfs_copy_to_user(data->ioc_pbuf1, &stat_buf, + min((int) data->ioc_plen1, + (int) sizeof(stat_buf)))) RETURN(-EFAULT); break; } @@ -2009,7 +2107,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, *genp = lov->lov_tgts[i]->ltd_gen; } - if (copy_to_user((void *)uarg, buf, len)) + if (cfs_copy_to_user((void *)uarg, buf, len)) rc = -EFAULT; obd_ioctl_freedata(buf, len); break; @@ -2078,11 +2176,16 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, for (i = 0; i < count; i++) { int err; + struct obd_device *osc_obd; /* OST was disconnected */ if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_exp) continue; + /* ll_umount_begin() sets force flag but for lov, not + * osc. Let's pass it through */ + osc_obd = class_exp2obd(lov->lov_tgts[i]->ltd_exp); + osc_obd->obd_force = obddev->obd_force; err = obd_iocontrol(cmd, lov->lov_tgts[i]->ltd_exp, len, karg, uarg); if (err == -ENODATA && cmd == OBD_IOC_POLL_QUOTACHECK) { @@ -2268,7 +2371,7 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key, if (fiemap_count_to_size(fm_key->fiemap.fm_extent_count) < buffer_size) buffer_size = fiemap_count_to_size(fm_key->fiemap.fm_extent_count); - OBD_ALLOC(fm_local, buffer_size); + OBD_ALLOC_LARGE(fm_local, buffer_size); if (fm_local == NULL) GOTO(out, rc = -ENOMEM); lcl_fm_ext = &fm_local->fm_extents[0]; @@ -2356,6 +2459,7 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key, fm_local->fm_flags = fiemap->fm_flags; fm_key->oa.o_id = lsm->lsm_oinfo[cur_stripe]->loi_id; + fm_key->oa.o_seq = lsm->lsm_oinfo[cur_stripe]->loi_seq; ost_index = lsm->lsm_oinfo[cur_stripe]->loi_ost_idx; if (ost_index < 0 || ost_index >=lov->desc.ld_tgt_count) @@ -2458,7 +2562,7 @@ skip_last_device_calc: fiemap->fm_mapped_extents = current_extent; out: - OBD_FREE(fm_local, buffer_size); + OBD_FREE_LARGE(fm_local, buffer_size); return rc; } @@ -2501,7 +2605,7 @@ static int lov_get_info(struct obd_export *exp, __u32 keylen, continue; if (lov->lov_tgts[loi->loi_ost_idx]->ltd_exp == data->lock->l_conn_export && - osc_res_name_eq(loi->loi_id, loi->loi_gr, res_id)) { + osc_res_name_eq(loi->loi_id, loi->loi_seq, res_id)) { *stripe = i; GOTO(out, rc = 0); } @@ -2530,6 +2634,19 @@ static int lov_get_info(struct obd_export *exp, __u32 keylen, } else if (KEY_IS(KEY_FIEMAP)) { rc = lov_fiemap(lov, keylen, key, vallen, val, lsm); GOTO(out, rc); + } else if (KEY_IS(KEY_CONNECT_FLAG)) { + struct lov_tgt_desc *tgt; + __u64 ost_idx = *((__u64*)val); + + LASSERT(*vallen == sizeof(__u64)); + LASSERT(ost_idx < lov->desc.ld_tgt_count); + tgt = lov->lov_tgts[ost_idx]; + + if (!tgt || !tgt->ltd_exp) + GOTO(out, rc = -ESRCH); + + *((__u64*)val) = tgt->ltd_exp->exp_connect_flags; + GOTO(out, rc = 0); } rc = -EINVAL; @@ -2572,8 +2689,6 @@ static int lov_set_info_async(struct obd_export *exp, obd_count keylen, next_id = 1; } else if (KEY_IS(KEY_CHECKSUM)) { do_inactive = 1; - } else if (KEY_IS(KEY_UNLINKED)) { - check_uuid = val ? 1 : 0; } else if (KEY_IS(KEY_EVICT_BY_NID)) { /* use defaults: do_inactive = incr = 0; */ } else if (KEY_IS(KEY_MDS_CONN)) { @@ -2652,21 +2767,6 @@ static int lov_set_info_async(struct obd_export *exp, obd_count keylen, RETURN(rc); } -static int lov_checkmd(struct obd_export *exp, struct obd_export *md_exp, - struct lov_stripe_md *lsm) -{ - int rc; - ENTRY; - - if (!lsm) - RETURN(0); - LASSERT(md_exp); - LASSERT(lsm_op_find(lsm->lsm_magic) != NULL); - rc = lsm_op_find(lsm->lsm_magic)->lsm_revalidate(lsm, md_exp->exp_obd); - - RETURN(rc); -} - int lov_test_and_clear_async_rc(struct lov_stripe_md *lsm) { int i, rc = 0; @@ -2710,7 +2810,7 @@ static int lov_extent_calc(struct obd_export *exp, struct lov_stripe_md *lsm, void lov_stripe_lock(struct lov_stripe_md *md) { LASSERT(md->lsm_lock_owner != cfs_curproc_pid()); - spin_lock(&md->lsm_lock); + cfs_spin_lock(&md->lsm_lock); LASSERT(md->lsm_lock_owner == 0); md->lsm_lock_owner = cfs_curproc_pid(); } @@ -2720,7 +2820,7 @@ void lov_stripe_unlock(struct lov_stripe_md *md) { LASSERT(md->lsm_lock_owner == cfs_curproc_pid()); md->lsm_lock_owner = 0; - spin_unlock(&md->lsm_lock); + cfs_spin_unlock(&md->lsm_lock); } EXPORT_SYMBOL(lov_stripe_unlock); @@ -2737,7 +2837,6 @@ struct obd_ops lov_obd_ops = { .o_statfs_async = lov_statfs_async, .o_packmd = lov_packmd, .o_unpackmd = lov_unpackmd, - .o_checkmd = lov_checkmd, .o_create = lov_create, .o_destroy = lov_destroy, .o_getattr = lov_getattr, @@ -2751,6 +2850,7 @@ struct obd_ops lov_obd_ops = { .o_sync = lov_sync, .o_enqueue = lov_enqueue, .o_change_cbdata = lov_change_cbdata, + .o_find_cbdata = lov_find_cbdata, .o_cancel = lov_cancel, .o_cancel_unused = lov_cancel_unused, .o_iocontrol = lov_iocontrol, @@ -2792,14 +2892,14 @@ int __init lov_init(void) lov_oinfo_slab = cfs_mem_cache_create("lov_oinfo", sizeof(struct lov_oinfo), - 0, SLAB_HWCACHE_ALIGN); + 0, CFS_SLAB_HWCACHE_ALIGN); if (lov_oinfo_slab == NULL) { lu_kmem_fini(lov_caches); return -ENOMEM; } lprocfs_lov_init_vars(&lvars); - request_module("lquota"); + cfs_request_module("lquota"); quota_interface = PORTAL_SYMBOL_GET(lov_quota_interface); init_obd_quota_ops(quota_interface, &lov_obd_ops);