int sli_fcmh_ctor(struct fidc_membh *f, __unusedx int flags) { int rc = 0; if (f->fcmh_fg.fg_gen == FGEN_ANY) { DEBUG_FCMH(PLL_NOTICE, f, "refusing to open backing file " "with FGEN_ANY"); /* * This is not an error, we just don't have enough info * to create the backing file. */ return (0); } /* try to get a file descriptor for this backing obj */ rc = sli_open_backing_file(f); if (rc == 0) { rc = sli_fcmh_getattr(f); if (rc) DEBUG_FCMH(PLL_WARN, f, "error during " "getattr backing file rc=%d", rc); } if (!rc) f->fcmh_flags |= FCMH_IOD_BACKFILE; return (rc); }
int sli_fcmh_ctor(struct fidc_membh *f, __unusedx int flags) { int rc; struct stat stb; struct fcmh_iod_info *fii; fii = fcmh_2_fii(f); INIT_PSC_LISTENTRY(&fii->fii_lentry); psc_assert(f->fcmh_flags & FCMH_INITING); if (f->fcmh_fg.fg_gen == FGEN_ANY) { DEBUG_FCMH(PLL_NOTICE, f, "refusing to open backing file " "with FGEN_ANY"); /* * This is not an error, we just don't have enough info * to create the backing file. */ return (0); } /* try to get a file descriptor for this backing obj */ rc = sli_open_backing_file(f); if (rc == 0) { if (fstat(fcmh_2_fd(f), &stb) == -1) { rc = -errno; DEBUG_FCMH(PLL_WARN, f, "error during " "getattr backing file rc=%d", rc); close(fcmh_2_fd(f)); } else { sl_externalize_stat(&stb, &f->fcmh_sstb); // XXX get ptruncgen and gen f->fcmh_flags |= FCMH_HAVE_ATTRS; } } if (!rc) f->fcmh_flags |= FCMH_IOD_BACKFILE; return (rc); }
void sli_fcmh_dtor(__unusedx struct fidc_membh *f) { if (f->fcmh_flags & FCMH_IOD_BACKFILE) { if (close(fcmh_2_fd(f)) == -1) { OPSTAT_INCR("close-fail"); DEBUG_FCMH(PLL_ERROR, f, "dtor/close errno=%d", errno); } else OPSTAT_INCR("close-succeed"); psc_rlim_adj(RLIMIT_NOFILE, -1); f->fcmh_flags &= ~FCMH_IOD_BACKFILE; } }
void sli_fcmh_dtor(__unusedx struct fidc_membh *f) { struct fcmh_iod_info *fii; if (f->fcmh_flags & FCMH_IOD_BACKFILE) { if (close(fcmh_2_fd(f)) == -1) { OPSTAT_INCR("close-fail"); DEBUG_FCMH(PLL_ERROR, f, "dtor/close errno=%d", errno); } else OPSTAT_INCR("close-succeed"); psc_rlim_adj(RLIMIT_NOFILE, -1); f->fcmh_flags &= ~FCMH_IOD_BACKFILE; } if (f->fcmh_flags & FCMH_IOD_DIRTYFILE) { fii = fcmh_2_fii(f); lc_remove(&sli_fcmh_dirty, fii); f->fcmh_flags &= ~FCMH_IOD_DIRTYFILE; } }
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); }
/* * Update the high-level app stat(2)-like attribute buffer for a FID * cache member. * @f: FID cache member to update. * @sstb: incoming stat attributes. * @flags: behavioral flags. * Notes: * (1) if SAVELOCAL has been specified, save local field values: * (o) file size * (o) mtime * (2) This function should only be used by a client. */ void slc_fcmh_setattrf(struct fidc_membh *f, struct srt_stat *sstb, int flags) { uidmap_int_stat(sstb); if (flags & FCMH_SETATTRF_HAVELOCK) FCMH_LOCK_ENSURE(f); else FCMH_LOCK(f); if (fcmh_2_gen(f) == FGEN_ANY) fcmh_2_gen(f) = sstb->sst_gen; if ((FID_GET_INUM(fcmh_2_fid(f))) != SLFID_ROOT && fcmh_2_gen(f) > sstb->sst_gen) { OPSTAT_INCR("msl.generation-backwards"); DEBUG_FCMH(PLL_DIAG, f, "attempt to set attr with " "gen %"PRIu64" from old gen %"PRIu64, fcmh_2_gen(f), sstb->sst_gen); goto out; } /* * If we don't have stat attributes, how can we save our local * updates? */ if ((f->fcmh_flags & FCMH_HAVE_ATTRS) == 0) flags |= FCMH_SETATTRF_CLOBBER; /* * Always update for roots because we might have faked them * with readdir at the super root. */ if ((FID_GET_INUM(fcmh_2_fid(f))) == SLFID_ROOT) flags |= FCMH_SETATTRF_CLOBBER; psc_assert(sstb->sst_gen != FGEN_ANY); psc_assert(f->fcmh_fg.fg_fid == sstb->sst_fid); /* * The default behavior is to save st_size and st_mtim since we * might have done I/O that the MDS does not know about. */ if ((flags & FCMH_SETATTRF_CLOBBER) == 0 && fcmh_isreg(f)) { /* * If generation numbers match, take the highest of the * values. Otherwise, disregard local values and * blindly accept whatever the MDS tells us. */ if (fcmh_2_ptruncgen(f) == sstb->sst_ptruncgen && fcmh_2_gen(f) == sstb->sst_gen && fcmh_2_fsz(f) > sstb->sst_size) sstb->sst_size = fcmh_2_fsz(f); if (fcmh_2_utimgen(f) == sstb->sst_utimgen) sstb->sst_mtim = f->fcmh_sstb.sst_mtim; } COPY_SSTB(sstb, &f->fcmh_sstb); f->fcmh_flags |= FCMH_HAVE_ATTRS; f->fcmh_flags &= ~FCMH_GETTING_ATTRS; if (sl_fcmh_ops.sfop_postsetattr) sl_fcmh_ops.sfop_postsetattr(f); DEBUG_FCMH(PLL_DEBUG, f, "attr set"); out: if (!(flags & FCMH_SETATTRF_HAVELOCK)) FCMH_ULOCK(f); }
/* * If the generation number changes, we assume a full truncation has * happened. We need to open a new backing file and attach it to the * fcmh. */ int sli_fcmh_reopen(struct fidc_membh *f, slfgen_t fgen) { int rc = 0; FCMH_LOCK_ENSURE(f); OPSTAT_INCR("reopen"); if (fgen == FGEN_ANY) { OPSTAT_INCR("generation-bogus"); return (EBADF); } if (fgen < fcmh_2_gen(f)) { OPSTAT_INCR("generation-stale"); return (ESTALE); } /* * If our generation number is still unknown try to set it here. */ if (fcmh_2_gen(f) == FGEN_ANY && fgen != FGEN_ANY) { OPSTAT_INCR("generation-fix"); fcmh_2_gen(f) = fgen; } if (fgen > fcmh_2_gen(f)) { struct sl_fidgen oldfg; char fidfn[PATH_MAX]; DEBUG_FCMH(PLL_DIAG, f, "reopening new backing file"); OPSTAT_INCR("slvr-remove-reopen"); slvr_remove_all(f); /* * It's possible the pruning of all slivers and bmaps * ended up fcmh_op_done() our fcmh so ensure it is * locked upon finishing. */ FCMH_RLOCK(f); /* * Need to reopen the backing file and possibly remove * the old one. */ if (f->fcmh_flags & FCMH_IOD_BACKFILE) { if (close(fcmh_2_fd(f)) == -1) { OPSTAT_INCR("close-fail"); DEBUG_FCMH(PLL_ERROR, f, "reopen/close errno=%d", errno); } else { OPSTAT_INCR("close-succeed"); } fcmh_2_fd(f) = -1; psc_rlim_adj(RLIMIT_NOFILE, -1); f->fcmh_flags &= ~FCMH_IOD_BACKFILE; } oldfg.fg_fid = fcmh_2_fid(f); oldfg.fg_gen = fcmh_2_gen(f); fcmh_2_gen(f) = fgen; rc = sli_open_backing_file(f); /* Notify upper layers that open() has failed. */ if (!rc) f->fcmh_flags |= FCMH_IOD_BACKFILE; /* Do some upfront garbage collection. */ sli_fg_makepath(&oldfg, fidfn); errno = 0; unlink(fidfn); DEBUG_FCMH(PLL_INFO, f, "upfront unlink(), errno=%d", errno); } else if (!(f->fcmh_flags & FCMH_IOD_BACKFILE)) { rc = sli_open_backing_file(f); if (!rc) f->fcmh_flags |= FCMH_IOD_BACKFILE; OPSTAT_INCR("generation-same"); } return (rc); }