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); }
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); }