X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_handler.c;h=0b31287d58d14c1779c16db957923a3a52ae66e1;hb=aa9938a26b2fd58afc53bd25020e8940464d1855;hp=58bd62442476668f7f8e648b08ce46c4bf99e269;hpb=5c50b8609e54cc6fa72253a4c0ceb9c77961da3c;p=fs%2Flustre-release.git diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 58bd624..0b31287 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -49,6 +49,7 @@ #define DEBUG_SUBSYSTEM S_MDS #include +#include #include #include @@ -379,6 +380,7 @@ static int mdt_get_root(struct tgt_session_info *tsi) nodemap_fileset = nodemap_get_fileset(exp->exp_target_data.ted_nodemap); if (nodemap_fileset && nodemap_fileset[0]) { + CDEBUG(D_INFO, "nodemap fileset is %s\n", nodemap_fileset); if (fileset) { /* consider fileset from client as a sub-fileset * of the nodemap one */ @@ -396,6 +398,7 @@ static int mdt_get_root(struct tgt_session_info *tsi) } if (fileset) { + CDEBUG(D_INFO, "Getting fileset %s\n", fileset); rc = mdt_lookup_fileset(info, fileset, &repbody->mbo_fid1); if (rc < 0) GOTO(out, rc = err_serious(rc)); @@ -448,15 +451,15 @@ static int mdt_statfs(struct tgt_session_info *tsi) rc = next->md_ops->mdo_statfs(info->mti_env, next, osfs); if (rc) GOTO(out, rc); - spin_lock(&info->mti_mdt->mdt_osfs_lock); + spin_lock(&info->mti_mdt->mdt_lock); info->mti_mdt->mdt_osfs = *osfs; info->mti_mdt->mdt_osfs_age = cfs_time_current_64(); - spin_unlock(&info->mti_mdt->mdt_osfs_lock); + spin_unlock(&info->mti_mdt->mdt_lock); } else { /** use cached statfs data */ - spin_lock(&info->mti_mdt->mdt_osfs_lock); + spin_lock(&info->mti_mdt->mdt_lock); *osfs = info->mti_mdt->mdt_osfs; - spin_unlock(&info->mti_mdt->mdt_osfs_lock); + spin_unlock(&info->mti_mdt->mdt_lock); } if (rc == 0) @@ -582,9 +585,6 @@ void mdt_pack_attr2body(struct mdt_thread_info *info, struct mdt_body *b, PFID(fid), b->mbo_nlink, b->mbo_mode, b->mbo_valid); } - if (info != NULL) - mdt_body_reverse_idmap(info, b); - if (!(attr->la_valid & LA_TYPE)) return; @@ -1017,7 +1017,8 @@ static int mdt_getattr_internal(struct mdt_thread_info *info, rc = mdt_attr_get_complex(info, o, ma); if (unlikely(rc)) { - CERROR("%s: getattr error for "DFID": rc = %d\n", + CDEBUG(rc == -ENOENT ? D_OTHER : D_ERROR, + "%s: getattr error for "DFID": rc = %d\n", mdt_obd_name(info->mti_mdt), PFID(mdt_object_fid(o)), rc); RETURN(rc); @@ -1138,23 +1139,8 @@ static int mdt_getattr_internal(struct mdt_thread_info *info, repbody->mbo_max_mdsize); } - if (exp_connect_rmtclient(info->mti_exp) && - reqbody->mbo_valid & OBD_MD_FLRMTPERM) { - void *buf = req_capsule_server_get(pill, &RMF_ACL); - - /* mdt_getattr_lock only */ - rc = mdt_pack_remote_perm(info, o, buf); - if (rc) { - repbody->mbo_valid &= ~OBD_MD_FLRMTPERM; - repbody->mbo_aclsize = 0; - RETURN(rc); - } else { - repbody->mbo_valid |= OBD_MD_FLRMTPERM; - repbody->mbo_aclsize = sizeof(struct mdt_remote_perm); - } - } #ifdef CONFIG_FS_POSIX_ACL - else if ((exp_connect_flags(req->rq_export) & OBD_CONNECT_ACL) && + if ((exp_connect_flags(req->rq_export) & OBD_CONNECT_ACL) && (reqbody->mbo_valid & OBD_MD_FLACL)) { struct lu_nodemap *nodemap = nodemap_get_from_exp(exp); if (IS_ERR(nodemap)) @@ -1227,18 +1213,13 @@ static int mdt_getattr(struct tgt_session_info *tsi) repbody->mbo_eadatasize = 0; repbody->mbo_aclsize = 0; - if (reqbody->mbo_valid & OBD_MD_FLRMTPERM) - rc = mdt_init_ucred(info, reqbody); - else - rc = mdt_check_ucred(info); + rc = mdt_check_ucred(info); if (unlikely(rc)) GOTO(out_shrink, rc); info->mti_cross_ref = !!(reqbody->mbo_valid & OBD_MD_FLCROSSREF); rc = mdt_getattr_internal(info, obj, 0); - if (reqbody->mbo_valid & OBD_MD_FLRMTPERM) - mdt_exit_ucred(info); EXIT; out_shrink: mdt_client_compatibility(info); @@ -1260,17 +1241,13 @@ out: */ static void mdt_swap_lov_flag(struct mdt_object *o1, struct mdt_object *o2) { - __u64 o1_flags; + unsigned int o1_lov_created = o1->mot_lov_created; mutex_lock(&o1->mot_lov_mutex); mutex_lock(&o2->mot_lov_mutex); - o1_flags = o1->mot_flags; - o1->mot_flags = (o1->mot_flags & ~MOF_LOV_CREATED) | - (o2->mot_flags & MOF_LOV_CREATED); - - o2->mot_flags = (o2->mot_flags & ~MOF_LOV_CREATED) | - (o1_flags & MOF_LOV_CREATED); + o1->mot_lov_created = o2->mot_lov_created; + o2->mot_lov_created = o1_lov_created; mutex_unlock(&o2->mot_lov_mutex); mutex_unlock(&o1->mot_lov_mutex); @@ -1842,6 +1819,26 @@ free_rdpg: return rc; } +static int mdt_fix_attr_ucred(struct mdt_thread_info *info, __u32 op) +{ + struct lu_ucred *uc = mdt_ucred_check(info); + struct lu_attr *attr = &info->mti_attr.ma_attr; + + if (uc == NULL) + return -EINVAL; + + if (op != REINT_SETATTR) { + if ((attr->la_valid & LA_UID) && (attr->la_uid != -1)) + attr->la_uid = uc->uc_fsuid; + /* for S_ISGID, inherit gid from his parent, such work will be + * done in cmm/mdd layer, here set all cases as uc->uc_fsgid. */ + if ((attr->la_valid & LA_GID) && (attr->la_gid != -1)) + attr->la_gid = uc->uc_fsgid; + } + + return 0; +} + static int mdt_reint_internal(struct mdt_thread_info *info, struct mdt_lock_handle *lhc, __u32 op) @@ -2094,32 +2091,7 @@ static int mdt_quotactl(struct tgt_session_info *tsi) GOTO(out_nodemap, rc = -EFAULT); } - /* map uid/gid for remote client */ id = oqctl->qc_id; - if (exp_connect_rmtclient(exp)) { - struct lustre_idmap_table *idmap; - - idmap = exp->exp_mdt_data.med_idmap; - - if (unlikely(oqctl->qc_cmd != Q_GETQUOTA && - oqctl->qc_cmd != Q_GETINFO)) - GOTO(out_nodemap, rc = -EPERM); - - if (oqctl->qc_type == USRQUOTA) - id = lustre_idmap_lookup_uid(NULL, idmap, 0, - oqctl->qc_id); - else if (oqctl->qc_type == GRPQUOTA) - id = lustre_idmap_lookup_gid(NULL, idmap, 0, - oqctl->qc_id); - else - GOTO(out_nodemap, rc = -EINVAL); - - if (id == CFS_IDMAP_NOTFOUND) { - CDEBUG(D_QUOTA, "no mapping for id %u\n", oqctl->qc_id); - GOTO(out_nodemap, rc = -EACCES); - } - } - if (oqctl->qc_type == USRQUOTA) id = nodemap_map_id(nodemap, NODEMAP_UID, NODEMAP_CLIENT_TO_FS, id); @@ -2218,21 +2190,9 @@ static int mdt_llog_ctxt_unclone(const struct lu_env *env, */ static int mdt_sec_ctx_handle(struct tgt_session_info *tsi) { - int rc; - - rc = mdt_handle_idmap(tsi); - if (unlikely(rc)) { - struct ptlrpc_request *req = tgt_ses_req(tsi); - __u32 opc; - - opc = lustre_msg_get_opc(req->rq_reqmsg); - if (opc == SEC_CTX_INIT || opc == SEC_CTX_INIT_CONT) - sptlrpc_svc_ctx_invalidate(req); - } - CFS_FAIL_TIMEOUT(OBD_FAIL_SEC_CTX_HDL_PAUSE, cfs_fail_val); - return rc; + return 0; } /* @@ -2415,12 +2375,13 @@ int mdt_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, int mdt_remote_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, void *data, int flag) { - struct lustre_handle lockh; - int rc; + int rc = 0; ENTRY; switch (flag) { - case LDLM_CB_BLOCKING: + case LDLM_CB_BLOCKING: { + struct lustre_handle lockh; + ldlm_lock2handle(lock, &lockh); rc = ldlm_cli_cancel(&lockh, ldlm_is_atomic_cb(lock) ? 0 : LCF_ASYNC); @@ -2429,17 +2390,46 @@ int mdt_remote_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, RETURN(rc); } break; - case LDLM_CB_CANCELING: - LDLM_DEBUG(lock, "Revoke remote lock"); + } + case LDLM_CB_CANCELING: { + LDLM_DEBUG(lock, "Revoke remote lock\n"); + /* discard slc lock here so that it can be cleaned anytime, * especially for cleanup_resource() */ tgt_discard_slc_lock(lock); + + /* once we cache lock, l_ast_data is set to mdt_object */ + if (lock->l_ast_data != NULL) { + struct mdt_object *mo = lock->l_ast_data; + struct lu_env env; + + rc = lu_env_init(&env, LCT_MD_THREAD); + if (unlikely(rc != 0)) { + struct obd_device *obd; + + obd = ldlm_lock_to_ns(lock)->ns_obd; + CWARN("%s: lu_env initialization failed, object" + "%p "DFID" is leaked!\n", + obd->obd_name, mo, + PFID(mdt_object_fid(mo))); + RETURN(rc); + } + + if (lock->l_policy_data.l_inodebits.bits & + (MDS_INODELOCK_XATTR | MDS_INODELOCK_UPDATE)) { + rc = mo_invalidate(&env, mdt_object_child(mo)); + mo->mot_cache_attr = 0; + } + mdt_object_put(&env, mo); + lu_env_fini(&env); + } break; + } default: LBUG(); } - RETURN(0); + RETURN(rc); } int mdt_check_resent_lock(struct mdt_thread_info *info, @@ -2479,7 +2469,8 @@ int mdt_check_resent_lock(struct mdt_thread_info *info, int mdt_remote_object_lock(struct mdt_thread_info *mti, struct mdt_object *o, const struct lu_fid *fid, struct lustre_handle *lh, - enum ldlm_mode mode, __u64 ibits, bool nonblock) + enum ldlm_mode mode, __u64 ibits, bool nonblock, + bool cache) { struct ldlm_enqueue_info *einfo = &mti->mti_einfo; union ldlm_policy_data *policy = &mti->mti_policy; @@ -2500,12 +2491,24 @@ int mdt_remote_object_lock(struct mdt_thread_info *mti, struct mdt_object *o, einfo->ei_res_id = res_id; if (nonblock) einfo->ei_nonblock = 1; + if (cache) { + /* + * if we cache lock, couple lock with mdt_object, so that object + * can be easily found in lock ASTs. + */ + mdt_object_get(mti->mti_env, o); + einfo->ei_cbdata = o; + } memset(policy, 0, sizeof(*policy)); policy->l_inodebits.bits = ibits; rc = mo_object_lock(mti->mti_env, mdt_object_child(o), lh, einfo, policy); + if (rc < 0 && cache) { + mdt_object_put(mti->mti_env, o); + einfo->ei_cbdata = NULL; + } RETURN(rc); } @@ -2654,7 +2657,8 @@ mdt_object_lock_internal(struct mdt_thread_info *info, struct mdt_object *o, rc = mdt_remote_object_lock(info, o, mdt_object_fid(o), &lh->mlh_rreg_lh, lh->mlh_rreg_mode, - MDS_INODELOCK_UPDATE, nonblock); + MDS_INODELOCK_UPDATE, nonblock, + false); if (rc != ELDLM_OK) { if (local_lh != NULL) mdt_object_unlock(info, o, local_lh, rc); @@ -2782,17 +2786,24 @@ static void mdt_save_lock(struct mdt_thread_info *info, struct lustre_handle *h, * \param decref force immediate lock releasing */ static void mdt_save_remote_lock(struct mdt_thread_info *info, - struct lustre_handle *h, enum ldlm_mode mode, - int decref) + struct mdt_object *o, struct lustre_handle *h, + enum ldlm_mode mode, int decref) { ENTRY; if (lustre_handle_is_used(h)) { + struct ldlm_lock *lock = ldlm_handle2lock(h); + + if (o != NULL && + (lock->l_policy_data.l_inodebits.bits & + (MDS_INODELOCK_XATTR | MDS_INODELOCK_UPDATE))) + mo_invalidate(info->mti_env, mdt_object_child(o)); + if (decref || !info->mti_has_trans || !(mode & (LCK_PW | LCK_EX))) { ldlm_lock_decref_and_cancel(h, mode); + LDLM_LOCK_PUT(lock); } else { - struct ldlm_lock *lock = ldlm_handle2lock(h); struct ptlrpc_request *req = mdt_info_req(info); LASSERT(req != NULL); @@ -2824,7 +2835,8 @@ void mdt_object_unlock(struct mdt_thread_info *info, struct mdt_object *o, mdt_save_lock(info, &lh->mlh_pdo_lh, lh->mlh_pdo_mode, decref); mdt_save_lock(info, &lh->mlh_reg_lh, lh->mlh_reg_mode, decref); - mdt_save_remote_lock(info, &lh->mlh_rreg_lh, lh->mlh_rreg_mode, decref); + mdt_save_remote_lock(info, o, &lh->mlh_rreg_lh, lh->mlh_rreg_mode, + decref); EXIT; } @@ -3034,11 +3046,6 @@ struct mdt_thread_info *tsi2mdt_info(struct tgt_session_info *tsi) static int mdt_tgt_connect(struct tgt_session_info *tsi) { - struct ptlrpc_request *req = tgt_ses_req(tsi); - int rc; - - ENTRY; - if (OBD_FAIL_CHECK(OBD_FAIL_TGT_DELAY_CONDITIONAL) && cfs_fail_val == tsi2mdt_info(tsi)->mti_mdt->mdt_seq_site.ss_node_id) { @@ -3046,17 +3053,7 @@ static int mdt_tgt_connect(struct tgt_session_info *tsi) schedule_timeout(msecs_to_jiffies(3 * MSEC_PER_SEC)); } - rc = tgt_connect(tsi); - if (rc != 0) - RETURN(rc); - - rc = mdt_init_idmap(tsi); - if (rc != 0) - GOTO(err, rc); - RETURN(0); -err: - obd_disconnect(class_export_get(req->rq_export)); - return rc; + return tgt_connect(tsi); } enum mdt_it_code { @@ -4501,6 +4498,11 @@ static void mdt_fini(const struct lu_env *env, struct mdt_device *m) struct lfsck_stop stop; ENTRY; + if (m->mdt_md_root != NULL) { + mdt_object_put(env, m->mdt_md_root); + m->mdt_md_root = NULL; + } + stop.ls_status = LS_PAUSED; stop.ls_flags = 0; next->md_ops->mdo_iocontrol(env, next, OBD_IOC_STOP_LFSCK, 0, &stop); @@ -4621,7 +4623,7 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, m->mdt_squash.rsi_gid = 0; INIT_LIST_HEAD(&m->mdt_squash.rsi_nosquash_nids); init_rwsem(&m->mdt_squash.rsi_sem); - spin_lock_init(&m->mdt_osfs_lock); + spin_lock_init(&m->mdt_lock); m->mdt_osfs_age = cfs_time_shift_64(-1000); m->mdt_enable_remote_dir = 0; m->mdt_enable_remote_dir_gid = 0; @@ -4957,8 +4959,10 @@ static int mdt_object_print(const struct lu_env *env, void *cookie, struct mdt_object *mdto = mdt_obj((struct lu_object *)o); return (*p)(env, cookie, - LUSTRE_MDT_NAME"-object@%p(flags=%d, writecount=%d)", - mdto, mdto->mot_flags, mdto->mot_write_count); + LUSTRE_MDT_NAME"-object@%p(%s %s, writecount=%d)", + mdto, mdto->mot_lov_created ? "lov_created" : "", + mdto->mot_cache_attr ? "cache_attr" : "", + mdto->mot_write_count); } static int mdt_prepare(const struct lu_env *env, @@ -5071,6 +5075,7 @@ static int mdt_connect_internal(struct obd_export *exp, LASSERT(data != NULL); data->ocd_connect_flags &= MDT_CONNECT_SUPPORTED; + data->ocd_connect_flags2 &= MDT_CONNECT_SUPPORTED2; data->ocd_ibits_known &= MDS_INODELOCK_FULL; if (!(data->ocd_connect_flags & OBD_CONNECT_MDS_MDS) && @@ -5312,6 +5317,8 @@ static int mdt_obd_connect(const struct lu_env *env, ENTRY; LASSERT(env != NULL); + LASSERT(data != NULL); + if (!exp || !obd || !cluuid) RETURN(-EINVAL); @@ -5328,7 +5335,7 @@ static int mdt_obd_connect(const struct lu_env *env, * XXX: probably not very appropriate method is used now * at some point we should find a better one */ - if (!test_bit(MDT_FL_SYNCED, &mdt->mdt_state) && data != NULL && + if (!test_bit(MDT_FL_SYNCED, &mdt->mdt_state) && !(data->ocd_connect_flags & OBD_CONNECT_LIGHTWEIGHT) && !(data->ocd_connect_flags & OBD_CONNECT_MDS_MDS)) { rc = obd_get_info(env, mdt->mdt_child_exp, @@ -5414,8 +5421,6 @@ static int mdt_init_export(struct obd_export *exp) INIT_LIST_HEAD(&med->med_open_head); spin_lock_init(&med->med_open_lock); - mutex_init(&med->med_idmap_mutex); - med->med_idmap = NULL; spin_lock(&exp->exp_lock); exp->exp_connecting = 1; spin_unlock(&exp->exp_lock); @@ -5447,9 +5452,6 @@ static int mdt_destroy_export(struct obd_export *exp) { ENTRY; - if (exp_connect_rmtclient(exp)) - mdt_cleanup_idmap(&exp->exp_mdt_data); - target_destroy_export(exp); /* destroy can be called from failed obd_setup, so * checking uuid is safer than obd_self_export */ @@ -5910,13 +5912,15 @@ static int mdt_iocontrol(unsigned int cmd, struct obd_export *exp, int len, if (rc) RETURN(rc); - switch (cmd) { - case OBD_IOC_SYNC: - rc = mdt_device_sync(&env, mdt); - break; - case OBD_IOC_SET_READONLY: - rc = dt->dd_ops->dt_ro(&env, dt); - break; + switch (cmd) { + case OBD_IOC_SYNC: + rc = mdt_device_sync(&env, mdt); + break; + case OBD_IOC_SET_READONLY: + rc = dt_sync(&env, dt); + if (rc == 0) + rc = dt_ro(&env, dt); + break; case OBD_IOC_ABORT_RECOVERY: CERROR("%s: Aborting recovery for device\n", mdt_obd_name(mdt)); obd->obd_abort_recovery = 1;