int slfid_to_vfsid(slfid_t fid, int *vfsid) { int i, siteid; /* * Our client uses this special fid to contact us during mount, * at which time it does not know the site ID yet. * * XXX The client should be able to retrieve the site id from * the slash2 config file. */ if (fid == SLFID_ROOT) { *vfsid = current_vfsid; return (0); } /* only have default file system in the root */ if (zfs_nmounts == 1) { *vfsid = current_vfsid; return (0); } siteid = FID_GET_SITEID(fid); for (i = 0; i < zfs_nmounts; i++) { if (zfs_mounts[i].zm_siteid == (uint64_t)siteid) { *vfsid = i; return (0); } } return (-EINVAL); }
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); }
int main(int argc, char *argv[]) { char *p, tmbuf[PFL_CTIME_BUFSIZ], *cursor_file = NULL, c; uint64_t newtxg = 0, newfid = 0, fid, cycle, newcycle; int dump = 0, verbose = 0, fd, rc; struct psc_journal_cursor cursor; progname = argv[0]; while ((c = getopt(argc, argv, "c:df:vx:")) != -1) switch (c) { case 'c': cursor_file = optarg; break; case 'd': dump = 1; break; case 'f': newfid = strtol(optarg, NULL, 0); break; case 'v': verbose = 1; break; case 'x': newtxg = strtol(optarg, NULL, 0); break; default: usage(); } argc -= optind; if (argc || !cursor_file) usage(); fd = open(cursor_file, O_RDWR); if (fd < 0) err(1, "failed to open %s", cursor_file); rc = pread(fd, &cursor, sizeof(struct psc_journal_cursor), 0); if (rc != sizeof(struct psc_journal_cursor)) err(1, "cursor file read"); ctime_r((time_t *)&cursor.pjc_timestamp, tmbuf); p = strchr(tmbuf, '\n'); if (p) *p = '\0'; cycle = FID_GET_CYCLE(cursor.pjc_fid); if (dump || verbose) { printf("Cursor contents of %s:\n" "\tmagic %"PRIx64"\n" "\tversion %"PRIx64"\n" "\ttimestamp %"PRId64" (%s)\n" "\tuuid %s\n" "\tcommit_txg %"PRId64"\n" "\tdistill_xid %"PRId64"\n" "\tfid %#"PRIx64" " "(flag=%"PRIx64", siteid=%"PRIx64", " "cycle=%"PRIx64", inum=%"PRIx64")\n" "\tseqno_lwm %"PRIx64"\n" "\tseqno_hwm %"PRIx64"\n" "\ttail %"PRIx64"\n" "\tupdate_seqno %"PRIx64"\n" "\treclaim_seqno %"PRIx64"\n" "\treplay_xid %"PRIx64"\n\n", cursor_file, cursor.pjc_magic, cursor.pjc_version, cursor.pjc_timestamp, tmbuf, cursor.pjc_uuid, cursor.pjc_commit_txg, cursor.pjc_distill_xid, cursor.pjc_fid, FID_GET_FLAGS(cursor.pjc_fid), FID_GET_SITEID(cursor.pjc_fid), FID_GET_CYCLE(cursor.pjc_fid), FID_GET_INUM(cursor.pjc_fid), cursor.pjc_seqno_lwm, cursor.pjc_seqno_hwm, cursor.pjc_tail, cursor.pjc_update_seqno, cursor.pjc_reclaim_seqno, cursor.pjc_replay_xid); fid = cursor.pjc_fid; fid = fid | FID_MAX_INUM; printf("The max FID for this cycle is %#"PRIx64"\n", fid); if (cycle < ((UINT64_C(1) << SLASH_FID_CYCLE_BITS) - 1)) { fid++; printf("The first FID for the next cycle is %#"PRIx64"\n", fid); } if (dump) exit(0); } if (!newtxg && !newfid) errx(1, "neither fid nor txg was specified"); if (newtxg) cursor.pjc_commit_txg = newtxg; if (newfid) { newcycle = FID_GET_CYCLE(newfid); if (newcycle <= cycle) errx(1, "cycle must be increased when setting a new FID"); cursor.pjc_fid = newfid; } rc = pwrite(fd, &cursor, sizeof(struct psc_journal_cursor), 0); if (rc != sizeof(struct psc_journal_cursor)) err(1, "cursor file write"); if (close(fd) == -1) err(1, "cursor file close"); exit(0); }
/* * 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); }