/** * _slm_fcmh_endow - "Endow" or apply inheritance to a new directory * entry from its parent directory replica layout. * Note: the bulk of this is empty until we have a place to store such * info in the SLASH2 metafile. */ int _slm_fcmh_endow(int vfsid, struct fidc_membh *p, struct fidc_membh *c, int wr) { sl_replica_t repls[SL_MAX_REPLICAS]; int nr, rc = 0; uint32_t pol; FCMH_LOCK(p); pol = fcmh_2_ino(p)->ino_replpol; nr = fcmh_2_nrepls(p); memcpy(repls, fcmh_2_ino(p)->ino_repls, sizeof(repls[0]) * SL_DEF_REPLICAS); if (nr > SL_DEF_REPLICAS) { mds_inox_ensure_loaded(fcmh_2_inoh(p)); memcpy(&repls[SL_DEF_REPLICAS], fcmh_2_inox(p)->inox_repls, sizeof(repls[0]) * SL_INOX_NREPLICAS); } FCMH_ULOCK(p); FCMH_WAIT_BUSY(c); fcmh_2_replpol(c) = pol; fcmh_2_ino(c)->ino_nrepls = nr; memcpy(fcmh_2_ino(c)->ino_repls, repls, sizeof(repls[0]) * SL_DEF_REPLICAS); if (nr > SL_DEF_REPLICAS) { mds_inox_ensure_loaded(fcmh_2_inoh(c)); memcpy(fcmh_2_inox(c)->inox_repls, &repls[SL_DEF_REPLICAS], sizeof(repls[0]) * SL_INOX_NREPLICAS); } if (wr) mds_inodes_odsync(vfsid, c, mdslog_ino_repls); FCMH_UNBUSY(c); return (rc); }
void slm_repl_upd_write(struct bmap *b, int rel) { struct { sl_replica_t iosv[SL_MAX_REPLICAS]; char *stat[SL_MAX_REPLICAS]; unsigned nios; } add, del, chg; int off, vold, vnew, sprio, uprio, rc; struct sl_mds_iosinfo *si; struct bmap_mds_info *bmi; struct fidc_membh *f; struct sl_resource *r; sl_ios_id_t resid; unsigned n, nrepls; bmi = bmap_2_bmi(b); f = b->bcm_fcmh; sprio = bmi->bmi_sys_prio; uprio = bmi->bmi_usr_prio; add.nios = 0; del.nios = 0; chg.nios = 0; nrepls = fcmh_2_nrepls(f); for (n = 0, off = 0; n < nrepls; n++, off += SL_BITS_PER_REPLICA) { if (n == SL_DEF_REPLICAS) mds_inox_ensure_loaded(fcmh_2_inoh(f)); resid = fcmh_2_repl(f, n); vold = SL_REPL_GET_BMAP_IOS_STAT(bmi->bmi_orepls, off); vnew = SL_REPL_GET_BMAP_IOS_STAT(bmi->bmi_repls, off); r = libsl_id2res(resid); si = r ? res2iosinfo(r) : &slm_null_iosinfo; if (vold == vnew) ; /* Work was added. */ else if ((vold != BREPLST_REPL_SCHED && vold != BREPLST_GARBAGE_QUEUED && vold != BREPLST_GARBAGE_SCHED && vnew == BREPLST_REPL_QUEUED) || (vold != BREPLST_GARBAGE_SCHED && vnew == BREPLST_GARBAGE_QUEUED && (si->si_flags & SIF_PRECLAIM_NOTSUP) == 0)) { OPSTAT_INCR("repl-work-add"); PUSH_IOS(b, &add, resid, NULL); } /* Work has finished. */ else if ((vold == BREPLST_REPL_QUEUED || vold == BREPLST_REPL_SCHED || vold == BREPLST_TRUNC_SCHED || vold == BREPLST_TRUNC_QUEUED || vold == BREPLST_GARBAGE_SCHED || vold == BREPLST_VALID) && (((si->si_flags & SIF_PRECLAIM_NOTSUP) && vnew == BREPLST_GARBAGE_QUEUED) || vnew == BREPLST_VALID || vnew == BREPLST_INVALID)) { OPSTAT_INCR("repl-work-del"); PUSH_IOS(b, &del, resid, NULL); } /* * Work that was previously scheduled failed so * requeue it. */ else if (vold == BREPLST_REPL_SCHED || vold == BREPLST_GARBAGE_SCHED || vold == BREPLST_TRUNC_SCHED) PUSH_IOS(b, &chg, resid, "Q"); /* Work was scheduled. */ else if (vnew == BREPLST_REPL_SCHED || vnew == BREPLST_GARBAGE_SCHED || vnew == BREPLST_TRUNC_SCHED) PUSH_IOS(b, &chg, resid, "S"); /* Work was reprioritized. */ else if (sprio != -1 || uprio != -1) PUSH_IOS(b, &chg, resid, NULL); } for (n = 0; n < add.nios; n++) { rc = slm_upsch_insert(b, add.iosv[n].bs_id, sprio, uprio); if (!rc) continue; psclog_warnx("upsch insert failed: bno = %d, " "fid=%"PRId64", ios= %d, rc = %d", b->bcm_bmapno, bmap_2_fid(b), add.iosv[n].bs_id, rc); } for (n = 0; n < del.nios; n++) { spinlock(&slm_upsch_lock); dbdo(NULL, NULL, " DELETE FROM upsch" " WHERE resid = ?" " AND fid = ?" " AND bno = ?", SQLITE_INTEGER, del.iosv[n].bs_id, SQLITE_INTEGER64, bmap_2_fid(b), SQLITE_INTEGER, b->bcm_bmapno); freelock(&slm_upsch_lock); } for (n = 0; n < chg.nios; n++) { spinlock(&slm_upsch_lock); dbdo(NULL, NULL, " UPDATE upsch" " SET status = IFNULL(?, status)," " sys_prio = IFNULL(?, sys_prio)," " usr_prio = IFNULL(?, usr_prio)" " WHERE resid = ?" " AND fid = ?" " AND bno = ?", chg.stat[n] ? SQLITE_TEXT : SQLITE_NULL, chg.stat[n] ? chg.stat[n] : 0, sprio == -1 ? SQLITE_NULL : SQLITE_INTEGER, sprio == -1 ? 0 : sprio, uprio == -1 ? SQLITE_NULL : SQLITE_INTEGER, uprio == -1 ? 0 : uprio, SQLITE_INTEGER, chg.iosv[n].bs_id, SQLITE_INTEGER64, bmap_2_fid(b), SQLITE_INTEGER, b->bcm_bmapno); freelock(&slm_upsch_lock); } bmap_2_bmi(b)->bmi_sys_prio = -1; bmap_2_bmi(b)->bmi_usr_prio = -1; if (rel) { BMAP_LOCK(b); b->bcm_flags &= ~BMAPF_REPLMODWR; bmap_wake_locked(b); bmap_op_done_type(b, BMAP_OPCNT_WORK); } }
/* * Walk the bmap replication bits, performing any specified translations * and returning any queried states. * @b: bmap. * @tract: translation actions; for each array slot, set states of the type * corresponding to the array index to the array value. For example: * * tract[BREPLST_INVALID] = BREPLST_VALID * * This changes any BREPLST_INVALID states into BREPLST_VALID. * @retifset: return the value of the slot in this array corresponding to * the state value as the slot index, if the array value is nonzero; * the last replica always gets priority unless SCIRCUIT is specified. * @flags: operational flags. * @iosidx: indexes of I/O systems to exclude or query, or NULL for everyone. * @nios: # I/O system indexes specified. */ int _mds_repl_bmap_walk(struct bmap *b, const int *tract, const int *retifset, int flags, const int *iosidx, int nios, brepl_walkcb_t cbf, void *cbarg) { int scircuit, nr, off, k, rc, trc; scircuit = rc = 0; /* * gdb help: * * ((struct fcmh_mds_info *) * (b->bcm_fcmh + 1))->fmi_inodeh.inoh_ino.ino_nrepls * * ((struct bmap_mds_info*)(b+1))->bmi_corestate.bcs_repls * */ nr = fcmh_2_nrepls(b->bcm_fcmh); if (nios == 0) { /* no one specified; apply to all */ for (k = 0, off = 0; k < nr; k++, off += SL_BITS_PER_REPLICA) { trc = _mds_repl_bmap_apply(b, tract, retifset, flags, off, &scircuit, cbf, cbarg); if (trc) rc = trc; if (scircuit) break; } return (rc); } if (flags & REPL_WALKF_MODOTH) { /* modify sites all sites except those specified */ for (k = 0, off = 0; k < nr; k++, off += SL_BITS_PER_REPLICA) if (!iosidx_in(k, iosidx, nios)) { trc = _mds_repl_bmap_apply(b, tract, retifset, flags, off, &scircuit, cbf, cbarg); if (trc) rc = trc; if (scircuit) break; } return (rc); } /* modify only the sites specified */ for (k = 0; k < nios; k++) { trc = _mds_repl_bmap_apply(b, tract, retifset, flags, iosidx[k] * SL_BITS_PER_REPLICA, &scircuit, cbf, cbarg); if (trc) rc = trc; if (scircuit) break; } return (rc); }