/* * 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); }
int slm_rmc_handle_ping(struct pscrpc_request *rq) { const struct srm_ping_req *mq; struct srm_ping_rep *mp; SL_RSX_ALLOCREP(rq, mq, mp); return (0); }
int slm_rmc_handle_getinode(struct pscrpc_request *rq) { const struct srm_get_inode_req *mq; struct srm_get_inode_rep *mp; struct fidc_membh *f; SL_RSX_ALLOCREP(rq, mq, mp); mp->rc = -slm_fcmh_get(&mq->fg, &f); if (mp->rc) return (0); slm_pack_inode(f, &mp->ino); fcmh_op_done(f); return (0); }
/* * Handle a BMAPCHWRMODE request to upgrade a client bmap lease from * READ-only to READ+WRITE. * @rq: RPC request. */ int slm_rmc_handle_bmap_chwrmode(struct pscrpc_request *rq) { struct bmap_mds_lease *bml = NULL; struct srm_bmap_chwrmode_req *mq; struct srm_bmap_chwrmode_rep *mp; struct fidc_membh *f = NULL; struct bmapc_memb *b = NULL; struct bmap_mds_info *bmi; SL_RSX_ALLOCREP(rq, mq, mp); mp->rc = -slm_fcmh_get(&mq->sbd.sbd_fg, &f); if (mp->rc) PFL_GOTOERR(out, mp->rc); mp->rc = bmap_lookup(f, mq->sbd.sbd_bmapno, &b); if (mp->rc) PFL_GOTOERR(out, mp->rc); bmi = bmap_2_bmi(b); bml = mds_bmap_getbml(b, mq->sbd.sbd_seq, mq->sbd.sbd_nid, mq->sbd.sbd_pid); if (bml == NULL) PFL_GOTOERR(out, mp->rc = -EINVAL); mp->rc = mds_bmap_bml_chwrmode(bml, mq->prefios[0]); if (mp->rc == -PFLERR_ALREADY) mp->rc = 0; else if (mp->rc) PFL_GOTOERR(out, mp->rc); mp->sbd = mq->sbd; mp->sbd.sbd_seq = bml->bml_seq; mp->sbd.sbd_key = bmi->bmi_assign->odtr_crc; psc_assert(bmi->bmi_wr_ion); mp->sbd.sbd_ios = rmmi2resm(bmi->bmi_wr_ion)->resm_res_id; out: if (bml) mds_bmap_bml_release(bml); if (b) bmap_op_done(b); if (f) fcmh_op_done(f); return (0); }
int slm_rmc_handle_lookup(struct pscrpc_request *rq) { struct fidc_membh *p = NULL; struct srm_lookup_req *mq; struct srm_lookup_rep *mp; int vfsid; SL_RSX_ALLOCREP(rq, mq, mp); mp->rc = slfid_to_vfsid(mq->pfg.fg_fid, &vfsid); if (mp->rc) PFL_GOTOERR(out, mp->rc); mp->rc = -slm_fcmh_get(&mq->pfg, &p); if (mp->rc) PFL_GOTOERR(out, mp->rc); mq->name[sizeof(mq->name) - 1] = '\0'; psclog_diag("lookup: pfid="SLPRI_FID" name=%s", fcmh_2_mfid(p), mq->name); if (fcmh_2_mfid(p) == SLFID_ROOT && strcmp(mq->name, SL_RPATH_META_DIR) == 0) PFL_GOTOERR(out, mp->rc = -EINVAL); if (mq->pfg.fg_fid == SLFID_ROOT && use_global_mount) { uint64_t fid; struct sl_site *site; mp->rc = -ENOENT; CONF_LOCK(); CONF_FOREACH_SITE(site) { if (strcmp(mq->name, site->site_name) != 0) continue; fid = SLFID_ROOT; FID_SET_SITEID(fid, site->site_id); mp->xattrsize = 0; mp->attr.sst_fg.fg_fid = fid; mp->attr.sst_fg.fg_gen = 2; slm_root_attributes(&mp->attr); mp->rc = 0; break; } CONF_ULOCK(); goto out; }
int slm_rmc_handle_extendbmapls(struct pscrpc_request *rq) { struct srm_leasebmapext_req *mq; struct srm_leasebmapext_rep *mp; struct fidc_membh *f; SL_RSX_ALLOCREP(rq, mq, mp); mp->rc = -slm_fcmh_get(&mq->sbd.sbd_fg, &f); if (mp->rc) return (0); mp->rc = mds_lease_renew(f, &mq->sbd, &mp->sbd, rq->rq_export); fcmh_op_done(f); return (0); }
int slm_rmc_handle_reassignbmapls(struct pscrpc_request *rq) { struct srm_reassignbmap_req *mq; struct srm_reassignbmap_rep *mp; struct fidc_membh *f; SL_RSX_ALLOCREP(rq, mq, mp); mp->rc = -slm_fcmh_get(&mq->sbd.sbd_fg, &f); if (mp->rc) return (0); mp->rc = mds_lease_reassign(f, &mq->sbd, mq->pios, mq->prev_sliods, mq->nreassigns, &mp->sbd, rq->rq_export); fcmh_op_done(f); return (0); }
int slm_rmc_handle_getattr(struct pscrpc_request *rq) { const struct srm_getattr_req *mq; struct srm_getattr_rep *mp; struct fidc_membh *f; int vfsid; SL_RSX_ALLOCREP(rq, mq, mp); psclog_diag("pfid="SLPRI_FID, mq->fg.fg_fid); if (mq->fg.fg_fid == SLFID_ROOT && use_global_mount) { mp->attr.sst_fg.fg_fid = SLFID_ROOT; mp->attr.sst_fg.fg_gen = FGEN_ANY-1; slm_root_attributes(&mp->attr); return (0); } mp->rc = -slm_fcmh_get(&mq->fg, &f); if (mp->rc) PFL_GOTOERR(out, mp->rc); mp->rc = slfid_to_vfsid(mq->fg.fg_fid, &vfsid); if (mp->rc) PFL_GOTOERR(out, mp->rc); mp->xattrsize = mdsio_hasxattrs(vfsid, &rootcreds, fcmh_2_mfid(f)); FCMH_LOCK(f); mp->attr = f->fcmh_sstb; out: if (f) fcmh_op_done(f); return (0); }
int slm_rmc_handle_link(struct pscrpc_request *rq) { struct fidc_membh *p = NULL, *c = NULL; struct srm_link_req *mq; struct srm_link_rep *mp; int vfsid; SL_RSX_ALLOCREP(rq, mq, mp); mp->rc = slfid_to_vfsid(mq->fg.fg_fid, &vfsid); if (mp->rc) PFL_GOTOERR(out, mp->rc); mp->rc = -slm_fcmh_get(&mq->pfg, &p); if (mp->rc) PFL_GOTOERR(out, mp->rc); mp->rc = -slm_fcmh_get(&mq->fg, &c); if (mp->rc) PFL_GOTOERR(out, mp->rc); mq->name[sizeof(mq->name) - 1] = '\0'; mds_reserve_slot(1); mp->rc = mdsio_link(vfsid, fcmh_2_mfid(c), fcmh_2_mfid(p), mq->name, &rootcreds, mdslog_namespace); mds_unreserve_slot(1); mdsio_fcmh_refreshattr(c, &mp->cattr); mdsio_fcmh_refreshattr(p, &mp->pattr); out: if (c) fcmh_op_done(c); if (p) fcmh_op_done(p); return (0); }
int slm_rmc_handle_getbmap(struct pscrpc_request *rq) { const struct srm_leasebmap_req *mq; struct srm_leasebmap_rep *mp; struct fidc_membh *f; int rc = 0; SL_RSX_ALLOCREP(rq, mq, mp); if (mq->rw == SL_WRITE) OPSTAT_INCR("getbmap-lease-write"); else if (mq->rw == SL_READ) OPSTAT_INCR("getbmap-lease-read"); else { mp->rc = -EINVAL; return (0); } mp->rc = -slm_fcmh_get(&mq->fg, &f); if (mp->rc) return (0); mp->flags = mq->flags; mp->rc = mds_bmap_load_cli(f, mq->bmapno, mq->flags, mq->rw, mq->prefios[0], &mp->sbd, rq->rq_export, mp->repls, 0); if (mp->rc) PFL_GOTOERR(out, mp->rc); if (mp->flags & SRM_LEASEBMAPF_GETINODE) slm_pack_inode(f, &mp->ino); out: fcmh_op_done(f); return (rc ? rc : mp->rc); }
/* * Handle a NAMESPACE_FORWARD request from another MDS. */ int slm_rmm_handle_namespace_forward(struct pscrpc_request *rq) { char *from, *to, *name, *linkname; struct fidc_membh *p = NULL, *op = NULL, *np = NULL; struct srm_forward_req *mq; struct srm_forward_rep *mp; struct slash_creds cr; struct srt_stat sstb; void *mfh; int vfsid; p = op = np = NULL; SL_RSX_ALLOCREP(rq, mq, mp); if (mq->op != SLM_FORWARD_MKDIR && mq->op != SLM_FORWARD_RMDIR && mq->op != SLM_FORWARD_CREATE && mq->op != SLM_FORWARD_UNLINK && mq->op != SLM_FORWARD_SYMLINK && mq->op != SLM_FORWARD_RENAME && mq->op != SLM_FORWARD_SETATTR) { mp->rc = -EINVAL; return (0); } psclog_info("op=%d, name=%s", mq->op, mq->req.name); mp->rc = slfid_to_vfsid(mq->fg.fg_fid, &vfsid); if (mp->rc) return (0); if (current_vfsid != vfsid) { mp->rc = -EINVAL; return (0); } cr.scr_uid = mq->creds.scr_uid; cr.scr_gid = mq->creds.scr_gid; mds_reserve_slot(2); switch (mq->op) { case SLM_FORWARD_MKDIR: mp->rc = slm_fcmh_get(&mq->fg, &p); if (mp->rc) break; sstb.sst_mode = mq->mode; sstb.sst_uid = mq->creds.scr_uid; sstb.sst_gid = mq->creds.scr_gid; mp->rc = -mdsio_mkdir(vfsid, fcmh_2_mfid(p), mq->req.name, &sstb, 0, 0, &mp->attr, NULL, mdslog_namespace, slm_get_next_slashfid, 0); break; case SLM_FORWARD_CREATE: mp->rc = slm_fcmh_get(&mq->fg, &p); if (mp->rc) break; mp->rc = mdsio_opencreate(vfsid, fcmh_2_mfid(p), &cr, O_CREAT | O_EXCL | O_RDWR, mq->mode, mq->req.name, NULL, &mp->attr, &mfh, mdslog_namespace, slm_get_next_slashfid, 0); if (!mp->rc) mdsio_release(vfsid, &rootcreds, mfh); break; case SLM_FORWARD_RMDIR: mp->rc = slm_fcmh_get(&mq->fg, &p); if (mp->rc) break; mp->rc = mdsio_rmdir(vfsid, fcmh_2_mfid(p), NULL, mq->req.name, &rootcreds, mdslog_namespace); break; case SLM_FORWARD_UNLINK: mp->rc = slm_fcmh_get(&mq->fg, &p); if (mp->rc) break; mp->rc = -mdsio_unlink(vfsid, fcmh_2_mfid(p), NULL, mq->req.name, &rootcreds, mdslog_namespace, &mp->attr); break; case SLM_FORWARD_RENAME: mp->rc = slm_fcmh_get(&mq->fg, &op); if (mp->rc) break; mp->rc = slm_fcmh_get(&mq->nfg, &np); if (mp->rc) break; from = mq->req.name; to = mq->req.name + strlen(mq->req.name) + 1; mp->rc = mdsio_rename(vfsid, fcmh_2_mfid(op), from, fcmh_2_mfid(np), to, &rootcreds, mdslog_namespace, &mp->attr); break; case SLM_FORWARD_SETATTR: /* * This is tough because we have some logic at the fcmh * layer dealing with (partial) truncates. It is not a * pure namespace operation. */ mp->rc = slm_fcmh_get(&mq->fg, &p); if (mp->rc) break; mp->rc = -mdsio_setattr(vfsid, fcmh_2_mfid(p), &mq->req.sstb, mq->to_set, &rootcreds, &mp->attr, fcmh_2_mfh(p), mdslog_namespace); break; case SLM_FORWARD_SYMLINK: mp->rc = slm_fcmh_get(&mq->fg, &p); if (mp->rc) break; name = mq->req.name; linkname = mq->req.name + strlen(mq->req.name) + 1; mp->rc = mdsio_symlink(vfsid, linkname, fcmh_2_mfid(p), name, &cr, &mp->attr, NULL, NULL, slm_get_next_slashfid, 0); break; } mds_unreserve_slot(2); if (p) fcmh_op_done(p); if (op) fcmh_op_done(op); if (np) fcmh_op_done(np); return (0); }