X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_lov.c;h=2ec38a768a214dd304ef8eb3c657bc3bb1b2f4ae;hb=4960810b94d808965cae9258fb4f7583618a75e9;hp=1b0336a8c811b02f3d564b871111b6819645fb71;hpb=4c01e64e0a72c1682ebf0a8bd4cccf99fd04cd88;p=fs%2Flustre-release.git diff --git a/lustre/mdd/mdd_lov.c b/lustre/mdd/mdd_lov.c index 1b0336a..2ec38a7 100644 --- a/lustre/mdd/mdd_lov.c +++ b/lustre/mdd/mdd_lov.c @@ -26,7 +26,7 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. */ /* @@ -145,7 +145,9 @@ int mdd_init_obd(const struct lu_env *env, struct mdd_device *mdd, LBUG(); } + cfs_spin_lock(&obd->obd_dev_lock); obd->obd_recovering = 1; + cfs_spin_unlock(&obd->obd_dev_lock); obd->u.mds.mds_id = mds_id; rc = class_setup(obd, lcfg); if (rc) @@ -274,8 +276,8 @@ static int mdd_lov_set_dir_md(const struct lu_env *env, /* if { size, offset, count } = { 0, -1, 0 } and no pool (i.e. all default * values specified) then delete default striping from dir. */ - if (lum->lmm_stripe_size == 0 && lum->lmm_stripe_count == 0 && - lum->lmm_stripe_offset == (typeof(lum->lmm_stripe_offset))(-1) && + if (LOVEA_DELETE_VALUES(lum->lmm_stripe_size, lum->lmm_stripe_count, + lum->lmm_stripe_offset) && lum->lmm_magic != LOV_USER_MAGIC_V3) { rc = mdd_xattr_set_txn(env, obj, &LU_BUF_NULL, XATTR_NAME_LOV, 0, handle); @@ -804,3 +806,167 @@ int mdd_lov_setattr_async(const struct lu_env *env, struct mdd_object *obj, lmm_size, logcookies, fid, NULL); RETURN(rc); } + +static int grouplock_blocking_ast(struct ldlm_lock *lock, + struct ldlm_lock_desc *desc, + void *data, int flag) +{ + struct md_attr *ma = data; + struct lustre_handle lockh; + int rc = 0; + ENTRY; + + switch (flag) + { + case LDLM_CB_BLOCKING : + /* lock is canceled */ + CDEBUG(D_DLMTRACE, "Lock %p is canceled\n", lock); + + ldlm_lock2handle(lock, &lockh); + rc = ldlm_cli_cancel(&lockh); + + break; + case LDLM_CB_CANCELING : + CDEBUG(D_DLMTRACE, + "Lock %p has been canceled, do cleaning\n", + lock); + + if (ma && ma->ma_som) + OBD_FREE_PTR(ma->ma_som); + if (ma) + OBD_FREE_PTR(ma); + break; + default: + LBUG(); + } + RETURN(rc); +} + +static int grouplock_glimpse_ast(struct ldlm_lock *lock, void *data) +{ + struct ptlrpc_request *req = data; + struct ost_lvb *lvb; + int rc; + struct md_attr *ma; + ENTRY; + + ma = lock->l_ast_data; + + req_capsule_extend(&req->rq_pill, &RQF_LDLM_GL_CALLBACK); + req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER, + sizeof(*lvb)); + rc = req_capsule_server_pack(&req->rq_pill); + if (rc) { + CERROR("failed pack reply: %d\n", rc); + GOTO(out, rc); + } + + lvb = req_capsule_server_get(&req->rq_pill, &RMF_DLM_LVB); + + if ((ma) && (ma->ma_valid & MA_SOM)) { + lvb->lvb_size = ma->ma_som->msd_size; + lvb->lvb_blocks = ma->ma_som->msd_blocks; + } else if ((ma) && (ma->ma_valid & MA_INODE)) { + lvb->lvb_size = ma->ma_attr.la_size; + lvb->lvb_blocks = ma->ma_attr.la_blocks; + } else { + lvb->lvb_size = 0; + rc = -ELDLM_NO_LOCK_DATA; + } + + EXIT; +out: + if (rc == -ELDLM_NO_LOCK_DATA) + lustre_pack_reply(req, 1, NULL, NULL); + + req->rq_status = rc; + return rc; +} + +int mdd_file_lock(const struct lu_env *env, struct md_object *obj, + struct lov_mds_md *lmm, struct ldlm_extent *extent, + struct lustre_handle *lockh) +{ + struct ldlm_enqueue_info einfo = { 0 }; + struct obd_info oinfo = { { { 0 } } }; + struct obd_device *obd; + struct obd_export *lov_exp; + struct lov_stripe_md *lsm = NULL; + struct md_attr *ma = NULL; + int rc; + ENTRY; + + obd = mdo2mdd(obj)->mdd_obd_dev; + lov_exp = obd->u.mds.mds_lov_exp; + + obd_unpackmd(lov_exp, &lsm, lmm, + lov_mds_md_size(lmm->lmm_stripe_count, lmm->lmm_magic)); + + OBD_ALLOC_PTR(ma); + if (ma == NULL) + GOTO(out, rc = -ENOMEM); + + OBD_ALLOC_PTR(ma->ma_som); + if (ma->ma_som == NULL) + GOTO(out, rc = -ENOMEM); + + ma->ma_need = MA_SOM | MA_INODE; + mo_attr_get(env, obj, ma); + + einfo.ei_type = LDLM_EXTENT; + einfo.ei_mode = LCK_GROUP; + einfo.ei_cb_bl = grouplock_blocking_ast; + einfo.ei_cb_cp = ldlm_completion_ast; + einfo.ei_cb_gl = grouplock_glimpse_ast; + + if (ma->ma_valid & (MA_SOM | MA_INODE)) + einfo.ei_cbdata = ma; + else + einfo.ei_cbdata = NULL; + + memset(&oinfo.oi_policy, 0, sizeof(oinfo.oi_policy)); + oinfo.oi_policy.l_extent = *extent; + oinfo.oi_lockh = lockh; + oinfo.oi_md = lsm; + oinfo.oi_flags = 0; + + rc = obd_enqueue(lov_exp, &oinfo, &einfo, NULL); + /* ei_cbdata is used as a free flag at exit */ + if (rc) + einfo.ei_cbdata = NULL; + + obd_unpackmd(lov_exp, &lsm, NULL, 0); + +out: + /* ma is freed if not used as callback data */ + if ((einfo.ei_cbdata == NULL) && ma && ma->ma_som) + OBD_FREE_PTR(ma->ma_som); + if ((einfo.ei_cbdata == NULL) && ma) + OBD_FREE_PTR(ma); + + RETURN(rc); +} + +int mdd_file_unlock(const struct lu_env *env, struct md_object *obj, + struct lov_mds_md *lmm, struct lustre_handle *lockh) +{ + struct obd_device *obd; + struct obd_export *lov_exp; + struct lov_stripe_md *lsm = NULL; + int rc; + ENTRY; + + LASSERT(lustre_handle_is_used(lockh)); + + obd = mdo2mdd(obj)->mdd_obd_dev; + lov_exp = obd->u.mds.mds_lov_exp; + + obd_unpackmd(lov_exp, &lsm, lmm, + lov_mds_md_size(lmm->lmm_stripe_count, lmm->lmm_magic)); + + rc = obd_cancel(lov_exp, lsm, LCK_GROUP, lockh); + + obd_unpackmd(lov_exp, &lsm, NULL, 0); + + RETURN(rc); +}