void slm_fcmh_dtor(struct fidc_membh *f) { struct fcmh_mds_info *fmi; int rc, vfsid; fmi = fcmh_2_fmi(f); if (fcmh_isreg(f)) { psc_assert(psc_dynarray_len(&fmi->fmi_ptrunc_clients) == 0); psc_dynarray_free(&fmi->fmi_ptrunc_clients); } if (fcmh_isreg(f) || fcmh_isdir(f)) { /* XXX Need to worry about other modes here */ if (!fmi->fmi_ctor_rc) { slfid_to_vfsid(fcmh_2_fid(f), &vfsid); rc = mdsio_release(vfsid, &rootcreds, fcmh_2_mfh(f)); psc_assert(rc == 0); } } if (fcmh_isdir(f)) { slfid_to_vfsid(fcmh_2_fid(f), &vfsid); rc = mdsio_release(vfsid, &rootcreds, fcmh_2_dino_mfh(f)); psc_assert(rc == 0); } if (fmi->fmi_inodeh.inoh_extras) PSCFREE(fmi->fmi_inodeh.inoh_extras); }
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 _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_bmap_read_v1(struct bmapc_memb *b, void *readh) { struct { uint8_t crcstates[128]; uint8_t repls[24]; uint64_t crcs[128]; uint32_t gen; uint32_t replpol; } bod; struct fidc_membh *f; struct iovec iovs[2]; uint64_t crc, od_crc; int i, rc, vfsid; size_t nb, bsz; struct bmap_mds_info *bmi = bmap_2_bmi(b); bsz = sizeof(bod) + sizeof(crc); iovs[0].iov_base = &bod; iovs[0].iov_len = sizeof(bod); iovs[1].iov_base = &od_crc; iovs[1].iov_len = sizeof(od_crc); f = b->bcm_fcmh; slfid_to_vfsid(fcmh_2_fid(f), &vfsid); rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, bsz * b->bcm_bmapno + 0x1000, readh); if (rc) return (rc); if (nb == 0) return (SLERR_BMAP_INVALID); if (nb != bsz) return (SLERR_SHORTIO); psc_crc64_calc(&crc, &bod, sizeof(bod)); if (crc != od_crc) return (PFLERR_BADCRC); for (i = 0; i < 128; i++) bmi->bmi_crcstates[i] = bod.crcstates[i]; for (i = 0; i < 24; i++) bmi->bmi_repls[i] = bod.repls[i]; for (i = 0; i < 128; i++) bmap_2_crcs(b, i) = bod.crcs[i]; bmap_2_bgen(b) = bod.gen; bmap_2_replpol(b) = bod.replpol; 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 mds_ino_read_v1(struct slash_inode_handle *ih) { struct { uint16_t version; uint16_t flags; uint32_t bsz; uint32_t nrepls; uint32_t replpol; sl_replica_t repls[4]; } ino; struct fidc_membh *f; struct iovec iovs[2]; uint64_t crc, od_crc; int i, rc, vfsid; size_t nb; iovs[0].iov_base = &ino; iovs[0].iov_len = sizeof(ino); iovs[1].iov_base = &od_crc; iovs[1].iov_len = sizeof(od_crc); f = inoh_2_fcmh(ih); slfid_to_vfsid(fcmh_2_fid(f), &vfsid); rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, 0, inoh_2_mfh(ih)); if (rc) return (rc); if (nb != sizeof(ino) + sizeof(od_crc)) return (SLERR_SHORTIO); psc_crc64_calc(&crc, &ino, sizeof(ino)); if (crc != od_crc) return (PFLERR_BADCRC); ih->inoh_ino.ino_version = INO_VERSION; ih->inoh_ino.ino_bsz = ino.bsz; ih->inoh_ino.ino_nrepls = ino.nrepls; ih->inoh_ino.ino_replpol = ino.replpol; for (i = 0; i < 4; i++) ih->inoh_ino.ino_repls[i] = ino.repls[i]; return (0); }
int mds_inox_read_v1(struct slash_inode_handle *ih) { struct { sl_snap_t snaps[1]; sl_replica_t repls[60]; } inox; struct fidc_membh *f; struct iovec iovs[2]; uint64_t crc, od_crc; int i, rc, vfsid; size_t nb; memset(&inox, 0, sizeof(inox)); iovs[0].iov_base = &inox; iovs[0].iov_len = sizeof(inox); iovs[1].iov_base = &od_crc; iovs[1].iov_len = sizeof(od_crc); f = inoh_2_fcmh(ih); slfid_to_vfsid(fcmh_2_fid(f), &vfsid); rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, 0x400, inoh_2_mfh(ih)); if (rc) return (rc); if (pfl_memchk(&inox, 0, sizeof(inox)) && od_crc == 0) return (0); if (nb != sizeof(inox) + sizeof(od_crc)) return (SLERR_SHORTIO); psc_crc64_calc(&crc, &inox, sizeof(inox)); if (crc != od_crc) return (PFLERR_BADCRC); for (i = 0; i < 60; i++) ih->inoh_extras->inox_repls[i] = inox.repls[i]; 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); }
/* * 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); }
/* * For the given bmap, change the status of all its replicas marked * "valid" to "invalid" except for the replica specified. * * This is a high-level convenience call provided to easily update * status after an ION has received some new I/O, which would make all * other existing copies of the bmap on any other replicas old. * @b: the bmap. * @iosidx: the index of the only ION resource in the inode replica * table that should be marked "valid". * * Note: All callers must journal log these bmap replica changes * themselves. In addition, they must log any changes to the inode * _before_ the bmap changes. Otherwise, we could end up actually * having bmap replicas that are not recognized by the information * stored in the inode during log replay. */ int mds_repl_inv_except(struct bmap *b, int iosidx) { int rc, logit = 0, tract[NBREPLST], retifset[NBREPLST]; uint32_t policy; /* Ensure replica on active IOS is marked valid. */ brepls_init(tract, -1); tract[BREPLST_INVALID] = BREPLST_VALID; tract[BREPLST_GARBAGE_SCHED] = BREPLST_VALID; tract[BREPLST_GARBAGE_QUEUED] = BREPLST_VALID; /* * The old state for this bmap on the given IOS is * either valid or invalid. */ brepls_init_idx(retifset); retifset[BREPLST_INVALID] = 0; retifset[BREPLST_VALID] = 0; /* * XXX on full truncate, the metafile will exist, which means * the bmap states will exist, which means a new IOS will be * selected which will probably be GARBAGE after truncate * happens a few times. */ rc = mds_repl_bmap_walk(b, tract, retifset, 0, &iosidx, 1); if (rc) { psclog_errorx("bcs_repls has active IOS marked in a " "weird state while invalidating other replicas; " "fid="SLPRI_FID" bmap=%d iosidx=%d state=%d", fcmh_2_fid(b->bcm_fcmh), b->bcm_bmapno, iosidx, rc); } policy = bmap_2_replpol(b); /* * Invalidate all other replicas. * Note: if the status is SCHED here, don't do anything; once * the replication status update comes from the ION, we will * know he copied an old bmap and mark it OLD then. */ brepls_init(tract, -1); tract[BREPLST_VALID] = policy == BRPOL_PERSIST ? BREPLST_REPL_QUEUED : BREPLST_GARBAGE_QUEUED; tract[BREPLST_REPL_SCHED] = BREPLST_REPL_QUEUED; brepls_init(retifset, 0); retifset[BREPLST_VALID] = 1; retifset[BREPLST_REPL_SCHED] = 1; if (_mds_repl_bmap_walk(b, tract, retifset, REPL_WALKF_MODOTH, &iosidx, 1, NULL, NULL)) { logit = 1; BHGEN_INCREMENT(b); } if (logit) rc = mds_bmap_write_logrepls(b); else rc = mds_bmap_write(b, NULL, NULL); /* * If this bmap is marked for persistent replication, the repl * request must exist and should be marked such that the * replication monitors do not release it in the midst of * processing it as this activity now means they have more to * do. */ if (policy == BRPOL_PERSIST) upsch_enqueue(&bmap_2_bmi(b)->bmi_upd); return (rc); }
/* * Apply a translation matrix of residency states to a bmap. * @b: bmap. * @tract: translation actions, indexed by current bmap state with * corresponding values to the new state that should be assigned. * For example, index BREPLST_VALID in the array with the value * BREPLST_INVALID would render a VALID state to an INVALID. * @retifset: return value, indexed in the same manner as @tract. * @flags: behavioral flags. * @off: offset int bmap residency table for IOS intended to be * changed/queried. * @scircuit: value-result for batch operations. * @cbf: callback routine for more detailed processing. * @cbarg: argument to callback. * */ int _mds_repl_bmap_apply(struct bmap *b, const int *tract, const int *retifset, int flags, int off, int *scircuit, brepl_walkcb_t cbf, void *cbarg) { int val, rc = 0; struct timeval tv1, tv2, tvd; struct bmap_mds_info *bmi = bmap_2_bmi(b); BMAP_LOCK_ENSURE(b); if (tract) { /* * The caller must set the flag if modifications are made. */ PFL_GETTIMEVAL(&tv1); bmap_wait_locked(b, b->bcm_flags & BMAPF_REPLMODWR); PFL_GETTIMEVAL(&tv2); timersub(&tv2, &tv1, &tvd); OPSTAT_ADD("bmap-wait-usecs", tvd.tv_sec * 1000000 + tvd.tv_usec); memcpy(bmi->bmi_orepls, bmi->bmi_repls, sizeof(bmi->bmi_orepls)); psc_assert((flags & REPL_WALKF_SCIRCUIT) == 0); } if (scircuit) *scircuit = 0; else psc_assert((flags & REPL_WALKF_SCIRCUIT) == 0); /* retrieve IOS status given a bit offset into the map */ val = SL_REPL_GET_BMAP_IOS_STAT(bmi->bmi_repls, off); if (val >= NBREPLST) psc_fatalx("corrupt bmap, val = %d, bno = %d, fid="SLPRI_FID, val, b->bcm_bmapno, fcmh_2_fid(b->bcm_fcmh)); /* callback can also be used to track if we did make any changes */ if (cbf) cbf(b, off / SL_BITS_PER_REPLICA, val, cbarg); /* check for & apply return values */ if (retifset && retifset[val]) { rc = retifset[val]; if (flags & REPL_WALKF_SCIRCUIT) { *scircuit = 1; goto out; } } /* apply any translations - this must be done after retifset */ if (tract && tract[val] != -1) { DEBUG_BMAPOD(PLL_DEBUG, b, "before modification"); SL_REPL_SET_BMAP_IOS_STAT(bmi->bmi_repls, off, tract[val]); DEBUG_BMAPOD(PLL_DEBUG, b, "after modification"); } out: return (rc); }
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); }