static void g_journal_ufs_dirty(struct g_consumer *cp) { struct fs *fs; int error, i, sb; if (SBLOCKSIZE % cp->provider->sectorsize != 0) return; for (i = 0; (sb = superblocks[i]) != -1; i++) { if (sb % cp->provider->sectorsize != 0) continue; fs = g_read_data(cp, sb, SBLOCKSIZE, NULL); if (fs == NULL) continue; if (fs->fs_magic != FS_UFS1_MAGIC && fs->fs_magic != FS_UFS2_MAGIC) { g_free(fs); continue; } GJ_DEBUG(0, "clean=%d flags=0x%x", fs->fs_clean, fs->fs_flags); fs->fs_clean = 0; fs->fs_flags |= FS_NEEDSFSCK | FS_UNCLEAN; error = g_write_data(cp, sb, fs, SBLOCKSIZE); g_free(fs); if (error != 0) { GJ_DEBUG(0, "Cannot mark file system %s as dirty " "(error=%d).", cp->provider->name, error); } else { GJ_DEBUG(0, "File system %s marked as dirty.", cp->provider->name); } } }
static void g_mbr_ioctl(void *arg) { struct bio *bp; struct g_geom *gp; struct g_slicer *gsp; struct g_mbr_softc *ms; struct g_ioctl *gio; struct g_consumer *cp; u_char *sec0; int error; /* Get hold of the interesting bits from the bio. */ bp = arg; gp = bp->bio_to->geom; gsp = gp->softc; ms = gsp->softc; gio = (struct g_ioctl *)bp->bio_data; /* The disklabel to set is the ioctl argument. */ sec0 = gio->data; error = g_mbr_modify(gp, ms, sec0); if (error) { g_io_deliver(bp, error); return; } cp = LIST_FIRST(&gp->consumer); error = g_write_data(cp, 0, sec0, 512); g_io_deliver(bp, error); }
static int g_bsd_writelabel(struct g_geom *gp, u_char *bootcode) { off_t secoff; u_int secsize; struct g_consumer *cp; struct g_slicer *gsp; struct g_bsd_softc *ms; u_char *buf; uint64_t sum; int error, i; gsp = gp->softc; ms = gsp->softc; cp = LIST_FIRST(&gp->consumer); /* Get sector size, we need it to read data. */ secsize = cp->provider->sectorsize; secoff = ms->labeloffset % secsize; if (bootcode == NULL) { buf = g_read_data(cp, ms->labeloffset - secoff, secsize, &error); if (buf == NULL) return (error); bcopy(ms->label, buf + secoff, sizeof(ms->label)); } else { buf = bootcode; bcopy(ms->label, buf + ms->labeloffset, sizeof(ms->label)); } if (ms->labeloffset == ALPHA_LABEL_OFFSET) { sum = 0; for (i = 0; i < 63; i++) sum += le64dec(buf + i * 8); le64enc(buf + 504, sum); } if (bootcode == NULL) { error = g_write_data(cp, ms->labeloffset - secoff, buf, secsize); g_free(buf); } else { error = g_write_data(cp, 0, bootcode, BBSIZE); } return(error); }
static int g_mbr_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) { struct g_geom *gp; struct g_mbr_softc *ms; struct g_slicer *gsp; struct g_consumer *cp; int error, opened; gp = pp->geom; gsp = gp->softc; ms = gsp->softc; opened = 0; error = 0; switch(cmd) { case DIOCSMBR: { if (!(fflag & FWRITE)) return (EPERM); DROP_GIANT(); g_topology_lock(); cp = LIST_FIRST(&gp->consumer); if (cp->acw == 0) { error = g_access(cp, 0, 1, 0); if (error == 0) opened = 1; } if (!error) error = g_mbr_modify(gp, ms, data, 512); if (!error) error = g_write_data(cp, 0, data, 512); if (opened) g_access(cp, 0, -1 , 0); g_topology_unlock(); PICKUP_GIANT(); return(error); } default: return (ENOIOCTL); } }
/*- * This start routine is only called for non-trivial requests, all the * trivial ones are handled autonomously by the slice code. * For requests we handle here, we must call the g_io_deliver() on the * bio, and return non-zero to indicate to the slice code that we did so. * This code executes in the "DOWN" I/O path, this means: * * No sleeping. * * Don't grab the topology lock. * * Don't call biowait, g_getattr(), g_setattr() or g_read_data() */ static int g_bsd_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) { struct g_geom *gp; struct g_bsd_softc *ms; struct g_slicer *gsp; u_char *label; int error; gp = pp->geom; gsp = gp->softc; ms = gsp->softc; switch(cmd) { case DIOCGDINFO: /* Return a copy of the disklabel to userland. */ bsd_disklabel_le_dec(ms->label, data, MAXPARTITIONS); return(0); case DIOCBSDBB: { struct g_consumer *cp; u_char *buf; void *p; int error, i; uint64_t sum; if (!(fflag & FWRITE)) return (EPERM); /* The disklabel to set is the ioctl argument. */ buf = g_malloc(BBSIZE, M_WAITOK); p = *(void **)data; error = copyin(p, buf, BBSIZE); if (!error) { /* XXX: Rude, but supposedly safe */ DROP_GIANT(); g_topology_lock(); /* Validate and modify our slice instance to match. */ error = g_bsd_modify(gp, buf + ms->labeloffset); if (!error) { cp = LIST_FIRST(&gp->consumer); if (ms->labeloffset == ALPHA_LABEL_OFFSET) { sum = 0; for (i = 0; i < 63; i++) sum += le64dec(buf + i * 8); le64enc(buf + 504, sum); } error = g_write_data(cp, 0, buf, BBSIZE); } g_topology_unlock(); PICKUP_GIANT(); } g_free(buf); return (error); } case DIOCSDINFO: case DIOCWDINFO: { if (!(fflag & FWRITE)) return (EPERM); label = g_malloc(LABELSIZE, M_WAITOK); /* The disklabel to set is the ioctl argument. */ bsd_disklabel_le_enc(label, data); DROP_GIANT(); g_topology_lock(); /* Validate and modify our slice instance to match. */ error = g_bsd_modify(gp, label); if (error == 0 && cmd == DIOCWDINFO) error = g_bsd_writelabel(gp, NULL); g_topology_unlock(); PICKUP_GIANT(); g_free(label); return(error); } default: return (ENOIOCTL); } }