* The OBD Filter Device (OFD) module belongs to the Object Storage
* Server stack and connects the RPC oriented Unified Target (TGT)
* layer (see lustre/include/lu_target.h) to the storage oriented OSD
- * layer (see lustre/doc/osd-api.txt).
+ * layer (see Documentation/osd-api.txt).
*
* TGT
* | DT and OBD APIs
static int ofd_recovery_complete(const struct lu_env *env,
struct lu_device *dev)
{
+ struct ofd_thread_info *oti = ofd_info(env);
struct ofd_device *ofd = ofd_dev(dev);
struct lu_device *next = &ofd->ofd_osd->dd_lu_dev;
- int rc = 0, max_precreate;
+ int rc = 0;
ENTRY;
/*
* Grant space for object precreation on the self export.
- * This initial reserved space (i.e. 10MB for zfs and 280KB for ldiskfs)
+ * The initial reserved space (i.e. 10MB for zfs and 280KB for ldiskfs)
* is enough to create 10k objects. More space is then acquired for
* precreation in ofd_grant_create().
*/
- max_precreate = OST_MAX_PRECREATE * ofd->ofd_dt_conf.ddp_inodespace / 2;
- ofd_grant_connect(env, dev->ld_obd->obd_self_export, max_precreate,
- false);
+ memset(&oti->fti_ocd, 0, sizeof(oti->fti_ocd));
+ oti->fti_ocd.ocd_grant = OST_MAX_PRECREATE / 2;
+ oti->fti_ocd.ocd_grant *= ofd->ofd_dt_conf.ddp_inodespace;
+ oti->fti_ocd.ocd_connect_flags = OBD_CONNECT_GRANT |
+ OBD_CONNECT_GRANT_PARAM;
+ ofd_grant_connect(env, dev->ld_obd->obd_self_export, &oti->fti_ocd,
+ true);
rc = next->ld_ops->ldo_recovery_complete(env, next);
RETURN(rc);
}
ss->ss_lu = lu->ld_site;
ss->ss_node_id = ofd->ofd_lut.lut_lsd.lsd_osd_index;
+ OBD_ALLOC(name, sizeof(obd_name) * 2 + 10);
+ if (name == NULL)
+ return -ENOMEM;
+
OBD_ALLOC_PTR(ss->ss_server_seq);
if (ss->ss_server_seq == NULL)
- GOTO(out_free, rc = -ENOMEM);
-
- OBD_ALLOC(name, strlen(obd_name) + 10);
- if (!name) {
- OBD_FREE_PTR(ss->ss_server_seq);
- ss->ss_server_seq = NULL;
- GOTO(out_free, rc = -ENOMEM);
- }
+ GOTO(out_name, rc = -ENOMEM);
rc = seq_server_init(env, ss->ss_server_seq, ofd->ofd_osd, obd_name,
LUSTRE_SEQ_SERVER, ss);
if (rc) {
CERROR("%s : seq server init error %d\n", obd_name, rc);
- GOTO(out_free, rc);
+ GOTO(out_server, rc);
}
ss->ss_server_seq->lss_space.lsr_index = ss->ss_node_id;
OBD_ALLOC_PTR(ss->ss_client_seq);
if (ss->ss_client_seq == NULL)
- GOTO(out_free, rc = -ENOMEM);
+ GOTO(out_server, rc = -ENOMEM);
- snprintf(name, strlen(obd_name) + 6, "%p-super", obd_name);
+ /*
+ * It always printed as "%p", so that the name is unique in the kernel,
+ * even if the filesystem is mounted twice. So sizeof(.) * 2 is enough.
+ */
+ snprintf(name, sizeof(obd_name) * 2 + 7, "%p-super", obd_name);
rc = seq_client_init(ss->ss_client_seq, NULL, LUSTRE_SEQ_DATA,
name, NULL);
if (rc) {
CERROR("%s : seq client init error %d\n", obd_name, rc);
- GOTO(out_free, rc);
+ GOTO(out_client, rc);
}
- OBD_FREE(name, strlen(obd_name) + 10);
- name = NULL;
rc = seq_server_set_cli(env, ss->ss_server_seq, ss->ss_client_seq);
-out_free:
if (rc) {
- if (ss->ss_server_seq) {
- seq_server_fini(ss->ss_server_seq, env);
- OBD_FREE_PTR(ss->ss_server_seq);
- ss->ss_server_seq = NULL;
- }
-
- if (ss->ss_client_seq) {
- seq_client_fini(ss->ss_client_seq);
- OBD_FREE_PTR(ss->ss_client_seq);
- ss->ss_client_seq = NULL;
- }
-
- if (name) {
- OBD_FREE(name, strlen(obd_name) + 10);
- name = NULL;
- }
+out_client:
+ seq_client_fini(ss->ss_client_seq);
+ OBD_FREE_PTR(ss->ss_client_seq);
+ ss->ss_client_seq = NULL;
+out_server:
+ seq_server_fini(ss->ss_server_seq, env);
+ OBD_FREE_PTR(ss->ss_server_seq);
+ ss->ss_server_seq = NULL;
}
+out_name:
+ OBD_FREE(name, sizeof(obd_name) * 2 + 10);
return rc;
}
ENTRY;
+ OBD_FAIL_TIMEOUT(OBD_FAIL_OST_PAUSE_PUNCH, cfs_fail_val);
+
/* check that we do support OBD_CONNECT_TRUNCLOCK. */
CLASSERT(OST_CONNECT_SUPPORTED & OBD_CONNECT_TRUNCLOCK);
}
/**
+ * OFD request handler for OST_LADVISE RPC.
+ *
+ * Tune cache or perfetch policies according to advices.
+ *
+ * \param[in] tsi target session environment for this request
+ *
+ * \retval 0 if successful
+ * \retval negative errno on error
+ */
+static int ofd_ladvise_hdl(struct tgt_session_info *tsi)
+{
+ struct ptlrpc_request *req = tgt_ses_req(tsi);
+ struct obd_export *exp = tsi->tsi_exp;
+ struct ofd_device *ofd = ofd_exp(exp);
+ struct ost_body *body, *repbody;
+ struct ofd_thread_info *info;
+ struct ofd_object *fo;
+ const struct lu_env *env = req->rq_svc_thread->t_env;
+ int rc = 0;
+ struct lu_ladvise *ladvise;
+ int num_advise;
+ struct ladvise_hdr *ladvise_hdr;
+ int i;
+ ENTRY;
+
+ body = tsi->tsi_ost_body;
+
+ if ((body->oa.o_valid & OBD_MD_FLID) != OBD_MD_FLID)
+ RETURN(err_serious(-EPROTO));
+
+ ladvise_hdr = req_capsule_client_get(tsi->tsi_pill,
+ &RMF_OST_LADVISE_HDR);
+ if (ladvise_hdr == NULL)
+ RETURN(err_serious(-EPROTO));
+
+ if (ladvise_hdr->lah_magic != LADVISE_MAGIC ||
+ ladvise_hdr->lah_count < 1)
+ RETURN(err_serious(-EPROTO));
+
+ if ((ladvise_hdr->lah_flags & (~LF_MASK)) != 0)
+ RETURN(err_serious(-EPROTO));
+
+ ladvise = req_capsule_client_get(tsi->tsi_pill, &RMF_OST_LADVISE);
+ if (ladvise == NULL)
+ RETURN(err_serious(-EPROTO));
+
+ num_advise = req_capsule_get_size(&req->rq_pill,
+ &RMF_OST_LADVISE, RCL_CLIENT) /
+ sizeof(*ladvise);
+ if (num_advise < ladvise_hdr->lah_count)
+ RETURN(err_serious(-EPROTO));
+
+ repbody = req_capsule_server_get(&req->rq_pill, &RMF_OST_BODY);
+ repbody->oa = body->oa;
+
+ info = ofd_info_init(env, exp);
+
+ rc = ostid_to_fid(&info->fti_fid, &body->oa.o_oi,
+ ofd->ofd_lut.lut_lsd.lsd_osd_index);
+ if (rc != 0)
+ RETURN(rc);
+
+ fo = ofd_object_find(env, ofd, &info->fti_fid);
+ if (IS_ERR(fo)) {
+ rc = PTR_ERR(fo);
+ RETURN(rc);
+ }
+ LASSERT(fo != NULL);
+
+ for (i = 0; i < num_advise; i++, ladvise++) {
+ if (ladvise->lla_end <= ladvise->lla_start) {
+ rc = err_serious(-EPROTO);
+ break;
+ }
+
+ /* Handle different advice types */
+ switch (ladvise->lla_advice) {
+ default:
+ rc = -ENOTSUPP;
+ break;
+ }
+ if (rc != 0)
+ break;
+ }
+
+ ofd_object_put(env, fo);
+ req->rq_status = rc;
+ RETURN(rc);
+}
+
+/**
* OFD request handler for OST_QUOTACTL RPC.
*
* This is part of request processing to validate incoming request fields,
*/
static int ofd_quotactl(struct tgt_session_info *tsi)
{
- struct obd_quotactl *oqctl, *repoqc;
- struct lu_nodemap *nodemap =
- tsi->tsi_exp->exp_target_data.ted_nodemap;
- int id;
- int rc;
+ struct obd_quotactl *oqctl, *repoqc;
+ struct lu_nodemap *nodemap;
+ int id;
+ int rc;
ENTRY;
*repoqc = *oqctl;
+ nodemap = nodemap_get_from_exp(tsi->tsi_exp);
+ if (IS_ERR(nodemap))
+ RETURN(PTR_ERR(nodemap));
+
id = repoqc->qc_id;
if (oqctl->qc_type == USRQUOTA)
id = nodemap_map_id(nodemap, NODEMAP_UID,
NODEMAP_CLIENT_TO_FS,
repoqc->qc_id);
+ nodemap_putref(nodemap);
+
if (repoqc->qc_id != id)
swap(repoqc->qc_id, id);
struct ldlm_lock *lock)
{
struct tgt_session_info *tsi;
+ struct obdo *oa;
+ struct ldlm_extent ext;
+
+ ENTRY;
/* Don't use tgt_ses_info() to get session info, because lock_match()
* can be called while request has no processing thread yet. */
LASSERT(tsi->tsi_ost_body != NULL);
if (tsi->tsi_ost_body->oa.o_valid & OBD_MD_FLHANDLE &&
tsi->tsi_ost_body->oa.o_handle.cookie == lock->l_handle.h_cookie)
- return 1;
+ RETURN(1);
- return 0;
+ oa = &tsi->tsi_ost_body->oa;
+ ext.start = oa->o_size;
+ ext.end = oa->o_blocks;
+
+ LASSERT(lock->l_resource != NULL);
+ if (!ostid_res_name_eq(&oa->o_oi, &lock->l_resource->lr_name))
+ RETURN(0);
+
+ if (!(lock->l_granted_mode & (LCK_PW | LCK_GROUP)))
+ RETURN(0);
+
+ RETURN(ldlm_extent_overlap(&lock->l_policy_data.l_extent, &ext));
}
/**
ofd_hp_punch),
TGT_OST_HDL(HABEO_CORPUS| HABEO_REFERO, OST_SYNC, ofd_sync_hdl),
TGT_OST_HDL(0 | HABEO_REFERO, OST_QUOTACTL, ofd_quotactl),
+TGT_OST_HDL(HABEO_CORPUS | HABEO_REFERO, OST_LADVISE, ofd_ladvise_hdl),
};
static struct tgt_opc_slice ofd_common_slice[] = {
ofd_slc_set(m);
m->ofd_grant_compat_disable = 0;
m->ofd_soft_sync_limit = OFD_SOFT_SYNC_LIMIT_DEFAULT;
+ m->ofd_brw_size = ONE_MB_BRW_SIZE;
/* statfs data */
spin_lock_init(&m->ofd_osfs_lock);
dt_conf_get(env, m->ofd_osd, &m->ofd_dt_conf);
- /* Allow at most ddp_grant_reserved% of the available filesystem space
- * to be granted to clients, so that any errors in the grant overhead
- * calculations do not allow granting more space to clients than can be
- * written. Assumes that in aggregate the grant overhead calculations do
- * not have more than ddp_grant_reserved% estimation error in them. */
- m->ofd_grant_ratio =
- ofd_grant_ratio_conv(m->ofd_dt_conf.ddp_grant_reserved);
-
rc = tgt_init(env, &m->ofd_lut, obd, m->ofd_osd, ofd_common_slice,
OBD_FAIL_OST_ALL_REQUEST_NET,
OBD_FAIL_OST_ALL_REPLY_NET);