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); }
void msl_fcmh_stash_inode(struct fidc_membh *f, struct srt_inode *ino) { struct fcmh_cli_info *fci; int i; fci = fcmh_2_fci(f); FCMH_LOCK_ENSURE(f); fci->fci_inode = *ino; /* XXX Do we really need this map just for stir? */ for (i = 0; i < fci->fci_inode.nrepls; i++) fci->fcif_idxmap[i] = i; fci->fcif_mapstircnt = MAPSTIR_THRESH; }
/* * 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); }