int slc_fcmh_ctor(struct fidc_membh *f, __unusedx int flags) { struct fcmh_cli_info *fci; struct sl_resource *res; struct sl_site *s; sl_siteid_t siteid; int i; fci = fcmh_get_pri(f); slc_fcmh_refresh_age(f); INIT_PSC_LISTENTRY(&fci->fci_lentry); siteid = FID_GET_SITEID(fcmh_2_fid(f)); psc_assert(f->fcmh_flags & FCMH_INITING); if (fcmh_2_fid(f) != SLFID_ROOT && siteid != msl_rmc_resm->resm_siteid) { s = libsl_siteid2site(siteid); if (s == NULL) { psclog_errorx("fid "SLPRI_FID" has " "invalid site ID %d", fcmh_2_fid(f), siteid); return (ESTALE); } SITE_FOREACH_RES(s, res, i) if (res->res_type == SLREST_MDS) { fci->fci_resm = psc_dynarray_getpos( &res->res_members, 0); return (0); } psclog_errorx("fid "SLPRI_FID" has invalid site ID %d", fcmh_2_fid(f), siteid); return (ESTALE); }
/* * Handle a NAMESPACE_UPDATE request from another MDS. */ int slm_rmm_handle_namespace_update(struct pscrpc_request *rq) { struct srt_update_entry *entryp; struct srm_update_req *mq; struct srm_update_rep *mp; struct sl_mds_peerinfo *p; struct sl_resource *res; struct sl_site *site; struct iovec iov; int i, len, count; SL_RSX_ALLOCREP(rq, mq, mp); count = mq->count; if (count <= 0 || mq->size > LNET_MTU) { mp->rc = -EINVAL; return (mp->rc); } iov.iov_len = mq->size; iov.iov_base = PSCALLOC(mq->size); mp->rc = slrpc_bulkserver(rq, BULK_GET_SINK, SRMM_BULK_PORTAL, &iov, 1); if (mp->rc) goto out; /* Search for the peer information by the given site ID. */ site = libsl_siteid2site(mq->siteid); p = NULL; if (site) SITE_FOREACH_RES(site, res, i) if (res->res_type == SLREST_MDS) { p = res2rpmi(res)->rpmi_info; break; } if (p == NULL) { psclog_info("fail to find site ID %d", mq->siteid); PFL_GOTOERR(out, mp->rc = -EINVAL); } /* * Iterate through the namespace update buffer and apply updates. * If we fail to apply an update, we still report success to our * peer because reporting an error does not help our cause. */ entryp = iov.iov_base; for (i = 0; i < count; i++) { slm_rmm_apply_update(entryp); len = UPDATE_ENTRY_LEN(entryp); entryp = PSC_AGP(entryp, len); } zfsslash2_wait_synced(0); out: PSCFREE(iov.iov_base); return (mp->rc); }
/* * Forward a name space operation to a remote MDS first before * replicating the operation locally by our callers. */ int slm_rmm_forward_namespace(int op, struct sl_fidgen *fg, struct sl_fidgen *nfg, char *name, char *newname, uint32_t mode, const struct slash_creds *crp, struct srt_stat *sstb, int32_t to_set) { struct slashrpc_cservice *csvc = NULL; struct pscrpc_request *rq = NULL; struct sl_resm *resm = NULL; struct srm_forward_req *mq; struct srm_forward_rep *mp; struct sl_resource *res; struct sl_site *site; int rc, len, i, vfsid; sl_siteid_t siteid; if (op != SLM_FORWARD_MKDIR && op != SLM_FORWARD_RMDIR && op != SLM_FORWARD_CREATE && op != SLM_FORWARD_UNLINK && op != SLM_FORWARD_RENAME && op != SLM_FORWARD_SETATTR && op != SLM_FORWARD_SYMLINK) return (-PFLERR_NOSYS); rc = slfid_to_vfsid(fg->fg_fid, &vfsid); if (rc) return (rc); siteid = FID_GET_SITEID(fg->fg_fid); site = libsl_siteid2site(siteid); if (site == NULL) return (-EBADF); SITE_FOREACH_RES(site, res, i) { if (res->res_type != SLREST_MDS) continue; resm = psc_dynarray_getpos(&res->res_members, 0); break; } csvc = slm_getmcsvc_wait(resm); if (csvc == NULL) { psclog_info("unable to connect to site %d", siteid); return (-EIO); } rc = SL_RSX_NEWREQ(csvc, SRMT_NAMESPACE_FORWARD, rq, mq, mp); if (rc) goto out; mq->op = op; mq->fg = *fg; if (op == SLM_FORWARD_SETATTR) { mq->to_set = to_set; mq->req.sstb = *sstb; } else strlcpy(mq->req.name, name, sizeof(mq->req.name)); if (op == SLM_FORWARD_RENAME || op == SLM_FORWARD_SYMLINK) { if (op == SLM_FORWARD_RENAME) mq->nfg = *nfg; len = strlen(name) + 1; strlcpy(mq->req.name + len, newname, sizeof(mq->req.name) - len); } if (op == SLM_FORWARD_MKDIR || op == SLM_FORWARD_CREATE || op == SLM_FORWARD_SYMLINK) { mq->mode = mode; mq->creds.scr_uid = crp->scr_uid; mq->creds.scr_gid = crp->scr_gid; } rc = SL_RSX_WAITREP(csvc, rq, mp); if (!rc) rc = mp->rc; if (!rc && sstb) *sstb = mp->attr; out: if (rq) pscrpc_req_finished(rq); if (csvc) sl_csvc_decref(csvc); return (rc); }