int _mds_fcmh_setattr(int vfsid, struct fidc_membh *f, int to_set, const struct srt_stat *sstb, int log) { struct srt_stat sstb_out; int rc; FCMH_LOCK_ENSURE(f); FCMH_BUSY_ENSURE(f); FCMH_ULOCK(f); if (log) mds_reserve_slot(1); rc = mdsio_setattr(vfsid, fcmh_2_mfid(f), sstb, to_set, &rootcreds, &sstb_out, fcmh_2_mfh(f), log ? mdslog_namespace : NULL); if (log) mds_unreserve_slot(1); if (!rc) { psc_assert(sstb_out.sst_fid == fcmh_2_fid(f)); FCMH_LOCK(f); f->fcmh_sstb = sstb_out; FCMH_ULOCK(f); } return (rc); }
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_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 mdsio_fcmh_refreshattr(struct fidc_membh *f, struct srt_stat *out_sstb) { int locked, rc, vfsid; pthread_t pthr; pthr = pthread_self(); locked = FCMH_RLOCK(f); fcmh_wait_locked(f, (f->fcmh_flags & FCMH_BUSY) && f->fcmh_owner != pthr); rc = slfid_to_vfsid(fcmh_2_fid(f), &vfsid); psc_assert(rc == 0); rc = mdsio_getattr(vfsid, fcmh_2_mfid(f), fcmh_2_mfh(f), &rootcreds, &f->fcmh_sstb); if (out_sstb) *out_sstb = f->fcmh_sstb; FCMH_URLOCK(f, locked); return (rc); }
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_fcmh_ctor(struct fidc_membh *f, __unusedx int flags) { struct fcmh_mds_info *fmi; struct mio_fh *ino_mfh; struct slm_inoh *ih; mio_fid_t ino_mfid; int rc, vfsid; DEBUG_FCMH(PLL_DIAG, f, "ctor"); rc = slfid_to_vfsid(fcmh_2_fid(f), &vfsid); if (rc) { DEBUG_FCMH(PLL_WARN, f, "invalid file system ID; " "rc=%d", rc); return (rc); } fmi = fcmh_2_fmi(f); memset(fmi, 0, sizeof(*fmi)); rc = mdsio_lookup_slfid(vfsid, fcmh_2_fid(f), &rootcreds, &f->fcmh_sstb, &fcmh_2_mfid(f)); if (rc) { fmi->fmi_ctor_rc = rc; DEBUG_FCMH(PLL_WARN, f, "mdsio_lookup_slfid failed; " "fid="SLPRI_FID" rc=%d", fcmh_2_fid(f), rc); return (rc); } ih = &fmi->fmi_inodeh; ih->inoh_flags = INOH_INO_NOTLOADED; ino_mfid = fcmh_2_mfid(f); ino_mfh = fcmh_2_mfhp(f); if (fcmh_isdir(f)) { mio_fid_t pmfid; char fn[24]; rc = mdsio_opendir(vfsid, fcmh_2_mfid(f), &rootcreds, NULL, &fcmh_2_mfh(f)); if (rc) { DEBUG_FCMH(PLL_WARN, f, "mdsio_opendir failed; " "mio_fid=%"PRIx64" rc=%d", fcmh_2_mfid(f), rc); return (rc); } snprintf(fn, sizeof(fn), "%016"PRIx64".ino", fcmh_2_fid(f)); pmfid = mdsio_getfidlinkdir(fcmh_2_fid(f)); rc = mdsio_lookup(vfsid, pmfid, fn, &fcmh_2_dino_mfid(f), &rootcreds, NULL); if (rc == ENOENT) { struct slm_inox_od inox; rc = mdsio_opencreatef(vfsid, pmfid, &rootcreds, O_CREAT | O_EXCL | O_RDWR, MDSIO_OPENCRF_NOLINK, 0644, fn, &fcmh_2_dino_mfid(f), NULL, &fcmh_2_dino_mfh(f), NULL, NULL, 0); psc_assert(rc == 0); INOH_LOCK(ih); rc = mds_inode_write(vfsid, ih, NULL, NULL); psc_assert(rc == 0); memset(&inox, 0, sizeof(inox)); ih->inoh_extras = &inox; rc = mds_inox_write(vfsid, ih, NULL, NULL); ih->inoh_extras = NULL; INOH_ULOCK(ih); psc_assert(rc == 0); mdsio_release(vfsid, &rootcreds, fcmh_2_dino_mfh(f)); } else if (rc) { fmi->fmi_ctor_rc = rc; DEBUG_FCMH(PLL_WARN, f, "mdsio_lookup failed; rc=%d", rc); return (rc); } ino_mfid = fcmh_2_dino_mfid(f); ino_mfh = fcmh_2_dino_mfhp(f); } if (fcmh_isreg(f)) psc_dynarray_init(&fmi->fmi_ptrunc_clients); if (fcmh_isdir(f) || fcmh_isreg(f)) { /* * We shouldn't need O_LARGEFILE because SLASH2 * metafiles are small. * * I created a file with size of 8070450532247928832 * using dd by seeking to a large offset and writing one * byte. Somehow, the ZFS size becomes 5119601018368. * Without O_LARGEFILE, I got EOVERFLOW (75) here. The * SLASH2 size is correct though. */ rc = mdsio_opencreate(vfsid, ino_mfid, &rootcreds, O_RDWR, 0, NULL, NULL, NULL, &ino_mfh->fh, NULL, NULL, 0); if (rc == 0) { rc = mds_inode_read(&fmi->fmi_inodeh); if (rc) DEBUG_FCMH(PLL_WARN, f, "could not load inode; " "mfid=%"PRIx64" rc=%d", ino_mfid, rc); } else { fmi->fmi_ctor_rc = rc; DEBUG_FCMH(PLL_WARN, f, "mdsio_opencreate failed; " "mfid=%"PRIx64" rc=%d", ino_mfid, rc); } } else DEBUG_FCMH(PLL_DIAG, f, "special file, no zfs obj"); return (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); }
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; } mp->rc = mdsio_lookupx(vfsid, fcmh_2_mfid(p), mq->name, NULL, &rootcreds, &mp->attr, &mp->xattrsize); if (mp->rc) PFL_GOTOERR(out, mp->rc); if (mq->pfg.fg_fid == SLFID_ROOT) { mount_info_t *mountinfo; struct srt_stat tmpattr; struct mio_rootnames *rn; uint64_t fid; int error; rn = slm_rmc_search_roots(mq->name); if (rn) { mountinfo = &zfs_mounts[rn->rn_vfsid]; fid = SLFID_ROOT;