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 mds_inode_update_interrupted(int vfsid, struct slash_inode_handle *ih, int *rc) { char fn[NAME_MAX + 1]; struct srt_stat sstb; struct iovec iovs[2]; uint64_t crc, od_crc; void *h = NULL, *th; mdsio_fid_t inum; int exists = 0; size_t nb; th = inoh_2_mfh(ih); snprintf(fn, sizeof(fn), "%016"PRIx64".update", inoh_2_fid(ih)); *rc = mdsio_lookup(vfsid, mds_tmpdir_inum[vfsid], fn, &inum, &rootcreds, NULL); if (*rc) PFL_GOTOERR(out, *rc); *rc = mdsio_opencreatef(vfsid, inum, &rootcreds, O_RDONLY, MDSIO_OPENCRF_NOLINK, 0644, NULL, NULL, NULL, &h, NULL, NULL, 0); if (*rc) PFL_GOTOERR(out, *rc); iovs[0].iov_base = &ih->inoh_ino; iovs[0].iov_len = sizeof(ih->inoh_ino); iovs[1].iov_base = &od_crc; iovs[1].iov_len = sizeof(od_crc); *rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, 0, h); if (*rc) PFL_GOTOERR(out, *rc); psc_crc64_calc(&crc, &ih->inoh_ino, sizeof(ih->inoh_ino)); if (crc != od_crc) { *rc = PFLERR_BADCRC; PFL_GOTOERR(out, *rc); } exists = 1; psc_assert(ih->inoh_extras == NULL); ih->inoh_extras = PSCALLOC(INOX_SZ); inoh_2_mfh(ih) = h; *rc = mds_inox_ensure_loaded(ih); if (*rc) PFL_GOTOERR(out, *rc); inoh_2_mfh(ih) = th; memset(&sstb, 0, sizeof(sstb)); *rc = mdsio_setattr(vfsid, 0, &sstb, SL_SETATTRF_METASIZE, &rootcreds, NULL, th, NULL); if (*rc) PFL_GOTOERR(out, *rc); *rc = mds_inode_dump(vfsid, NULL, ih, h); if (*rc) PFL_GOTOERR(out, *rc); mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn, &rootcreds, NULL, NULL); out: if (h) mdsio_release(vfsid, &rootcreds, h); if (*rc) mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn, &rootcreds, NULL, NULL); inoh_2_mfh(ih) = th; return (exists); }
/* * 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); }
int mds_inode_update(int vfsid, struct slash_inode_handle *ih, int old_version) { char fn[NAME_MAX + 1]; struct sl_ino_compat *sic; struct fidc_membh *f; struct srt_stat sstb; void *h = NULL, *th; int rc; sic = &sl_ino_compat_table[old_version]; rc = sic->sic_read_ino(ih); if (rc) return (rc); DEBUG_INOH(PLL_INFO, ih, "updating old inode (v %d)", old_version); f = inoh_2_fcmh(ih); snprintf(fn, sizeof(fn), "%016"PRIx64".update", fcmh_2_fid(f)); rc = mdsio_opencreatef(vfsid, mds_tmpdir_inum[vfsid], &rootcreds, O_RDWR | O_CREAT | O_TRUNC, MDSIO_OPENCRF_NOLINK, 0644, fn, NULL, NULL, &h, NULL, NULL, 0); if (rc) PFL_GOTOERR(out, rc); psc_assert(ih->inoh_extras == NULL); ih->inoh_extras = PSCALLOC(INOX_SZ); /* convert old structures into new into temp file */ rc = sic->sic_read_inox(ih); if (rc) PFL_GOTOERR(out, rc); th = inoh_2_mfhp(ih)->fh; inoh_2_mfhp(ih)->fh = h; rc = mds_inode_dump(vfsid, sic, ih, th); inoh_2_mfhp(ih)->fh = th; if (rc) PFL_GOTOERR(out, rc); /* move new structures to inode meta file */ memset(&sstb, 0, sizeof(sstb)); rc = mdsio_setattr(vfsid, 0, &sstb, SL_SETATTRF_METASIZE, &rootcreds, NULL, th, NULL); if (rc) PFL_GOTOERR(out, rc); // mdsio_rename(mds_tmpdir_inum, NULL, fn, &rootcreds, NULL); rc = mds_inode_dump(vfsid, NULL, ih, h); if (rc) PFL_GOTOERR(out, rc); mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn, &rootcreds, NULL, NULL); out: if (h) mdsio_release(vfsid, &rootcreds, h); if (rc) { mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn, &rootcreds, NULL, NULL); DEBUG_INOH(PLL_ERROR, ih, "error updating old inode " "rc=%d", rc); } return (rc); }