/** * Disconnect a connected client. * * This function terminates the client connection. The client export is * disconnected (cleaned up) and client data on persistent storage is removed. * * \param[in] exp OBD export * * \retval 0 if successful * \retval negative value on error */ int ofd_obd_disconnect(struct obd_export *exp) { struct ofd_device *ofd = ofd_exp(exp); struct lu_env env; int rc; ENTRY; LASSERT(exp); class_export_get(exp); if (!(exp->exp_flags & OBD_OPT_FORCE)) ofd_grant_sanity_check(ofd_obd(ofd), __FUNCTION__); nodemap_del_member(exp); rc = server_disconnect_export(exp); ofd_grant_discard(exp); /* Do not erase record for recoverable client. */ if (exp->exp_obd->obd_replayable && (!exp->exp_obd->obd_fail || exp->exp_failed)) { rc = lu_env_init(&env, LCT_DT_THREAD); if (rc) GOTO(out, rc); tgt_client_del(&env, exp); lu_env_fini(&env); } out: class_export_put(exp); RETURN(rc); }
/* Update last_rcvd records with the latest transaction data */ int ofd_txn_stop_cb(const struct lu_env *env, struct thandle *txn, void *cookie) { struct ofd_device *ofd = cookie; struct ofd_thread_info *info; ENTRY; info = lu_context_key_get(&env->le_ctx, &ofd_thread_key); if (info->fti_exp == NULL) RETURN(0); LASSERT(ofd_exp(info->fti_exp) == ofd); if (info->fti_has_trans) { if (info->fti_mult_trans == 0) { CERROR("More than one transaction "LPU64"\n", info->fti_transno); RETURN(0); } /* we need another transno to be assigned */ info->fti_transno = 0; } else if (txn->th_result == 0) { info->fti_has_trans = 1; } spin_lock(&ofd->ofd_lut.lut_translock); if (txn->th_result != 0) { if (info->fti_transno != 0) { CERROR("Replay transno "LPU64" failed: rc %d\n", info->fti_transno, txn->th_result); info->fti_transno = 0; } } else if (info->fti_transno == 0) { info->fti_transno = ++ofd->ofd_lut.lut_last_transno; } else { /* should be replay */ if (info->fti_transno > ofd->ofd_lut.lut_last_transno) ofd->ofd_lut.lut_last_transno = info->fti_transno; } spin_unlock(&ofd->ofd_lut.lut_translock); /** VBR: set new versions */ if (txn->th_result == 0 && info->fti_obj != NULL) { dt_version_set(env, ofd_object_child(info->fti_obj), info->fti_transno, txn); info->fti_obj = NULL; } /* filling reply data */ CDEBUG(D_INODE, "transno = %llu, last_committed = %llu\n", info->fti_transno, ofd_obd(ofd)->obd_last_committed); /* if can't add callback, do sync write */ txn->th_sync |= !!tgt_last_commit_cb_add(txn, &ofd->ofd_lut, info->fti_exp, info->fti_transno); return ofd_last_rcvd_update(info, txn); }
/** * Initialize OFD per-export statistics. * * This function sets up procfs entries for various OFD export counters. These * counters are for per-client statistics tracked on the server. * * \param[in] ofd OFD device * \param[in] exp OBD export * \param[in] client_nid NID of client * * \retval 0 if successful * \retval negative value on error */ static int ofd_export_stats_init(struct ofd_device *ofd, struct obd_export *exp, lnet_nid_t *client_nid) { struct obd_device *obd = ofd_obd(ofd); struct nid_stat *stats; int rc; ENTRY; LASSERT(obd->obd_uses_nid_stats); if (obd_uuid_equals(&exp->exp_client_uuid, &obd->obd_uuid)) /* Self-export gets no proc entry */ RETURN(0); rc = lprocfs_exp_setup(exp, client_nid); if (rc != 0) /* Mask error for already created /proc entries */ RETURN(rc == -EALREADY ? 0 : rc); stats = exp->exp_nid_stats; stats->nid_stats = lprocfs_alloc_stats(NUM_OBD_STATS + LPROC_OFD_STATS_LAST, LPROCFS_STATS_FLAG_NOPERCPU); if (stats->nid_stats == NULL) RETURN(-ENOMEM); lprocfs_init_ops_stats(LPROC_OFD_STATS_LAST, stats->nid_stats); ofd_stats_counter_init(stats->nid_stats); rc = lprocfs_register_stats(stats->nid_proc, "stats", stats->nid_stats); if (rc != 0) { lprocfs_free_stats(&stats->nid_stats); GOTO(out, rc); } rc = lprocfs_nid_ldlm_stats_init(stats); if (rc != 0) GOTO(out, rc); out: RETURN(rc); }
* * Author: Lai Siyao <*****@*****.**> */ #define DEBUG_SUBSYSTEM S_FILTER #include "ofd_internal.h" static inline __u32 ofd_ck_keyid(struct filter_capa_key *key) { return key->k_key.lk_keyid; } int ofd_update_capa_key(struct ofd_device *ofd, struct lustre_capa_key *new) { struct obd_device *obd = ofd_obd(ofd); struct filter_capa_key *k, *keys[2] = { NULL, NULL }; int i; spin_lock(&capa_lock); cfs_list_for_each_entry(k, &obd->u.filter.fo_capa_keys, k_list) { if (k->k_key.lk_seq != new->lk_seq) continue; if (keys[0]) { keys[1] = k; if (ofd_ck_keyid(keys[1]) > ofd_ck_keyid(keys[0])) keys[1] = keys[0], keys[0] = k; } else { keys[0] = k; }
/* This will be called in two ways: * * r != NULL : called by the DLM itself after a glimpse callback * r == NULL : called by the ofd after a disk write * * If 'increase_only' is true, don't allow values to move backwards. */ static int ofd_lvbo_update(struct ldlm_resource *res, struct ptlrpc_request *req, int increase_only) { struct ofd_device *ofd; struct ofd_object *fo; struct ofd_thread_info *info; struct ost_lvb *lvb; struct lu_env env; int rc = 0; ENTRY; LASSERT(res != NULL); ofd = ldlm_res_to_ns(res)->ns_lvbp; LASSERT(ofd != NULL); rc = lu_env_init(&env, LCT_DT_THREAD); if (rc) RETURN(rc); info = ofd_info_init(&env, NULL); fid_extract_from_res_name(&info->fti_fid, &res->lr_name); lvb = res->lr_lvb_data; if (lvb == NULL) { CERROR("%s: no LVB data for "DFID"\n", ofd_obd(ofd)->obd_name, PFID(&info->fti_fid)); GOTO(out_env, rc = 0); } /* Update the LVB from the network message */ if (req != NULL) { struct ost_lvb *rpc_lvb; bool lvb_type; if (req->rq_import != NULL) lvb_type = imp_connect_lvb_type(req->rq_import); else lvb_type = exp_connect_lvb_type(req->rq_export); if (!lvb_type) { struct ost_lvb_v1 *lvb_v1; lvb_v1 = req_capsule_server_swab_get(&req->rq_pill, &RMF_DLM_LVB, lustre_swab_ost_lvb_v1); if (lvb_v1 == NULL) goto disk_update; rpc_lvb = &info->fti_lvb; memcpy(rpc_lvb, lvb_v1, sizeof *lvb_v1); rpc_lvb->lvb_mtime_ns = 0; rpc_lvb->lvb_atime_ns = 0; rpc_lvb->lvb_ctime_ns = 0; } else { rpc_lvb = req_capsule_server_swab_get(&req->rq_pill, &RMF_DLM_LVB, lustre_swab_ost_lvb); if (rpc_lvb == NULL) goto disk_update; } lock_res(res); if (rpc_lvb->lvb_size > lvb->lvb_size || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb size: " LPU64" -> "LPU64"\n", PFID(&info->fti_fid), lvb->lvb_size, rpc_lvb->lvb_size); lvb->lvb_size = rpc_lvb->lvb_size; } if (rpc_lvb->lvb_mtime > lvb->lvb_mtime || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb mtime: " LPU64" -> "LPU64"\n", PFID(&info->fti_fid), lvb->lvb_mtime, rpc_lvb->lvb_mtime); lvb->lvb_mtime = rpc_lvb->lvb_mtime; } if (rpc_lvb->lvb_atime > lvb->lvb_atime || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb atime: " LPU64" -> "LPU64"\n", PFID(&info->fti_fid), lvb->lvb_atime, rpc_lvb->lvb_atime); lvb->lvb_atime = rpc_lvb->lvb_atime; } if (rpc_lvb->lvb_ctime > lvb->lvb_ctime || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb ctime: " LPU64" -> "LPU64"\n", PFID(&info->fti_fid), lvb->lvb_ctime, rpc_lvb->lvb_ctime); lvb->lvb_ctime = rpc_lvb->lvb_ctime; } if (rpc_lvb->lvb_blocks > lvb->lvb_blocks || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb blocks: " LPU64" -> "LPU64"\n", PFID(&info->fti_fid), lvb->lvb_blocks, rpc_lvb->lvb_blocks); lvb->lvb_blocks = rpc_lvb->lvb_blocks; } unlock_res(res); } disk_update: /* Update the LVB from the disk inode */ ost_fid_from_resid(&info->fti_fid, &res->lr_name, ofd->ofd_lut.lut_lsd.lsd_osd_index); fo = ofd_object_find(&env, ofd, &info->fti_fid); if (IS_ERR(fo)) GOTO(out_env, rc = PTR_ERR(fo)); rc = ofd_attr_get(&env, fo, &info->fti_attr); if (rc) GOTO(out_obj, rc); lock_res(res); if (info->fti_attr.la_size > lvb->lvb_size || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb size from disk: " LPU64" -> %llu\n", PFID(&info->fti_fid), lvb->lvb_size, info->fti_attr.la_size); lvb->lvb_size = info->fti_attr.la_size; } if (info->fti_attr.la_mtime >lvb->lvb_mtime || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb mtime from disk: " LPU64" -> "LPU64"\n", PFID(&info->fti_fid), lvb->lvb_mtime, info->fti_attr.la_mtime); lvb->lvb_mtime = info->fti_attr.la_mtime; } if (info->fti_attr.la_atime >lvb->lvb_atime || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb atime from disk: " LPU64" -> "LPU64"\n", PFID(&info->fti_fid), lvb->lvb_atime, info->fti_attr.la_atime); lvb->lvb_atime = info->fti_attr.la_atime; } if (info->fti_attr.la_ctime >lvb->lvb_ctime || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb ctime from disk: " LPU64" -> "LPU64"\n", PFID(&info->fti_fid), lvb->lvb_ctime, info->fti_attr.la_ctime); lvb->lvb_ctime = info->fti_attr.la_ctime; } if (info->fti_attr.la_blocks > lvb->lvb_blocks || !increase_only) { CDEBUG(D_DLMTRACE, "res: "DFID" updating lvb blocks from disk: " LPU64" -> %llu\n", PFID(&info->fti_fid), lvb->lvb_blocks, (unsigned long long)info->fti_attr.la_blocks); lvb->lvb_blocks = info->fti_attr.la_blocks; } unlock_res(res); out_obj: ofd_object_put(&env, fo); out_env: lu_env_fini(&env); return rc; }